كيفية إضافة العلامات المحتملة إلى اللغات المحلية غير المكتملة
استخدم جافا سكريبت لإكمال معرفات اللغة المحلية الجزئية بالنص والمنطقة الأكثر احتمالًا
مقدمة
عند العمل مع معرّفات اللغات المحلية، قد تتلقى معلومات غير مكتملة. قد يحدد المستخدم رمز اللغة فقط مثل ja دون الإشارة إلى النص أو المنطقة. على الرغم من أن هذا المعرّف الجزئي صالح، إلا أنه يفتقر إلى التحديد اللازم لبعض العمليات مثل مقارنة اللغات المحلية أو تحديد اتفاقيات التنسيق.
توفر جافا سكريبت طريقة لإكمال هذه المعرّفات الجزئية من خلال إضافة المكونات المفقودة الأكثر احتمالاً. تستخدم هذه العملية بيانات اللغة لاستنتاج النص والمنطقة التي يستخدمها عادةً مستخدمو تلك اللغة.
يشرح هذا الدليل ماهية العلامات الفرعية المحتملة، وكيف تحددها جافا سكريبت، ومتى تستخدم هذه الميزة في تطبيقاتك.
ما هي العلامات الفرعية المحتملة
العلامات الفرعية المحتملة هي رموز النص والمنطقة التي تظهر بشكل شائع مع لغة معينة. تأتي هذه الارتباطات من بيانات استخدام اللغة في العالم الحقيقي التي يحتفظ بها اتحاد يونيكود.
على سبيل المثال، تُكتب اللغة الإنجليزية عادةً بالنص اللاتيني وتُستخدم بشكل شائع في الولايات المتحدة. إذا كان لديك رمز اللغة en فقط، فإن العلامات الفرعية المحتملة هي Latn للنص وUS للمنطقة، مما يعطيك المعرّف الكامل en-Latn-US.
يعتمد الاحتمال على عدد المتحدثين وأنماط الاستخدام التاريخية. تُرجع الخوارزمية دائمًا المجموعة الأكثر شيوعًا إحصائيًا.
لماذا نضيف العلامات الفرعية المحتملة
تعمل معرّفات اللغات المحلية الجزئية لمعظم عمليات التنسيق. تقبل واجهات برمجة التطبيقات Intl.DateTimeFormat وIntl.NumberFormat الرمز en وستطبق الإعدادات الافتراضية المنطقية. ومع ذلك، هناك حالات يكون فيها وجود معرّفات كاملة ضروريًا.
مقارنة معرّفات اللغات المحلية
عند مقارنة معرّفين للغات المحلية لمعرفة ما إذا كانا يشيران إلى نفس اللغة والمنطقة، تخلق المعرّفات الجزئية غموضًا. هل en تعني نفس شيء en-US، أم أنها مختلفة لأن أحدهما يحدد منطقة والآخر لا؟
إضافة العلامات الفرعية المحتملة تزيل هذا الغموض. كل من en وen-US يتم تعظيمهما إلى en-Latn-US، مما يجعلهما قابلين للمقارنة مباشرة.
const locale1 = new Intl.Locale("en");
const locale2 = new Intl.Locale("en-US");
console.log(locale1.baseName === locale2.baseName);
// false - they look different
const maximized1 = locale1.maximize();
const maximized2 = locale2.maximize();
console.log(maximized1.baseName === maximized2.baseName);
// true - both are "en-Latn-US"
تخزين الأشكال القياسية
عند تخزين معرفات اللغات المحلية في قواعد البيانات أو ملفات التكوين، فإن استخدام الأشكال الكاملة يضمن الاتساق. كل لغة فرنسية تصبح fr-Latn-FR، وكل لغة يابانية تصبح ja-Jpan-JP، وهكذا.
هذا الاتساق يجعل البحث والتصفية والتجميع حسب اللغة المحلية أكثر موثوقية.
تحديد السلوك الخاص بالنص
تستخدم بعض اللغات نصوصًا متعددة، ويؤثر النص على عرض النص واختيار الخط والترتيب. يمكن كتابة الصينية بأحرف مبسطة أو تقليدية، ويمكن للصربية استخدام النص السيريلي أو اللاتيني.
إضافة العلامات الفرعية المحتملة تجعل النص صريحًا. إذا قدم المستخدم zh دون تحديد نص، فإن تعظيمها ينتج zh-Hans-CN، مما يشير إلى أن الأحرف الصينية المبسطة متوقعة.
كيف تعمل الخوارزمية
تستخدم خوارزمية إضافة العلامات الفرعية المحتملة قاعدة بيانات لمعلومات استخدام اللغة لتحديد المكونات المفقودة. يتم الحفاظ على قاعدة البيانات هذه من قبل اتحاد يونيكود كجزء من مستودع بيانات اللغات المحلية المشتركة.
تفحص الخوارزمية المعلومات التي تقدمها وتملأ الفجوات:
- إذا قدمت لغة فقط، فإنها تضيف النص والمنطقة الأكثر شيوعًا لتلك اللغة
- إذا قدمت لغة ونصًا، فإنها تضيف المنطقة الأكثر شيوعًا لهذه المجموعة
- إذا قدمت لغة ومنطقة، فإنها تضيف النص الأكثر شيوعًا لهذه المجموعة
- إذا قدمت المكونات الثلاثة جميعها، فإنها تبقى دون تغيير
تستند القرارات إلى بيانات إحصائية حول استخدام اللغة في جميع أنحاء العالم.
استخدام طريقة maximize
طريقة maximize() متاحة على كائنات Intl.Locale. تعيد كائن لغة محلية جديدًا مع إضافة العلامات الفرعية المحتملة إلى الاسم الأساسي.
const locale = new Intl.Locale("ja");
const maximized = locale.maximize();
console.log(locale.baseName);
// "ja"
console.log(maximized.baseName);
// "ja-Jpan-JP"
لا تقوم الطريقة بتعديل كائن اللغة المحلية الأصلي. بل تنشئ وتعيد كائنًا جديدًا.
أمثلة بلغات مختلفة
تحتوي اللغات المختلفة على علامات فرعية محتملة مختلفة بناءً على المكان الذي يتم التحدث بها فيه بشكل أساسي والنصوص التي تستخدمها.
اللغات الأوروبية
تتوسع الفرنسية إلى فرنسا مع النص اللاتيني:
const french = new Intl.Locale("fr");
const maximized = french.maximize();
console.log(maximized.baseName);
// "fr-Latn-FR"
تتوسع الألمانية إلى ألمانيا مع النص اللاتيني:
const german = new Intl.Locale("de");
const maximized = german.maximize();
console.log(maximized.baseName);
// "de-Latn-DE"
اللغات ذات النصوص غير اللاتينية
تتوسع اليابانية إلى اليابان مع النص الياباني:
const japanese = new Intl.Locale("ja");
const maximized = japanese.maximize();
console.log(maximized.baseName);
// "ja-Jpan-JP"
تتوسع العربية إلى مصر مع النص العربي:
const arabic = new Intl.Locale("ar");
const maximized = arabic.maximize();
console.log(maximized.baseName);
// "ar-Arab-EG"
تتوسع الصينية بدون نص إلى الأحرف المبسطة والصين:
const chinese = new Intl.Locale("zh");
const maximized = chinese.maximize();
console.log(maximized.baseName);
// "zh-Hans-CN"
المعرفات الجزئية مع المناطق
عندما تقدم لغة ومنطقة ولكن بدون نص، تضيف الخوارزمية النص:
const britishEnglish = new Intl.Locale("en-GB");
const maximized = britishEnglish.maximize();
console.log(maximized.baseName);
// "en-Latn-GB"
تبقى المنطقة كما هي محددة. يتم إضافة النص المفقود فقط.
المعرفات الجزئية مع النصوص
عندما تقدم لغة ونصًا ولكن بدون منطقة، تضيف الخوارزمية المنطقة الأكثر شيوعًا لذلك النص:
const traditionalChinese = new Intl.Locale("zh-Hant");
const maximized = traditionalChinese.maximize();
console.log(maximized.baseName);
// "zh-Hant-TW"
تُستخدم الأحرف الصينية التقليدية بشكل أساسي في تايوان، لذلك تتم إضافة TW كمنطقة.
يتم الحفاظ على علامات الامتداد
تحدد علامات امتداد يونيكود تفضيلات التنسيق مثل أنظمة التقويم وأنظمة الترقيم ودورات الساعة. تظهر هذه العلامات بعد -u- في معرف اللغة المحلية.
لا تغير طريقة maximize() علامات الامتداد. فهي تؤثر فقط على مكونات اللغة والنص والمنطقة.
const locale = new Intl.Locale("fr", {
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h23"
});
console.log(locale.toString());
// "fr-u-ca-gregory-hc-h23-nu-latn"
const maximized = locale.maximize();
console.log(maximized.toString());
// "fr-Latn-FR-u-ca-gregory-hc-h23-nu-latn"
يتغير الاسم الأساسي من fr إلى fr-Latn-FR، لكن علامات الامتداد تبقى متطابقة.
متى تستخدم maximize
استخدم طريقة maximize() عندما تحتاج إلى معرفات لغة كاملة لأغراض الاتساق أو المقارنة.
تطبيع إدخال المستخدم
قد يدخل المستخدمون اللغات بأشكال مختلفة. قد يكتب البعض en، وآخرون en-US، وآخرون en-Latn-US. تعظيم جميع المدخلات ينشئ تنسيقًا متسقًا:
function normalizeLocale(input) {
try {
const locale = new Intl.Locale(input);
const maximized = locale.maximize();
return maximized.baseName;
} catch (error) {
return null;
}
}
console.log(normalizeLocale("en"));
// "en-Latn-US"
console.log(normalizeLocale("en-US"));
// "en-Latn-US"
console.log(normalizeLocale("en-Latn-US"));
// "en-Latn-US"
جميع المدخلات الثلاثة تنتج نفس الشكل المطبع.
بناء سلاسل الرجوع للغات
عندما لا تكون لغة محددة متاحة، تعود التطبيقات إلى لغات أكثر عمومية. يساعد التعظيم في بناء هذه السلاسل بشكل صحيح:
function buildFallbackChain(localeString) {
const locale = new Intl.Locale(localeString);
const maximized = locale.maximize();
const chain = [maximized.toString()];
if (maximized.script && maximized.region) {
const withoutRegion = new Intl.Locale(
`${maximized.language}-${maximized.script}`
);
chain.push(withoutRegion.toString());
}
if (maximized.region) {
chain.push(maximized.language);
}
chain.push("en");
return chain;
}
console.log(buildFallbackChain("zh-TW"));
// ["zh-Hant-TW", "zh-Hant", "zh", "en"]
هذا ينشئ تراجعًا مناسبًا من اللغة الأكثر تحديدًا إلى اللغة الأكثر عمومية.
مطابقة تفضيلات المستخدم مع اللغات المتاحة
عندما يكون لديك مجموعة من الترجمات المتاحة وتحتاج إلى العثور على أفضل تطابق لتفضيل المستخدم، فإن تعظيم كلا الجانبين يمكّن من المقارنة الدقيقة:
function findBestMatch(userPreference, availableLocales) {
const userMaximized = new Intl.Locale(userPreference).maximize();
const matches = availableLocales.map(available => {
const availableMaximized = new Intl.Locale(available).maximize();
let score = 0;
if (userMaximized.language === availableMaximized.language) score += 1;
if (userMaximized.script === availableMaximized.script) score += 1;
if (userMaximized.region === availableMaximized.region) score += 1;
return { locale: available, score };
});
matches.sort((a, b) => b.score - a.score);
return matches[0].locale;
}
const available = ["en-US", "en-GB", "fr-FR", "de-DE"];
console.log(findBestMatch("en", available));
// "en-US"
تقوم الدالة بتوسيع تفضيل المستخدم en إلى en-Latn-US وتجد أقرب تطابق.
متى لا تستخدم التعظيم
لست بحاجة إلى تعظيم اللغات المحلية قبل تمريرها إلى واجهات برمجة التطبيقات الخاصة بالتنسيق. تتعامل منشئات Intl.DateTimeFormat وIntl.NumberFormat وغيرها من منشئات التنسيق مع المعرفات الجزئية بشكل صحيح.
const date = new Date("2025-03-15");
const partial = new Intl.DateTimeFormat("fr").format(date);
const maximized = new Intl.DateTimeFormat("fr-Latn-FR").format(date);
console.log(partial);
// "15/03/2025"
console.log(maximized);
// "15/03/2025"
كلاهما ينتج نفس المخرجات. التحديد الإضافي لا يغير سلوك التنسيق في هذه الحالة.
استخدم maximize() عندما تحتاج إلى المعلومات الصريحة للمنطق الخاص بك، وليس عند تمرير اللغات المحلية إلى المنسقات المدمجة.
دعم المتصفح
طريقة maximize() متاحة في جميع المتصفحات الحديثة. كروم وفايرفوكس وسفاري وإيدج جميعها تدعمها كجزء من واجهة برمجة تطبيقات Intl.Locale.
يدعم Node.js طريقة maximize() بدءًا من الإصدار 12، مع دعم كامل في الإصدار 14 وما بعده.
الملخص
العلامات المحتملة تكمل معرفات اللغة المحلية الجزئية بإضافة النص والمنطقة الأكثر شيوعًا للغة معينة. تنفذ طريقة Intl.Locale.maximize() خوارزمية Unicode لإضافة العلامات المحتملة لإجراء هذا التوسيع.
النقاط الرئيسية:
- العلامات المحتملة تستند إلى بيانات استخدام اللغة في العالم الحقيقي
- طريقة
maximize()تضيف رموز النص والمنطقة المفقودة - علامات التمديد للتقويمات وأنظمة الترقيم تبقى دون تغيير
- استخدم التعظيم لتطبيع إدخال المستخدم ومقارنة اللغات المحلية
- واجهات برمجة التطبيقات الخاصة بالتنسيق لا تتطلب لغات محلية معظمة
توفر طريقة maximize() طريقة موحدة للعمل مع معرفات اللغة المحلية الكاملة عندما يتطلب منطق التطبيق الخاص بك معلومات صريحة عن النص والمنطقة.