Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ const DefaultI18N: I18n = {
currentLocale: 'en',
locales: ['en'],
defaultLocale: 'en',
localeConfigs: {},
localeConfigs: {
en: {
calendar: 'gregory',
},
},
};

function getBlogContentPaths(siteDir: string): BlogContentPaths {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function getI18n(locale: string): I18n {
currentLocale: locale,
locales: [locale],
defaultLocale: locale,
localeConfigs: {},
localeConfigs: {[locale]: {calendar: 'gregory'}},
};
}

Expand Down
13 changes: 11 additions & 2 deletions packages/docusaurus-plugin-content-blog/src/blogUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,18 @@ export function parseBlogFileName(
return {date: undefined, text, slug};
}

function formatBlogPostDate(locale: string, date: Date): string {
function formatBlogPostDate(
locale: string,
date: Date,
calendar: string,
): string {
try {
return new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'long',
year: 'numeric',
timeZone: 'UTC',
calendar,
}).format(date);
} catch (err) {
logger.error`Can't format blog post date "${String(date)}"`;
Expand Down Expand Up @@ -253,7 +258,11 @@ async function processBlogSourceFile(
}

const date = await getDate();
const formattedDate = formatBlogPostDate(i18n.currentLocale, date);
const formattedDate = formatBlogPostDate(
i18n.currentLocale,
date,
i18n.localeConfigs[i18n.currentLocale]!.calendar,
);

const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
const description = frontMatter.description ?? excerpt ?? '';
Expand Down
6 changes: 3 additions & 3 deletions packages/docusaurus-plugin-content-docs/src/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,9 @@ function doProcessDocMetadata({
lastUpdatedBy: lastUpdate.lastUpdatedBy,
lastUpdatedAt: lastUpdate.lastUpdatedAt,
formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
? new Intl.DateTimeFormat(i18n.currentLocale).format(
lastUpdate.lastUpdatedAt * 1000,
)
? new Intl.DateTimeFormat(i18n.currentLocale, {
calendar: i18n.localeConfigs[i18n.currentLocale]!.calendar,
}).format(lastUpdate.lastUpdatedAt * 1000)
: undefined,
sidebarPosition,
frontMatter,
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-types/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export type I18nLocaleConfig = {
label: string;
htmlLang: string;
direction: string;
calendar: string;
};

export type I18nConfig = {
Expand Down
22 changes: 21 additions & 1 deletion packages/docusaurus/src/server/__tests__/i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,48 +32,63 @@ describe('defaultLocaleConfig', () => {
label: 'Français',
direction: 'ltr',
htmlLang: 'fr',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('fr-FR')).toEqual({
label: 'Français (France)',
direction: 'ltr',
htmlLang: 'fr-FR',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('en')).toEqual({
label: 'English',
direction: 'ltr',
htmlLang: 'en',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('en-US')).toEqual({
label: 'American English',
direction: 'ltr',
htmlLang: 'en-US',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('zh')).toEqual({
label: '中文',
direction: 'ltr',
htmlLang: 'zh',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('zh-CN')).toEqual({
label: '中文(中国)',
direction: 'ltr',
htmlLang: 'zh-CN',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('en-US')).toEqual({
label: 'American English',
direction: 'ltr',
htmlLang: 'en-US',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('fa')).toEqual({
// cSpell:ignore فارسی
label: 'فارسی',
direction: 'rtl',
htmlLang: 'fa',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('fa-IR')).toEqual({
// cSpell:ignore ایران فارسیا
label: 'فارسی (ایران)',
direction: 'rtl',
htmlLang: 'fa-IR',
calendar: 'gregory',
});
expect(getDefaultLocaleConfig('en-US-u-ca-buddhist')).toEqual({
label: 'American English',
direction: 'ltr',
htmlLang: 'en-US-u-ca-buddhist',
calendar: 'buddhist',
});
});
});
Expand Down Expand Up @@ -144,7 +159,12 @@ describe('loadI18n', () => {
locales: ['en', 'fr', 'de'],
currentLocale: 'de',
localeConfigs: {
fr: {label: 'Français', direction: 'ltr', htmlLang: 'fr'},
fr: {
label: 'Français',
direction: 'ltr',
htmlLang: 'fr',
calendar: 'gregory',
},
en: getDefaultLocaleConfig('en'),
de: getDefaultLocaleConfig('de'),
},
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus/src/server/configValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const LocaleConfigSchema = Joi.object({
label: Joi.string(),
htmlLang: Joi.string(),
direction: Joi.string().equal('ltr', 'rtl').default('ltr'),
calendar: Joi.string(),
});

const I18N_CONFIG_SCHEMA = Joi.object<I18nConfig>({
Expand Down
2 changes: 2 additions & 0 deletions packages/docusaurus/src/server/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export function getDefaultLocaleConfig(locale: string): I18nLocaleConfig {
label: getDefaultLocaleLabel(locale),
direction: getLangDir(locale),
htmlLang: locale,
// If the locale name includes -u-ca-xxx the calendar will be defined
Copy link
Copy Markdown
Collaborator

@slorber slorber Apr 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a test case for this? Using something like ar-u-ca-islamicc ?

and a test case for an invalid locale, ensuring it falls back and fail-safe instead of crashing

Copy link
Copy Markdown
Collaborator Author

@Josh-Cena Josh-Cena Apr 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use new Intl.DisplayNames to construct the label, which is gonna crash on terribly malformed locale names anyways. new Intl.Locale is more resilient than new Intl.DisplayNames

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This currently works fine: yarn start:website --locale "My-weird-locale"

But anything more fancy will crash: yarn start:website --locale "My weird locale"

But ok we can implement that later, considering we don't have anything setup to accept properly an invalid locale name

calendar: new Intl.Locale(locale).calendar ?? 'gregory',
};
}

Expand Down
13 changes: 9 additions & 4 deletions website/docs/api/docusaurus.config.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ The i18n configuration object to [localize your site](../i18n/i18n-introduction.

Example:

<!-- cSpell:ignore فارسی -->

```js title="docusaurus.config.js"
module.exports = {
i18n: {
Expand All @@ -134,11 +136,13 @@ module.exports = {
label: 'English',
direction: 'ltr',
htmlLang: 'en-US',
calendar: 'gregory',
},
fr: {
label: 'Français',
direction: 'ltr',
htmlLang: 'fr-FR',
fa: {
label: 'فارسی',
direction: 'rtl',
htmlLang: 'fa-IR',
calendar: 'persian',
},
},
},
Expand All @@ -148,6 +152,7 @@ module.exports = {
- `label`: the label to use for this locale
- `direction`: `ltr` (default) or `rtl` (for [right-to-left languages](https://developer.mozilla.org/en-US/docs/Glossary/rtl) like Arabic, Hebrew, etc.)
- `htmlLang`: BCP 47 language tag to use in `<html lang="...">` and in `<link ... hreflang="...">`
- `calendar`: the [calendar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar) used to calculate the date era. Note that it doesn't control the actual string displayed: `MM/DD/YYYY` and `DD/MM/YYYY` are both `gregory`. To choose the format (`DD/MM/YYYY` or `MM/DD/YYYY`), set your locale name to `en-GB` or `en-US` (`en` means `en-US`).

### `noIndex` {#noindex}

Expand Down