كيفية توحيد معرفات اللغات إلى الشكل القياسي
تحويل معرفات اللغات إلى الصيغة الموحدة مع الأحرف الكبيرة والصغيرة الصحيحة وترتيب المكونات
مقدمة
يمكن كتابة معرفات اللغات بطرق مختلفة عديدة بينما تشير إلى نفس اللغة والمنطقة. قد يكتب المستخدم EN-us، أو en-US، أو en-us، وجميعها الثلاثة تمثل الإنجليزية الأمريكية. عند تخزين معرفات اللغات أو مقارنتها أو عرضها، تخلق هذه الاختلافات عدم اتساق.
يحول التوحيد معرفات اللغات إلى شكل موحد قياسي. تقوم هذه العملية بضبط حالة الأحرف الكبيرة والصغيرة للمكونات، وترتيب الكلمات المفتاحية للامتدادات أبجدياً، وإنتاج تمثيل متسق يمكنك الاعتماد عليه في جميع أنحاء تطبيقك.
توفر JavaScript طرقاً مدمجة لتوحيد معرفات اللغات تلقائياً. يشرح هذا الدليل ما يعنيه التوحيد، وكيفية تطبيقه في الكود الخاص بك، ومتى تحسن المعرفات الموحدة منطق التدويل الخاص بك.
ما يعنيه التوحيد لمعرفات اللغات
يحول التوحيد معرف اللغة إلى شكله الموحد وفقاً لمعيار BCP 47 ومواصفات Unicode. يحتوي الشكل الموحد على قواعد محددة للأحرف الكبيرة والصغيرة والترتيب والبنية.
يتبع معرف اللغة الموحد هذه الاصطلاحات:
- رموز اللغة بأحرف صغيرة
- رموز الكتابة بحالة العنوان مع الحرف الأول كبير
- رموز المنطقة بأحرف كبيرة
- رموز المتغيرات بأحرف صغيرة
- الكلمات المفتاحية للامتدادات مرتبة أبجدياً
- سمات الامتدادات مرتبة أبجدياً
تنشئ هذه القواعد تمثيلاً قياسياً واحداً لكل لغة. بغض النظر عن كيفية كتابة المستخدم لمعرف اللغة، يكون الشكل الموحد دائماً هو نفسه.
فهم قواعد التوحيد
كل مكون من مكونات معرف اللغة له اصطلاح محدد للأحرف الكبيرة والصغيرة في الشكل الموحد.
حالة الأحرف في اللغة
رموز اللغات تستخدم دائماً أحرفاً صغيرة:
en (correct)
EN (incorrect, but normalizes to en)
eN (incorrect, but normalizes to en)
ينطبق هذا على رموز اللغات المكونة من حرفين وثلاثة أحرف.
حالة الأحرف في نظام الكتابة
رموز أنظمة الكتابة تستخدم حالة العنوان، حيث يكون الحرف الأول كبيراً والأحرف الثلاثة المتبقية صغيرة:
Hans (correct)
hans (incorrect, but normalizes to Hans)
HANS (incorrect, but normalizes to Hans)
تتضمن رموز أنظمة الكتابة الشائعة Latn للاتينية، Cyrl للسيريلية، Hans لأحرف هان المبسطة، وHant لأحرف هان التقليدية.
حالة الأحرف في المنطقة
رموز المناطق تستخدم دائماً أحرفاً كبيرة:
US (correct)
us (incorrect, but normalizes to US)
Us (incorrect, but normalizes to US)
ينطبق هذا على رموز الدول المكونة من حرفين المستخدمة في معظم معرفات اللغات المحلية.
ترتيب الامتدادات
علامات امتداد يونيكود تحتوي على كلمات مفتاحية تحدد تفضيلات التنسيق. في الشكل القياسي، تظهر هذه الكلمات المفتاحية بترتيب أبجدي حسب مفتاحها:
en-US-u-ca-gregory-nu-latn (correct)
en-US-u-nu-latn-ca-gregory (incorrect, but normalizes to first form)
مفتاح التقويم ca يأتي قبل مفتاح نظام الترقيم nu أبجدياً، لذلك يظهر ca-gregory أولاً في الشكل الموحد.
استخدام Intl.getCanonicalLocales للتوحيد
تقوم دالة Intl.getCanonicalLocales() بتوحيد معرفات اللغات المحلية وإرجاعها في الشكل القياسي. هذه هي الطريقة الأساسية للتوحيد في JavaScript.
const normalized = Intl.getCanonicalLocales("EN-us");
console.log(normalized);
// ["en-US"]
تقبل الدالة معرف لغة محلية بأي حالة أحرف وتُرجع الشكل القياسي بحالة الأحرف الصحيحة.
توحيد رموز اللغات
تحول الدالة رموز اللغات إلى أحرف صغيرة:
const result = Intl.getCanonicalLocales("FR-fr");
console.log(result);
// ["fr-FR"]
رمز اللغة FR يصبح fr في المخرجات.
توحيد رموز أنظمة الكتابة
تقوم الطريقة بتحويل رموز النصوص إلى حالة العنوان:
const result = Intl.getCanonicalLocales("zh-HANS-cn");
console.log(result);
// ["zh-Hans-CN"]
يصبح رمز النص HANS هو Hans، ويصبح رمز المنطقة cn هو CN.
توحيد رموز المناطق
تقوم الطريقة بتحويل رموز المناطق إلى أحرف كبيرة:
const result = Intl.getCanonicalLocales("en-gb");
console.log(result);
// ["en-GB"]
يصبح رمز المنطقة gb هو GB في الناتج.
توحيد كلمات الامتداد الرئيسية
تقوم الطريقة بترتيب كلمات الامتداد الرئيسية أبجديًا:
const result = Intl.getCanonicalLocales("en-US-u-nu-latn-hc-h12-ca-gregory");
console.log(result);
// ["en-US-u-ca-gregory-hc-h12-nu-latn"]
تُعاد ترتيب الكلمات الرئيسية من nu-latn-hc-h12-ca-gregory إلى ca-gregory-hc-h12-nu-latn لأن ca يأتي قبل hc وhc يأتي قبل nu أبجديًا.
توحيد معرفات اللغات المحلية المتعددة
تقبل طريقة Intl.getCanonicalLocales() مصفوفة من معرفات اللغات المحلية وتوحدها جميعًا:
const locales = ["EN-us", "fr-FR", "ZH-hans-cn"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US", "fr-FR", "zh-Hans-CN"]
يتم تحويل كل لغة محلية في المصفوفة إلى شكلها القانوني.
إزالة التكرارات
تقوم الطريقة بإزالة معرفات اللغات المحلية المكررة بعد التوحيد. إذا تم توحيد قيم إدخال متعددة إلى نفس الشكل القانوني، فإن النتيجة تحتوي على نسخة واحدة فقط:
const locales = ["en-US", "EN-us", "en-us"];
const normalized = Intl.getCanonicalLocales(locales);
console.log(normalized);
// ["en-US"]
تمثل جميع المدخلات الثلاثة نفس اللغة المحلية، لذا يحتوي الناتج على معرف موحد واحد.
تعتبر إزالة التكرارات هذه مفيدة عند معالجة إدخال المستخدم أو دمج قوائم اللغات المحلية من مصادر متعددة.
معالجة المعرفات غير الصالحة
إذا كان أي معرف لغة محلية في المصفوفة غير صالح، فإن الطريقة تطرح استثناء RangeError:
try {
Intl.getCanonicalLocales(["en-US", "invalid", "fr-FR"]);
} catch (error) {
console.error(error.message);
// "invalid is not a structurally valid language tag"
}
عند توحيد القوائم المقدمة من المستخدم، تحقق من صحة كل لغة محلية على حدة أو اعترض الأخطاء لتحديد المعرفات غير الصالحة بالتحديد.
استخدام Intl.Locale للتوحيد
يقوم منشئ Intl.Locale أيضًا بتطبيع معرفات اللغة عند إنشاء كائنات اللغة. يمكنك الوصول إلى الشكل المطبّع من خلال طريقة toString().
const locale = new Intl.Locale("EN-us");
console.log(locale.toString());
// "en-US"
يقبل المنشئ أي حالة أحرف صالحة وينتج كائن لغة مطبّع.
الوصول إلى المكونات المطبّعة
تُرجع كل خاصية من خصائص كائن اللغة الشكل المطبّع لذلك المكون:
const locale = new Intl.Locale("ZH-hans-CN");
console.log(locale.language);
// "zh"
console.log(locale.script);
// "Hans"
console.log(locale.region);
// "CN"
console.log(locale.baseName);
// "zh-Hans-CN"
تستخدم خصائص language وscript وregion جميعها حالة الأحرف الصحيحة للشكل القياسي.
التطبيع باستخدام الخيارات
عند إنشاء كائن لغة مع خيارات، يقوم المنشئ بتطبيع كل من المعرّف الأساسي والخيارات:
const locale = new Intl.Locale("EN-us", {
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h12"
});
console.log(locale.toString());
// "en-US-u-ca-gregory-hc-h12-nu-latn"
تظهر الكلمات المفتاحية للامتداد بترتيب أبجدي في المخرجات، حتى لو لم يحدد كائن الخيارات أي ترتيب معين.
لماذا يهم التطبيع
يوفر التطبيع الاتساق عبر تطبيقك. عند تخزين معرفات اللغة أو عرضها أو مقارنتها، يمنع استخدام الشكل القياسي الأخطاء الدقيقة ويحسن الموثوقية.
التخزين المتسق
عند تخزين معرفات اللغة في قواعد البيانات أو ملفات التكوين أو التخزين المحلي، تمنع الأشكال المطبّعة التكرار:
const userPreferences = new Set();
function saveUserLocale(identifier) {
const normalized = Intl.getCanonicalLocales(identifier)[0];
userPreferences.add(normalized);
}
saveUserLocale("en-US");
saveUserLocale("EN-us");
saveUserLocale("en-us");
console.log(userPreferences);
// Set { "en-US" }
بدون التطبيع، ستحتوي المجموعة على ثلاثة إدخالات لنفس اللغة. مع التطبيع، تحتوي بشكل صحيح على إدخال واحد.
المقارنة الموثوقة
تتطلب مقارنة معرفات اللغة التطبيع. معرّفان يختلفان فقط في حالة الأحرف يمثلان نفس اللغة:
function isSameLocale(locale1, locale2) {
const normalized1 = Intl.getCanonicalLocales(locale1)[0];
const normalized2 = Intl.getCanonicalLocales(locale2)[0];
return normalized1 === normalized2;
}
console.log(isSameLocale("en-US", "EN-us"));
// true
console.log(isSameLocale("en-US", "en-GB"));
// false
تنتج المقارنة المباشرة للسلاسل النصية للمعرفات غير المطبّعة نتائج غير صحيحة.
العرض المتسق
عند عرض معرفات اللغة للمستخدمين أو في مخرجات التصحيح، توفر الأشكال المطبّعة تنسيقًا متسقًا:
function displayLocale(identifier) {
try {
const normalized = Intl.getCanonicalLocales(identifier)[0];
return `Current locale: ${normalized}`;
} catch (error) {
return "Invalid locale identifier";
}
}
console.log(displayLocale("EN-us"));
// "Current locale: en-US"
console.log(displayLocale("zh-HANS-cn"));
// "Current locale: zh-Hans-CN"
يرى المستخدمون معرفات اللغة منسقة بشكل صحيح بغض النظر عن تنسيق الإدخال.
التطبيقات العملية
تحل المعايرة المشاكل الشائعة عند العمل مع معرفات اللغات في التطبيقات الحقيقية.
معايرة إدخال المستخدم
عندما يدخل المستخدمون معرفات اللغات في النماذج أو الإعدادات، قم بمعايرة الإدخال قبل تخزينه:
function processLocaleInput(input) {
try {
const normalized = Intl.getCanonicalLocales(input)[0];
return {
success: true,
locale: normalized
};
} catch (error) {
return {
success: false,
error: "Please enter a valid locale identifier"
};
}
}
const result = processLocaleInput("fr-ca");
console.log(result);
// { success: true, locale: "fr-CA" }
يضمن هذا تنسيقاً متسقاً في قاعدة البيانات أو التكوين الخاص بك.
بناء جداول البحث للغات
عند إنشاء جداول بحث للترجمات أو البيانات الخاصة باللغة، استخدم مفاتيح معايرة:
const translations = new Map();
function addTranslation(locale, key, value) {
const normalized = Intl.getCanonicalLocales(locale)[0];
if (!translations.has(normalized)) {
translations.set(normalized, {});
}
translations.get(normalized)[key] = value;
}
addTranslation("en-us", "hello", "Hello");
addTranslation("EN-US", "goodbye", "Goodbye");
console.log(translations.get("en-US"));
// { hello: "Hello", goodbye: "Goodbye" }
كلا الاستدعاءين لـ addTranslation يستخدمان نفس المفتاح المعاير، لذلك يتم تخزين الترجمات في نفس الكائن.
دمج قوائم اللغات
عند دمج معرفات اللغات من مصادر متعددة، قم بمعايرتها وإزالة التكرارات:
function mergeLocales(...sources) {
const allLocales = sources.flat();
const normalized = Intl.getCanonicalLocales(allLocales);
return normalized;
}
const userLocales = ["en-us", "fr-FR"];
const appLocales = ["EN-US", "de-de"];
const systemLocales = ["en-US", "es-mx"];
const merged = mergeLocales(userLocales, appLocales, systemLocales);
console.log(merged);
// ["en-US", "fr-FR", "de-DE", "es-MX"]
تزيل الطريقة التكرارات وتعاير الأحرف الكبيرة والصغيرة عبر جميع المصادر.
إنشاء واجهات اختيار اللغة
عند بناء قوائم منسدلة أو واجهات اختيار، قم بمعايرة معرفات اللغات للعرض:
function buildLocaleOptions(locales) {
const normalized = Intl.getCanonicalLocales(locales);
return normalized.map(locale => {
const localeObj = new Intl.Locale(locale);
const displayNames = new Intl.DisplayNames([locale], {
type: "language"
});
return {
value: locale,
label: displayNames.of(localeObj.language)
};
});
}
const options = buildLocaleOptions(["EN-us", "fr-FR", "DE-de"]);
console.log(options);
// [
// { value: "en-US", label: "English" },
// { value: "fr-FR", label: "French" },
// { value: "de-DE", label: "German" }
// ]
توفر القيم المعايرة معرفات متسقة لإرسال النماذج.
التحقق من صحة ملفات التكوين
عند تحميل معرفات اللغات من ملفات التكوين، قم بمعايرتها أثناء التهيئة:
function loadLocaleConfig(config) {
const validatedConfig = {
defaultLocale: null,
supportedLocales: []
};
try {
validatedConfig.defaultLocale = Intl.getCanonicalLocales(
config.defaultLocale
)[0];
} catch (error) {
console.error("Invalid default locale:", config.defaultLocale);
validatedConfig.defaultLocale = "en-US";
}
config.supportedLocales.forEach(locale => {
try {
const normalized = Intl.getCanonicalLocales(locale)[0];
validatedConfig.supportedLocales.push(normalized);
} catch (error) {
console.warn("Skipping invalid locale:", locale);
}
});
return validatedConfig;
}
const config = {
defaultLocale: "en-us",
supportedLocales: ["EN-us", "fr-FR", "invalid", "de-DE"]
};
const validated = loadLocaleConfig(config);
console.log(validated);
// {
// defaultLocale: "en-US",
// supportedLocales: ["en-US", "fr-FR", "de-DE"]
// }
يكتشف هذا أخطاء التكوين مبكراً ويضمن أن تطبيقك يستخدم معرفات معايرة صالحة.
المعايرة ومطابقة اللغات
المعايرة مهمة لخوارزميات مطابقة اللغات. عند إيجاد أفضل مطابقة للغة لتفضيل المستخدم، قارن الأشكال المعايرة:
function findBestMatch(userPreference, availableLocales) {
const normalizedPreference = Intl.getCanonicalLocales(userPreference)[0];
const normalizedAvailable = Intl.getCanonicalLocales(availableLocales);
if (normalizedAvailable.includes(normalizedPreference)) {
return normalizedPreference;
}
const preferenceLocale = new Intl.Locale(normalizedPreference);
const languageMatch = normalizedAvailable.find(available => {
const availableLocale = new Intl.Locale(available);
return availableLocale.language === preferenceLocale.language;
});
if (languageMatch) {
return languageMatch;
}
return normalizedAvailable[0];
}
const available = ["en-us", "fr-FR", "DE-de"];
console.log(findBestMatch("EN-GB", available));
// "en-US"
يضمن التطبيع عمل منطق المطابقة بشكل صحيح بغض النظر عن حالة الأحرف في المدخلات.
التطبيع لا يغير المعنى
يؤثر التطبيع فقط على تمثيل معرّف اللغة المحلية. لا يغير اللغة أو الكتابة أو المنطقة التي يمثلها المعرّف.
const locale1 = new Intl.Locale("en-us");
const locale2 = new Intl.Locale("EN-US");
console.log(locale1.language === locale2.language);
// true
console.log(locale1.region === locale2.region);
// true
console.log(locale1.toString() === locale2.toString());
// true
كلا المعرّفين يشيران إلى الإنجليزية الأمريكية. التطبيع يضمن فقط كتابتهما بنفس الطريقة.
هذا يختلف عن العمليات مثل maximize() و minimize()، التي تضيف أو تزيل مكونات ويمكن أن تغير مستوى التحديد للمعرّف.
دعم المتصفحات
تعمل طريقة Intl.getCanonicalLocales() في جميع المتصفحات الحديثة. توفر Chrome وFirefox وSafari وEdge دعمًا كاملاً.
يدعم Node.js طريقة Intl.getCanonicalLocales() بدءًا من الإصدار 9، مع دعم كامل في الإصدار 10 وما بعده.
يعمل مُنشئ Intl.Locale وسلوك التطبيع الخاص به في جميع المتصفحات التي تدعم واجهة برمجة التطبيقات Intl.Locale. يشمل ذلك الإصدارات الحديثة من Chrome وFirefox وSafari وEdge.
الخلاصة
يحوّل التطبيع معرّفات اللغة المحلية إلى شكلها القانوني من خلال تطبيق قواعد الأحرف القياسية وترتيب الكلمات المفتاحية للامتدادات. ينشئ هذا تمثيلات متسقة يمكنك تخزينها ومقارنتها وعرضها بشكل موثوق.
المفاهيم الأساسية:
- يستخدم الشكل القانوني أحرفًا صغيرة للغات، وحالة العنوان للكتابات، وأحرفًا كبيرة للمناطق
- يتم ترتيب الكلمات المفتاحية للامتدادات أبجديًا في الشكل القانوني
- تقوم طريقة
Intl.getCanonicalLocales()بتطبيع المعرّفات وإزالة التكرارات - ينتج مُنشئ
Intl.Localeأيضًا مخرجات مطبّعة - التطبيع لا يغير معنى معرّف اللغة المحلية
- استخدم المعرّفات المطبّعة للتخزين والمقارنة والعرض
التطبيع هو عملية أساسية لأي تطبيق يعمل مع معرّفات اللغة المحلية. يمنع الأخطاء الناتجة عن عدم اتساق حالة الأحرف ويضمن أن منطق التدويل الخاص بك يتعامل مع معرّفات اللغة المحلية بشكل موثوق.