Reputation: 1913
Is there a way to use Intl.DisplayNames to get sorting-friendly language names where the base language comes first?
const languageNames = new Intl.DisplayNames(['en'], { type: 'language' });
console.log(languageNames.of('en'));
console.log(languageNames.of('en-AU'));
console.log(languageNames.of('fr'));
console.log(languageNames.of('fr-CA'));
The above snippet returns:
English
Australian English
French
Canadian French
I'm looking for values formatted as documented in the CLDR Language/Locale Name Patterns page:
English
English (Australia)
French
French (Canada)
Some languages have alt="menu"
variants as of CLDR 36, e.g. Chinese, Cantonese
for yue
(instead of the default Cantonese
), but I'm not sure if these are exposed via JavaScript (and aren't defined for the languages in my example above, anyway).
I found a related ticket in the CLDR Jira: ICU-21549: Fix the API to support language menus
Upvotes: 1
Views: 612
Reputation: 3792
Setting the languageDisplay
option to 'standard'
produces the output you want:
const languageNames = new Intl.DisplayNames(['en'], {
type: 'language',
languageDisplay: 'standard'
});
console.log(languageNames.of('en'));
console.log(languageNames.of('en-AU'));
console.log(languageNames.of('fr'));
console.log(languageNames.of('fr-CA'));
I don't know if it's possible to access the menu
variants through this API.
Upvotes: 1
Reputation: 11
We can achieve this with the help of Intl.DisplayNames translations { type: "region" }
code
const languageNames = new Intl.DisplayNames(['en'], { type: 'language' });
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
const languagesObj = {};
const languages = [];
languagesObj['en'] = languageNames.of('en');
languagesObj['en-AU'] = languageNames.of('en-AU');
languagesObj['fr'] = languageNames.of('fr');
languagesObj['fr-CA'] = languageNames.of('fr-CA');
for (let lang in languagesObj) {
if (lang.includes('-')) {
const indexOfCountryLang = lang.indexOf('-');
try {
const language = languageNames.of(lang.slice(0, indexOfCountryLang)) ? languageNames.of(lang.slice(0, indexOfCountryLang)) : '';
const region = regionNames.of(lang.slice(indexOfCountryLang + 1)) ? regionNames.of(lang.slice(indexOfCountryLang + 1)) : '';
lang = `${language} (${region})`;
} catch (error) {
lang = languagesObj[lang];
}
} else {
lang = languagesObj[lang];
}
languages.push(lang);
}
console.log(languages);
output [ 'English', 'English (Australia)', 'French', 'French (Canada)' ]
if any of instance not available in the languageNames.of() or regionNames.of() then it will keep default string
Upvotes: 1