diff options
author | Yan Thomas | 2023-08-10 08:08:41 -0300 |
---|---|---|
committer | GitHub | 2023-08-10 13:08:41 +0200 |
commit | 06a205e0e673f505bbb87dfcfcb0f35b051677e9 (patch) | |
tree | ae4be87f29799cd4d95ac210df4dc62db8f7254a | |
parent | 43c1481da61d112a2212b86b56a49020e4063424 (diff) | |
download | IT.starlight-06a205e0e673f505bbb87dfcfcb0f35b051677e9.tar.gz IT.starlight-06a205e0e673f505bbb87dfcfcb0f35b051677e9.tar.bz2 IT.starlight-06a205e0e673f505bbb87dfcfcb0f35b051677e9.zip |
Include built-in UI translation for regional docs (#475)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com>
-rw-r--r-- | .changeset/two-experts-rest.md | 5 | ||||
-rw-r--r-- | docs/src/content/docs/reference/configuration.md | 2 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/config.test.ts | 2 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/routing.test.ts | 2 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/translations-with-user-config.test.ts (renamed from packages/starlight/__tests__/basics/translations-with-user-config.test.ts) | 11 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/translations.test.ts (renamed from packages/starlight/__tests__/basics/translations.test.ts) | 6 | ||||
-rw-r--r-- | packages/starlight/__tests__/i18n/vitest.config.ts | 1 | ||||
-rw-r--r-- | packages/starlight/utils/translations.ts | 19 |
8 files changed, 41 insertions, 7 deletions
diff --git a/.changeset/two-experts-rest.md b/.changeset/two-experts-rest.md new file mode 100644 index 00000000..550fe900 --- /dev/null +++ b/.changeset/two-experts-rest.md @@ -0,0 +1,5 @@ +--- +"@astrojs/starlight": patch +--- + +Locales whose language tag includes a regional subtag now use built-in UI translations for their base language. For example, a locale with a language of `pt-BR` will use our `pt` UI translations. diff --git a/docs/src/content/docs/reference/configuration.md b/docs/src/content/docs/reference/configuration.md index c0d77d7f..593f4593 100644 --- a/docs/src/content/docs/reference/configuration.md +++ b/docs/src/content/docs/reference/configuration.md @@ -255,7 +255,7 @@ The label for this language to show to users, for example in the language switch **type:** `string` -The BCP-47 tag for this language, e.g. `"en"`, `"ar"`, or `"zh-CN"`. If not set, the language’s directory name will be used by default. +The BCP-47 tag for this language, e.g. `"en"`, `"ar"`, or `"zh-CN"`. If not set, the language’s directory name will be used by default. Language tags with regional subtags (e.g. `"pt-BR"` or `"en-US"`) will use built-in UI translations for their base language if no region-specific translations are found. ##### `dir` diff --git a/packages/starlight/__tests__/i18n/config.test.ts b/packages/starlight/__tests__/i18n/config.test.ts index 93f9659c..0e8e9c8d 100644 --- a/packages/starlight/__tests__/i18n/config.test.ts +++ b/packages/starlight/__tests__/i18n/config.test.ts @@ -7,7 +7,7 @@ test('test suite is using correct env', () => { test('config.isMultilingual is true with multiple locales', () => { expect(config.isMultilingual).toBe(true); - expect(config.locales).keys('fr', 'en', 'ar'); + expect(config.locales).keys('fr', 'en', 'ar', 'pt-br'); }); test('config.defaultLocale is populated from the user’s chosen default', () => { diff --git a/packages/starlight/__tests__/i18n/routing.test.ts b/packages/starlight/__tests__/i18n/routing.test.ts index e0402b54..18d8ed89 100644 --- a/packages/starlight/__tests__/i18n/routing.test.ts +++ b/packages/starlight/__tests__/i18n/routing.test.ts @@ -38,7 +38,7 @@ test('routes have locale data added', () => { expect(lang).toBe('ar'); expect(dir).toBe('rtl'); expect(locale).toBe('ar'); - } else { + } else if (id.startsWith('fr')) { expect(lang).toBe('fr'); expect(dir).toBe('ltr'); expect(locale).toBe('fr'); diff --git a/packages/starlight/__tests__/basics/translations-with-user-config.test.ts b/packages/starlight/__tests__/i18n/translations-with-user-config.test.ts index 57c0afe9..4335aa03 100644 --- a/packages/starlight/__tests__/basics/translations-with-user-config.test.ts +++ b/packages/starlight/__tests__/i18n/translations-with-user-config.test.ts @@ -4,7 +4,10 @@ import { useTranslations } from '../../utils/translations'; vi.mock('astro:content', async () => (await import('../test-utils')).mockedAstroContent({ - i18n: [['en', { 'page.editLink': 'Modify this doc!' }]], + i18n: [ + ['en-US', { 'page.editLink': 'Modify this doc!' }], + ['pt-BR', { 'page.editLink': 'Modifique esse doc!' }], + ], }) ); @@ -14,4 +17,10 @@ describe('useTranslations()', () => { expect(t('page.editLink')).toBe('Modify this doc!'); expect(t('page.editLink')).not.toBe(translations.en?.['page.editLink']); }); + + test('uses user-defined regional translations when available', () => { + const t = useTranslations('pt-br'); + expect(t('page.editLink')).toBe('Modifique esse doc!'); + expect(t('page.editLink')).not.toBe(translations.pt?.['page.editLink']); + }); }); diff --git a/packages/starlight/__tests__/basics/translations.test.ts b/packages/starlight/__tests__/i18n/translations.test.ts index bd67ef9c..a8442166 100644 --- a/packages/starlight/__tests__/basics/translations.test.ts +++ b/packages/starlight/__tests__/i18n/translations.test.ts @@ -29,4 +29,10 @@ describe('useTranslations()', () => { 'tableOfContents.overview': 'Overview', }); }); + + test('uses built-in translations for regional variants', () => { + const t = useTranslations('pt-br'); + expect(t('page.nextLink')).toBe(translations.pt?.['page.nextLink']); + expect(t('page.nextLink')).not.toBe(translations.en?.['page.nextLink']); + }); }); diff --git a/packages/starlight/__tests__/i18n/vitest.config.ts b/packages/starlight/__tests__/i18n/vitest.config.ts index da62f01a..36212fc7 100644 --- a/packages/starlight/__tests__/i18n/vitest.config.ts +++ b/packages/starlight/__tests__/i18n/vitest.config.ts @@ -7,5 +7,6 @@ export default defineVitestConfig({ fr: { label: 'French' }, en: { label: 'English', lang: 'en-US' }, ar: { label: 'Arabic', dir: 'rtl' }, + 'pt-br': { label: 'Brazilian Portuguese', lang: 'pt-BR' }, }, }); diff --git a/packages/starlight/utils/translations.ts b/packages/starlight/utils/translations.ts index da69bb1e..b4c6da4b 100644 --- a/packages/starlight/utils/translations.ts +++ b/packages/starlight/utils/translations.ts @@ -19,11 +19,21 @@ try { const defaults = buildDictionary( builtinTranslations.en!, userTranslations.en, - builtinTranslations[defaultLocale], + builtinTranslations[defaultLocale] || builtinTranslations[stripLangRegion(defaultLocale)], userTranslations[defaultLocale] ); /** + * Strips the region subtag from a BCP-47 lang string. + * @param {string} [lang] + * @example + * const lang = stripLangRegion('en-GB'); // => 'en' + */ +export function stripLangRegion(lang: string) { + return lang.replace(/-[a-zA-Z]{2}/, ''); +} + +/** * Generate a utility function that returns UI strings for the given `locale`. * @param {string | undefined} [locale] * @example @@ -31,9 +41,12 @@ const defaults = buildDictionary( * const label = t('search.label'); // => 'Search' */ export function useTranslations(locale: string | undefined) { - // TODO: Use better mapping, e.g. so that `en-GB` matches `en`. const lang = localeToLang(locale); - const dictionary = buildDictionary(defaults, builtinTranslations[lang], userTranslations[lang]); + const dictionary = buildDictionary( + defaults, + builtinTranslations[lang] || builtinTranslations[stripLangRegion(lang)], + userTranslations[lang] + ); const t = <K extends keyof typeof dictionary>(key: K) => dictionary[key]; t.pick = (startOfKey: string) => Object.fromEntries(Object.entries(dictionary).filter(([k]) => k.startsWith(startOfKey))); |