From e8ee1fdb3d4c7c4f0ae9633219328ff84c65b769 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:51:48 +0000 Subject: [PATCH 1/7] Initial plan From 4ec212a28793a7e646f241afcf923b8fed5d243a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:56:37 +0000 Subject: [PATCH 2/7] Add translation support infrastructure: metadata, language detection, and UI components Co-authored-by: sinedied <593151+sinedied@users.noreply.github.com> --- packages/database/src/lib/entry.ts | 2 +- packages/database/src/lib/language.ts | 2 +- .../app/shared/components/header.component.ts | 10 +- .../components/language-selector.component.ts | 123 ++++++++++++++++++ .../website/src/app/shared/frontmatter.ts | 2 + .../src/app/workshop/workshop.component.ts | 95 +++++++++++++- 6 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 packages/website/src/app/shared/components/language-selector.component.ts diff --git a/packages/database/src/lib/entry.ts b/packages/database/src/lib/entry.ts index f9a984ea..2a1a3ed2 100644 --- a/packages/database/src/lib/entry.ts +++ b/packages/database/src/lib/entry.ts @@ -33,7 +33,7 @@ export async function createEntry( lastUpdated: extraData.lastUpdated ?? file.lastModified, url: extraData.url ?? getUrl(file.path), githubUrl: extraData.githubUrl ?? undefined, - language: extraData.language ?? getLanguageFromFile(file.path), + language: extraData.language ?? file.meta.language ?? getLanguageFromFile(file.path), level: file.meta.level ?? 'beginner', audience: parseCsvOrArray(file.meta.audience) ?? ['students', 'pro devs'], ...(searchTranslations ? { translations: await findTranslations(file.path) } : {}) diff --git a/packages/database/src/lib/language.ts b/packages/database/src/lib/language.ts index c91415ce..26677bb8 100644 --- a/packages/database/src/lib/language.ts +++ b/packages/database/src/lib/language.ts @@ -5,7 +5,7 @@ import { ContentEntry } from '../../../website/src/app/catalog/content-entry.js' import { getWorkshops } from './workshop.js'; import { createEntry } from './entry.js'; -const languageRegex = /.*?\.([a-zA-Z]{2})\.md$/; +const languageRegex = /.*?\.([a-zA-Z]{2}(?:_[a-zA-Z]{2})?)\.md$/; const translationsFolder = 'translations'; export function getLanguageFromFile(filePath: string): string { diff --git a/packages/website/src/app/shared/components/header.component.ts b/packages/website/src/app/shared/components/header.component.ts index 6f3a0034..bd9c987d 100644 --- a/packages/website/src/app/shared/components/header.component.ts +++ b/packages/website/src/app/shared/components/header.component.ts @@ -2,12 +2,13 @@ import { Component, Input } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IconComponent } from './icon.component'; import { SidebarComponent } from './sidebar.component'; +import { LanguageSelectorComponent, LanguageOption } from './language-selector.component'; import { Link } from '../link'; @Component({ selector: 'app-header', standalone: true, - imports: [CommonModule, IconComponent], + imports: [CommonModule, IconComponent, LanguageSelectorComponent], template: `