واجهة برمجة التطبيقات Intl.DisplayNames
تحويل رموز اللغات والمناطق والعملات والنصوص إلى أسماء مقروءة للإنسان
مقدمة
تطبيقك يحتوي على رمز البلد US، لكن المستخدمين يرون النص "الولايات المتحدة". لديك رمز اللغة fr، لكن مبدل اللغة يعرض "الفرنسية". لديك رمز العملة EUR، لكن صفحة الدفع تظهر "يورو".
تحتفظ المتصفحات ببيانات توطين شاملة لعرض واجهاتها الخاصة بلغات مختلفة. توفر واجهة برمجة التطبيقات Intl.DisplayNames هذه البيانات لجافا سكريبت، وتحول الرموز القياسية إلى أسماء مقروءة للإنسان ومترجمة لأي لغة.
هذا يلغي الحاجة إلى مكتبات طرف ثالث أو جداول بحث مخصصة تتطلب صيانة وترجمة. يتعامل المتصفح مع كل من البيانات والترجمات.
تحويل رموز المناطق إلى أسماء البلدان
تتضمن حالة الاستخدام الأكثر شيوعًا تحويل رموز البلدان بمعيار ISO إلى أسماء البلدان. قم بإنشاء نسخة من DisplayNames مع لغة ونوع، ثم استدعاء طريقة of() مع رمز البلد:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("GB")); // "United Kingdom"
console.log(regionNames.of("JP")); // "Japan"
تقبل المعلمة الأولى مصفوفة من رموز اللغات التي تتبع معيار BCP 47. يستخدم المتصفح أول لغة مدعومة من المصفوفة. يحدد خيار type نوع الرمز الذي تريد تحويله.
تنتج نفس الرموز مخرجات مختلفة عند ترجمتها للغات مختلفة:
const englishRegions = new Intl.DisplayNames(["en"], { type: "region" });
const japaneseRegions = new Intl.DisplayNames(["ja"], { type: "region" });
const spanishRegions = new Intl.DisplayNames(["es"], { type: "region" });
console.log(englishRegions.of("FR")); // "France"
console.log(japaneseRegions.of("FR")); // "フランス"
console.log(spanishRegions.of("FR")); // "Francia"
يعمل هذا النمط لبناء محددات البلدان، وعروض المواقع، وأي عنصر واجهة يحول رموز البلدان إلى أسماء مقروءة.
تحويل رموز اللغات إلى أسماء اللغات
تستخدم رموز اللغات نفس النمط المستخدم في رموز المناطق. قم بتعيين type: "language" لتحويل رموز اللغات إلى أسماء اللغات:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("es")); // "Spanish"
console.log(languageNames.of("zh")); // "Chinese"
console.log(languageNames.of("ar")); // "Arabic"
يمكن أن تتضمن رموز اللغات علامات فرعية للمناطق للإشارة إلى الاختلافات الإقليمية:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("en-GB")); // "British English"
console.log(languageNames.of("fr-CA")); // "Canadian French"
console.log(languageNames.of("pt-BR")); // "Brazilian Portuguese"
يحول هذا رموز اللغات إلى أسماء مناسبة لمبدلات اللغة وواجهات الترجمة ومحددات تفضيلات اللغة.
عرض أسماء اللغات بلغتها الأصلية
غالبًا ما تعرض مبدلات اللغة كل لغة بنظام كتابتها الخاص. قم بإنشاء نسخة منفصلة من DisplayNames لكل لغة مستهدفة:
const english = new Intl.DisplayNames(["en"], { type: "language" });
const french = new Intl.DisplayNames(["fr"], { type: "language" });
const japanese = new Intl.DisplayNames(["ja"], { type: "language" });
const arabic = new Intl.DisplayNames(["ar"], { type: "language" });
console.log(english.of("en")); // "English"
console.log(french.of("fr")); // "français"
console.log(japanese.of("ja")); // "日本語"
console.log(arabic.of("ar")); // "العربية"
يتعرف المستخدمون على لغتهم بشكل أسرع عندما تُعرض بنصها الأصلي.
تحويل رموز العملات إلى أسماء العملات
تتبع رموز العملات معيار ISO 4217. قم بتعيين type: "currency" لتحويل رموز العملات المكونة من ثلاثة أحرف إلى أسماء العملات:
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
console.log(currencyNames.of("GBP")); // "British Pound"
console.log(currencyNames.of("JPY")); // "Japanese Yen"
تتم محلية أسماء العملات بناءً على لغة العرض:
const englishCurrency = new Intl.DisplayNames(["en"], { type: "currency" });
const germanCurrency = new Intl.DisplayNames(["de"], { type: "currency" });
const japaneseCurrency = new Intl.DisplayNames(["ja"], { type: "currency" });
console.log(englishCurrency.of("EUR")); // "Euro"
console.log(germanCurrency.of("EUR")); // "Euro"
console.log(japaneseCurrency.of("EUR")); // "ユーロ"
يعمل هذا النمط لمحددات العملات في تدفقات الدفع ولوحات المعلومات المالية وواجهات تحويل العملات.
تحويل رموز النصوص إلى أسماء النصوص
تستخدم رموز النصوص معيار ISO 15924. قم بتعيين type: "script" لتحويل رموز النصوص المكونة من أربعة أحرف إلى أسماء النصوص:
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
console.log(scriptNames.of("Cyrl")); // "Cyrillic"
console.log(scriptNames.of("Hans")); // "Simplified Chinese"
console.log(scriptNames.of("Hant")); // "Traditional Chinese"
تظهر أسماء النصوص بشكل أقل تكرارًا في واجهات المستخدم ولكنها تصبح ذات صلة لأنظمة إدارة المحتوى متعددة اللغات وواجهات اختيار اللغة التي تميز بين أنظمة الكتابة.
تحويل رموز التقويم إلى أسماء التقويم
تختلف أنظمة التقويم عبر الثقافات. قم بتعيين type: "calendar" لتحويل معرفات التقويم إلى أسماء التقويم:
const calendarNames = new Intl.DisplayNames(["en"], { type: "calendar" });
console.log(calendarNames.of("gregory")); // "Gregorian Calendar"
console.log(calendarNames.of("japanese")); // "Japanese Calendar"
console.log(calendarNames.of("buddhist")); // "Buddhist Calendar"
console.log(calendarNames.of("hebrew")); // "Hebrew Calendar"
console.log(calendarNames.of("islamic")); // "Islamic Calendar"
console.log(calendarNames.of("chinese")); // "Chinese Calendar"
يصبح هذا مفيدًا لتطبيقات الجدولة، ومنتقي التواريخ مع اختيار نظام التقويم، وواجهات التقويم المدولة.
تحويل رموز حقول التاريخ والوقت إلى أسماء الحقول
تحتوي واجهات التاريخ والوقت على حقول مسماة مثل السنة والشهر واليوم. قم بتعيين type: "dateTimeField" لتحويل معرفات الحقول إلى أسماء حقول مترجمة:
const dateFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
console.log(dateFields.of("year")); // "year"
console.log(dateFields.of("month")); // "month"
console.log(dateFields.of("day")); // "day"
console.log(dateFields.of("hour")); // "hour"
console.log(dateFields.of("minute")); // "minute"
console.log(dateFields.of("weekday")); // "day of the week"
console.log(dateFields.of("dayPeriod")); // "AM/PM"
console.log(dateFields.of("timeZoneName")); // "time zone"
تتم ترجمة أسماء هذه الحقول للغة العرض:
const englishFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
const spanishFields = new Intl.DisplayNames(["es"], { type: "dateTimeField" });
const japaneseFields = new Intl.DisplayNames(["ja"], { type: "dateTimeField" });
console.log(englishFields.of("month")); // "month"
console.log(spanishFields.of("month")); // "mes"
console.log(japaneseFields.of("month")); // "月"
تشمل معرفات الحقول الصالحة era، year، quarter، month، weekOfYear، weekday، day، dayPeriod، hour، minute، second، وtimeZoneName.
يدعم هذا النمط بناء منتقيات تاريخ سهلة الوصول، وواجهات تقويم، ومكونات اختيار الوقت مع تسميات مترجمة بشكل صحيح.
التحكم في طول العرض باستخدام خيارات النمط
يتحكم خيار style في مدى تفصيل المخرجات. تنتج ثلاث قيم أطوالًا مختلفة:
const longNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "long",
});
const shortNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "short",
});
const narrowNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "narrow",
});
console.log(longNames.of("US")); // "United States"
console.log(shortNames.of("US")); // "US"
console.log(narrowNames.of("US")); // "US"
ينتج نمط long (الافتراضي) الاسم الكامل. ينتج نمطا short وnarrow أشكالًا مختصرة عند توفرها، رغم أن ليس كل الرموز لها متغيرات أقصر.
يصبح النمط أكثر أهمية مع أسماء اللغات:
const longLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "long",
});
const shortLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "short",
});
console.log(longLanguages.of("en-US")); // "American English"
console.log(shortLanguages.of("en-US")); // "US English"
استخدم long للتسميات الكاملة في النماذج والواجهات المفصلة. استخدم short أو narrow للعروض المدمجة مثل التنقل على الأجهزة المحمولة أو عناصر واجهة المستخدم المقيدة بالمساحة.
التعامل مع المتغيرات اللغوية الإقليمية باستخدام languageDisplay
يمكن عرض رموز اللغة ذات العلامات الفرعية الإقليمية كلهجات أو كأسماء لغات قياسية مع محددات إقليمية. يتحكم خيار languageDisplay في هذا السلوك وينطبق فقط عند type: "language":
const dialectNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "dialect",
});
const standardNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "standard",
});
console.log(dialectNames.of("nl-BE")); // "Flemish"
console.log(standardNames.of("nl-BE")); // "Dutch (Belgium)"
console.log(dialectNames.of("en-AU")); // "Australian English"
console.log(standardNames.of("en-AU")); // "English (Australia)"
تعرض قيمة dialect (الافتراضية) المتغيرات الإقليمية باستخدام أسمائها الشائعة. تعرض قيمة standard دائمًا اللغة الأساسية مع محدد إقليمي بين قوسين.
اختر dialect عندما يكون للمتغيرات الإقليمية أسماء معروفة جيدًا يتعرف عليها المستخدمون. اختر standard للتنسيق المتسق أو عند العمل مع مجموعات لغة-منطقة أقل شيوعًا.
التحكم في سلوك الرجوع للرموز غير الصالحة
تستقبل طريقة of() رموزًا قد لا تحتوي على أسماء عرض مقابلة. يحدد خيار fallback ما يحدث:
const withCodeFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "code",
});
const withNoneFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
console.log(withCodeFallback.of("ZZ")); // "ZZ"
console.log(withNoneFallback.of("ZZ")); // undefined
قيمة code (الافتراضية) تُرجع رمز الإدخال عندما لا يوجد اسم عرض. قيمة none تُرجع undefined للرموز غير المعينة.
استخدم code عندما تحتاج دائمًا إلى قيمة نصية للعرض، حتى لو كانت ترجع إلى الرمز نفسه. استخدم none عندما تحتاج إلى اكتشاف الرموز غير الصالحة والتعامل معها بشكل صريح:
const regionNames = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
function getRegionName(code) {
const name = regionNames.of(code);
if (name === undefined) {
return "Unknown region";
}
return name;
}
console.log(getRegionName("US")); // "United States"
console.log(getRegionName("INVALID")); // "Unknown region"
بناء مكون منتقي الدول
تتكامل واجهة برمجة التطبيقات Intl.DisplayNames مباشرة مع مكونات الواجهة. يبني هذا المثال منتقي دول يعرض أسماء الدول بلغة المستخدم:
function CountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const countries = [
"US",
"GB",
"CA",
"AU",
"FR",
"DE",
"JP",
"CN",
"BR",
"IN",
];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{countries.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
يستقبل المكون خاصية locale التي تتحكم في لغة العرض. يؤدي تغيير خاصية locale إلى إعادة عرض القائمة المنسدلة بأسماء الدول المترجمة.
بناء مكون مبدل اللغة
تعرض مبدلات اللغة كل لغة بنظام كتابتها الخاص. قم بإنشاء نسخة DisplayNames لكل لغة:
function LanguageSwitcher({ currentLocale, onLocaleChange }) {
const languages = [
{ code: "en", name: "English" },
{ code: "es", name: "Español" },
{ code: "fr", name: "Français" },
{ code: "de", name: "Deutsch" },
{ code: "ja", name: "日本語" },
{ code: "zh", name: "中文" },
];
return (
<div>
{languages.map((lang) => {
const displayNames = new Intl.DisplayNames([lang.code], {
type: "language",
});
const nativeName = displayNames.of(lang.code);
return (
<button
key={lang.code}
onClick={() => onLocaleChange(lang.code)}
className={currentLocale === lang.code ? "active" : ""}
>
{nativeName}
</button>
);
})}
</div>
);
}
يعرض كل زر اسم اللغة بالخط الخاص بها. يتعرف المستخدمون على لغتهم فورًا بغض النظر عن لغة الواجهة الحالية.
بناء مكون محدد العملة
تستفيد محددات العملة من أسماء العملات المترجمة. يقوم هذا المثال بإنشاء محدد عملة يتكيف مع لغة العرض:
function CurrencySelector({ locale, value, onChange }) {
const currencyNames = new Intl.DisplayNames([locale], { type: "currency" });
const currencies = ["USD", "EUR", "GBP", "JPY", "CNY", "CAD", "AUD"];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select currency</option>
{currencies.map((code) => (
<option key={code} value={code}>
{code} - {currencyNames.of(code)}
</option>
))}
</select>
);
}
تعرض القائمة المنسدلة كلاً من رمز العملة واسم العملة المترجم. يرى المستخدمون في المناطق المختلفة أسماء العملات بلغتهم الخاصة.
الحصول على جميع القيم المدعومة
تُرجع طريقة Intl.supportedValuesOf() مصفوفات لجميع القيم المدعومة لكل نوع. هذا يلغي الحاجة إلى قوائم ثابتة من الرموز:
const regions = Intl.supportedValuesOf("region");
console.log(regions); // ["AD", "AE", "AF", "AG", "AI", ...]
const languages = Intl.supportedValuesOf("language");
console.log(languages); // ["aa", "ab", "ae", "af", "ak", ...]
const currencies = Intl.supportedValuesOf("currency");
console.log(currencies); // ["AED", "AFN", "ALL", "AMD", ...]
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars); // ["buddhist", "chinese", "coptic", ...]
قم ببناء محددات ديناميكية تتضمن تلقائيًا جميع القيم المدعومة:
function UniversalCountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const allRegions = Intl.supportedValuesOf("region");
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{allRegions.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
يتضمن هذا المكون كل رمز منطقة مدعوم من قبل المتصفح دون الحاجة إلى الاحتفاظ بقائمة ثابتة.
فهم متطلبات تنسيق الرموز
يتوقع كل نوع رموزًا بتنسيقات محددة. التنسيقات غير الصحيحة تنتج سلوك الرجوع بدلاً من أسماء العرض.
تتبع رموز المناطق معيار ISO 3166-1 alpha-2 (حرفان) أو UN M.49 (ثلاثة أرقام):
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States" (ISO 3166-1)
console.log(regionNames.of("001")); // "world" (UN M.49)
console.log(regionNames.of("150")); // "Europe" (UN M.49)
تتبع رموز اللغات معيار BCP 47، الذي يجمع بين رموز لغات ISO 639 مع علامات فرعية اختيارية للمنطقة والنص:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("zh-Hans")); // "Simplified Chinese"
console.log(languageNames.of("zh-Hans-CN")); // "Simplified Chinese (China)"
تتبع رموز العملات معيار ISO 4217 (ثلاثة أحرف):
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
تتبع رموز النصوص معيار ISO 15924 (أربعة أحرف، مع الحرف الأول كبير):
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
مقارنة الرموز غير حساسة لحالة الأحرف، ولكن اتباع التكبير القياسي يحسن القراءة:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("us")); // "United States"
console.log(regionNames.of("Us")); // "United States"
دعم المتصفح والتوافق
أصبحت واجهة برمجة التطبيقات Intl.DisplayNames متاحة في جميع المتصفحات الرئيسية في عام 2021. يمكن للتطبيقات الحديثة استخدامها بدون polyfills.
تحظى واجهة البرمجة الأساسية مع أنواع language وregion وscript وcurrency بدعم عالمي. ظهرت أنواع calendar وdateTimeField في إصدارات لاحقة من المتصفح ولكنها تتمتع بدعم واسع اعتبارًا من عام 2025.
تحقق من دعم الميزات في وقت التشغيل عند الضرورة:
if (typeof Intl.DisplayNames !== "undefined") {
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US"));
} else {
console.log("Intl.DisplayNames not supported");
}
بالنسبة للتطبيقات التي تدعم المتصفحات القديمة، ارجع إلى جداول البحث الثابتة أو مكتبات الطرف الثالث عندما تكون واجهة البرمجة غير متوفرة.
تحسين الأداء باستخدام التخزين المؤقت
إنشاء نسخ من DisplayNames له تكلفة ضئيلة، لكن التطبيقات التي تحول العديد من الرموز يجب أن تعيد استخدام النسخ:
const cache = new Map();
function getDisplayNames(locale, type) {
const key = `${locale}-${type}`;
if (!cache.has(key)) {
cache.set(key, new Intl.DisplayNames([locale], { type }));
}
return cache.get(key);
}
function getCountryName(locale, code) {
const displayNames = getDisplayNames(locale, "region");
return displayNames.of(code);
}
console.log(getCountryName("en", "US")); // "United States"
console.log(getCountryName("en", "FR")); // "France"
console.log(getCountryName("es", "US")); // "Estados Unidos"
يخزن التخزين المؤقت النسخ مفهرسة حسب اللغة والنوع. تستخدم الاستدعاءات اللاحقة النسخ الموجودة بدلاً من إنشاء نسخ جديدة.
هذا النمط مهم بشكل خاص في مسارات الشفرة الساخنة التي تحول مئات أو آلاف الرموز، مثل عرض جداول كبيرة من البيانات المترجمة.
مقارنة بالأساليب البديلة
قبل واجهة برمجة التطبيقات Intl.DisplayNames، استخدمت التطبيقات عدة أساليب لتحويل الرموز إلى أسماء.
جداول البحث المضمنة في الشفرة تطلبت صيانة ودعمت فقط لغات محددة مسبقًا:
const countryNames = {
US: "United States",
GB: "United Kingdom",
FR: "France",
};
function getCountryName(code) {
return countryNames[code] || code;
}
هذا الأسلوب يفشل عند إضافة لغات جديدة لأن كل لغة تحتاج إلى جدول بحث منفصل.
المكتبات الخارجية وفرت بيانات الترجمة لكنها زادت من حجم الحزمة:
import countries from "i18n-iso-countries";
import countriesEN from "i18n-iso-countries/langs/en.json";
import countriesES from "i18n-iso-countries/langs/es.json";
countries.registerLocale(countriesEN);
countries.registerLocale(countriesES);
console.log(countries.getName("US", "en")); // "United States"
console.log(countries.getName("US", "es")); // "Estados Unidos"
تضيف المكتبات كيلوبايتات من البيانات إلى الحزمة وتتطلب تحديثات عندما تظهر دول جديدة أو تتغير الأسماء.
تلغي واجهة برمجة التطبيقات Intl.DisplayNames كلا المشكلتين. يحافظ المتصفح على البيانات، مما يبقيها محدثة ويلغي مخاوف حجم الحزمة. تدعم البيانات جميع اللغات التي يدعمها المتصفح دون تنزيلات إضافية.