كيفية إضافة العلامات الفرعية المحتملة إلى اللغات المحلية غير المكتملة

استخدم JavaScript لإكمال معرفات اللغة المحلية الجزئية بالنص والمنطقة الأكثر احتمالاً

مقدمة

عند العمل مع معرفات اللغة المحلية، قد تتلقى أحياناً معلومات غير مكتملة. قد يحدد المستخدم رمز اللغة فقط مثل ja دون الإشارة إلى النص أو المنطقة. على الرغم من أن هذا المعرف الجزئي صالح، إلا أنه يفتقر إلى الدقة اللازمة لعمليات معينة مثل مقارنة اللغات المحلية أو تحديد اصطلاحات التنسيق.

توفر JavaScript طريقة لإكمال هذه المعرفات الجزئية عن طريق إضافة المكونات المفقودة الأكثر احتمالاً. تستخدم هذه العملية بيانات اللغة لاستنتاج النص والمنطقة التي يستخدمها مستخدمو تلك اللغة عادةً.

يشرح هذا الدليل ماهية العلامات الفرعية المحتملة، وكيف تحددها JavaScript، ومتى تستخدم هذه الميزة في تطبيقاتك.

ما هي العلامات الفرعية المحتملة

العلامات الفرعية المحتملة هي رموز النص والمنطقة التي تظهر بشكل أكثر شيوعاً مع لغة معينة. تأتي هذه الارتباطات من بيانات استخدام اللغة في العالم الحقيقي التي يحتفظ بها اتحاد Unicode.

على سبيل المثال، عادةً ما تُكتب اللغة الإنجليزية بالنص اللاتيني وتُستخدم بشكل أكثر شيوعاً في الولايات المتحدة. إذا كان لديك رمز اللغة فقط 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، مما يشير إلى أن الأحرف الصينية المبسطة متوقعة.

كيفية عمل الخوارزمية

تستخدم خوارزمية إضافة العلامات الفرعية المحتملة قاعدة بيانات لمعلومات استخدام اللغة لتحديد المكونات المفقودة. يتم صيانة قاعدة البيانات هذه من قبل اتحاد Unicode كجزء من مستودع بيانات اللغات المحلية المشتركة.

تفحص الخوارزمية المعلومات التي تقدمها وتملأ الفجوات:

  • إذا قدمت لغة فقط، فإنها تضيف النص والمنطقة الأكثر شيوعاً لتلك اللغة
  • إذا قدمت لغة ونصاً، فإنها تضيف المنطقة الأكثر شيوعاً لهذا المزيج
  • إذا قدمت لغة ومنطقة، فإنها تضيف النص الأكثر شيوعاً لهذا المزيج
  • إذا قدمت المكونات الثلاثة جميعها، فإنها تبقى دون تغيير

تستند القرارات إلى بيانات إحصائية حول استخدام اللغة في جميع أنحاء العالم.

استخدام طريقة 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 كمنطقة.

يتم الحفاظ على علامات الامتداد

تحدد علامات امتداد Unicode تفضيلات التنسيق مثل أنظمة التقويم وأنظمة الترقيم ودورات الساعة. تظهر هذه العلامات بعد -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 وتجد أقرب تطابق.

متى لا تستخدم maximize

لا تحتاج إلى تعظيم اللغات المحلية قبل تمريرها إلى واجهات برمجة التطبيقات للتنسيق. تتعامل 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() متاحة في جميع المتصفحات الحديثة. يدعمها Chrome وFirefox وSafari وEdge كجزء من واجهة برمجة التطبيقات Intl.Locale.

يدعم Node.js طريقة maximize() بدءاً من الإصدار 12، مع دعم كامل في الإصدار 14 وما بعده.

الملخص

تكمل العلامات الفرعية المحتملة معرفات اللغة المحلية الجزئية بإضافة النص والمنطقة الأكثر شيوعاً للغة معينة. تنفذ طريقة Intl.Locale.maximize() خوارزمية Unicode Add Likely Subtags لإجراء هذا التوسيع.

النقاط الرئيسية:

  • تستند العلامات الفرعية المحتملة إلى بيانات استخدام اللغة في العالم الحقيقي
  • تضيف طريقة maximize() رموز النص والمنطقة المفقودة
  • تظل علامات الامتداد للتقويمات وأنظمة الترقيم دون تغيير
  • استخدم التعظيم لتطبيع إدخال المستخدم ومقارنة اللغات المحلية
  • لا تتطلب واجهات برمجة التطبيقات للتنسيق لغات محلية معظمة

توفر طريقة maximize() طريقة موحدة للعمل مع معرفات اللغة المحلية الكاملة عندما يتطلب منطق تطبيقك معلومات صريحة عن النص والمنطقة.