كيفية استخراج اللغة والبلد والنص من معرّف اللغة

استخدم JavaScript لتحليل معرّفات اللغة والوصول إلى مكوناتها الفردية

مقدمة

معرّفات اللغة مثل en-US وfr-CA وzh-Hans-CN تشفّر عدة معلومات في سلسلة نصية واحدة. تخبرك هذه المكونات باللغة المستخدمة والمنطقة التي يتم التحدث بها فيها، وأحياناً نظام الكتابة.

عند بناء تطبيقات متعددة اللغات، غالباً ما تحتاج إلى استخراج هذه المكونات الفردية. قد ترغب في عرض اسم اللغة فقط للمستخدمين، أو تجميع اللغات حسب المنطقة، أو التحقق من نظام الكتابة الذي يستخدمه معرّف اللغة. بدلاً من تحليل السلاسل النصية يدوياً باستخدام التعبيرات النمطية، توفر JavaScript واجهة برمجة التطبيقات Intl.Locale لاستخراج المكونات بشكل موثوق.

يشرح هذا الدليل المكونات الموجودة في معرّفات اللغة، وكيفية استخراجها باستخدام واجهة برمجة التطبيقات Intl.Locale، ومتى تحتاج إلى استخدام هذه المكونات عملياً.

ما هي المكونات الموجودة في معرّفات اللغة

تتبع معرّفات اللغة معيار BCP 47، الذي يحدد بنية لوصف اللغات والاختلافات الإقليمية. يمكن أن يحتوي معرّف اللغة الكامل على عدة مكونات مفصولة بشرطات.

المكونات الثلاثة الأكثر شيوعاً هي:

  • اللغة: اللغة الأساسية المستخدمة، مثل الإنجليزية أو الإسبانية أو الصينية
  • المنطقة: المنطقة الجغرافية التي يتم استخدام اللغة فيها، مثل الولايات المتحدة أو كندا أو الصين
  • النص: نظام الكتابة المستخدم لتمثيل اللغة، مثل الأحرف اللاتينية أو السيريلية أو الصينية

يحتوي معرّف اللغة البسيط على رمز اللغة فقط:

en

تتضمن معظم معرّفات اللغة لغة ومنطقة:

en-US
fr-CA
es-MX

تتضمن بعض معرّفات اللغات نظام كتابة عندما يمكن كتابة اللغة بأنظمة كتابة متعددة:

zh-Hans-CN
zh-Hant-TW
sr-Cyrl-RS
sr-Latn-RS

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

استخدام Intl.Locale لاستخراج المكونات

تحوّل واجهة برمجة التطبيقات Intl.Locale سلاسل معرّفات اللغات إلى كائنات منظمة. بمجرد إنشاء كائن لغة، يمكنك قراءة مكوناته من خلال الخصائص.

أنشئ كائن لغة عن طريق تمرير المعرّف إلى المُنشئ:

const locale = new Intl.Locale("en-US");

console.log(locale.language); // "en"
console.log(locale.region); // "US"

يعرض كائن اللغة خصائص تتوافق مع كل مكون من مكونات المعرّف. توفر هذه الخصائص وصولاً منظماً دون الحاجة إلى تحليل السلاسل النصية.

استخراج رمز اللغة

تُرجع الخاصية language مكون اللغة من معرّف اللغة. هذا هو الرمز المكون من حرفين أو ثلاثة أحرف الذي يحدد اللغة الأساسية.

const english = new Intl.Locale("en-US");
console.log(english.language); // "en"

const french = new Intl.Locale("fr-CA");
console.log(french.language); // "fr"

const chinese = new Intl.Locale("zh-Hans-CN");
console.log(chinese.language); // "zh"

تتبع رموز اللغات معيار ISO 639. تتضمن الرموز الشائعة en للإنجليزية، وes للإسبانية، وfr للفرنسية، وde للألمانية، وja لليابانية، وzh للصينية.

رمز اللغة موجود دائماً في معرّف لغة صالح. إنه المكون الوحيد المطلوب.

const languageOnly = new Intl.Locale("ja");
console.log(languageOnly.language); // "ja"
console.log(languageOnly.region); // undefined

عند استخراج رمز اللغة، يمكنك استخدامه لاختيار الترجمات، أو تحديد قواعد معالجة النصوص، أو إنشاء محددات اللغة للمستخدمين.

استخراج رمز المنطقة

تُرجع الخاصية region مكون المنطقة من معرّف اللغة. هذا هو الرمز المكون من حرفين الذي يحدد المنطقة الجغرافية التي تُستخدم فيها اللغة.

const americanEnglish = new Intl.Locale("en-US");
console.log(americanEnglish.region); // "US"

const britishEnglish = new Intl.Locale("en-GB");
console.log(britishEnglish.region); // "GB"

const canadianFrench = new Intl.Locale("fr-CA");
console.log(canadianFrench.region); // "CA"

تتبع رموز المناطق معيار ISO 3166-1. وتستخدم حرفين كبيرين لتمثيل البلدان والأقاليم. تشمل الرموز الشائعة US للولايات المتحدة، وGB للمملكة المتحدة، وCA لكندا، وMX للمكسيك، وFR لفرنسا، وCN للصين.

يغير رمز المنطقة طريقة تنسيق التواريخ والأرقام والعملات. تستخدم الإنجليزية الأمريكية تواريخ بصيغة شهر-يوم-سنة ونقاطاً كفواصل عشرية. بينما تستخدم الإنجليزية البريطانية تواريخ بصيغة يوم-شهر-سنة وفواصل للآلاف.

رموز المناطق اختيارية في معرفات اللغة. عندما لا يحتوي معرف اللغة على منطقة، تُرجع الخاصية region القيمة undefined:

const genericSpanish = new Intl.Locale("es");
console.log(genericSpanish.region); // undefined

عند استخراج رمز المنطقة، يمكنك استخدامه لتخصيص التنسيق الإقليمي، أو اختيار محتوى خاص بمنطقة معينة، أو عرض معلومات الموقع للمستخدمين.

استخراج رمز الكتابة

تُرجع الخاصية script مكون الكتابة من معرف اللغة. وهو الرمز المكون من أربعة أحرف الذي يحدد نظام الكتابة المستخدم لتمثيل اللغة.

const simplifiedChinese = new Intl.Locale("zh-Hans-CN");
console.log(simplifiedChinese.script); // "Hans"

const traditionalChinese = new Intl.Locale("zh-Hant-TW");
console.log(traditionalChinese.script); // "Hant"

const serbianCyrillic = new Intl.Locale("sr-Cyrl-RS");
console.log(serbianCyrillic.script); // "Cyrl"

const serbianLatin = new Intl.Locale("sr-Latn-RS");
console.log(serbianLatin.script); // "Latn"

تتبع رموز الكتابة معيار ISO 15924. وتستخدم أربعة أحرف مع كتابة الحرف الأول بحرف كبير. تشمل الرموز الشائعة Latn للكتابة اللاتينية، وCyrl للكتابة السيريلية، وHans للحروف الصينية المبسطة، وHant للحروف الصينية التقليدية، وArab للكتابة العربية.

تحذف معظم معرفات اللغة رمز الكتابة لأن كل لغة لها نظام كتابة افتراضي. تستخدم الإنجليزية الكتابة اللاتينية افتراضياً، لذا تكتب en بدلاً من en-Latn. وتستخدم الروسية الكتابة السيريلية افتراضياً، لذا تكتب ru بدلاً من ru-Cyrl.

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

عندما لا يحتوي المعرّف المحلي على رمز كتابة صريح، تُرجع الخاصية script القيمة undefined:

const english = new Intl.Locale("en-US");
console.log(english.script); // undefined

عند استخراج رمز الكتابة، يمكنك استخدامه لاختيار الخطوط، أو تحديد عرض النص، أو تصفية المحتوى حسب نظام الكتابة.

فهم متى تكون المكونات غير معرّفة

لا تتضمن جميع معرّفات اللغة المحلية كل المكونات. رمز اللغة مطلوب، لكن المنطقة والكتابة اختيارية.

عندما لا يكون المكون موجوداً في المعرّف، تُرجع الخاصية المقابلة القيمة undefined:

const locale = new Intl.Locale("fr");

console.log(locale.language); // "fr"
console.log(locale.region); // undefined
console.log(locale.script); // undefined

يتيح لك هذا السلوك التحقق مما إذا كانت اللغة المحلية تحدد منطقة أو كتابة قبل استخدام تلك القيم:

const locale = new Intl.Locale("en-US");

if (locale.region) {
  console.log(`Region-specific formatting for ${locale.region}`);
} else {
  console.log("Using default formatting");
}

يمكنك استخدام عامل الدمج الفارغ لتوفير قيم افتراضية:

const locale = new Intl.Locale("es");
const region = locale.region ?? "ES";

console.log(region); // "ES"

عند بناء سلاسل الاحتياطية للغة المحلية، يساعدك التحقق من المكونات غير المعرّفة في إنشاء البدائل:

function buildFallbackChain(identifier) {
  const locale = new Intl.Locale(identifier);
  const fallbacks = [identifier];

  if (locale.region) {
    fallbacks.push(locale.language);
  }

  return fallbacks;
}

console.log(buildFallbackChain("fr-CA")); // ["fr-CA", "fr"]
console.log(buildFallbackChain("fr")); // ["fr"]

ينشئ هذا قائمة بمعرّفات اللغة المحلية مرتبة من الأكثر تحديداً إلى الأكثر عمومية.

حالات الاستخدام العملية لاستخراج المكونات

يحل استخراج مكونات اللغة المحلية العديد من المشكلات الشائعة عند بناء تطبيقات متعددة اللغات.

تجميع اللغات المحلية حسب اللغة

عند عرض قائمة باللغات المتاحة، قم بتجميع اللغات المحلية التي تشترك في نفس رمز اللغة:

const locales = ["en-US", "en-GB", "fr-FR", "fr-CA", "es-ES", "es-MX"];

const grouped = locales.reduce((groups, identifier) => {
  const locale = new Intl.Locale(identifier);
  const language = locale.language;

  if (!groups[language]) {
    groups[language] = [];
  }

  groups[language].push(identifier);
  return groups;
}, {});

console.log(grouped);
// {
//   en: ["en-US", "en-GB"],
//   fr: ["fr-FR", "fr-CA"],
//   es: ["es-ES", "es-MX"]
// }

يساعد هذا التنظيم المستخدمين في العثور على الاختلاف الإقليمي المفضل لديهم ضمن اللغة.

بناء محددات اللغة المحلية

عند بناء واجهة مستخدم لاختيار اللغة، استخرج المكونات لعرض تسميات ذات معنى:

function buildLocaleSelector(identifiers) {
  return identifiers.map(identifier => {
    const locale = new Intl.Locale(identifier);

    const languageNames = new Intl.DisplayNames([identifier], {
      type: "language"
    });

    const regionNames = new Intl.DisplayNames([identifier], {
      type: "region"
    });

    return {
      value: identifier,
      language: languageNames.of(locale.language),
      region: locale.region ? regionNames.of(locale.region) : null
    };
  });
}

const options = buildLocaleSelector(["en-US", "en-GB", "fr-FR"]);
console.log(options);
// [
//   { value: "en-US", language: "English", region: "United States" },
//   { value: "en-GB", language: "English", region: "United Kingdom" },
//   { value: "fr-FR", language: "French", region: "France" }
// ]

يوفر هذا تسميات قابلة للقراءة البشرية لكل خيار لغة.

التصفية حسب المنطقة

عندما تحتاج إلى عرض محتوى خاص بمنطقة معينة، استخرج رمز المنطقة لتصفية اللغات:

function filterByRegion(identifiers, targetRegion) {
  return identifiers.filter(identifier => {
    const locale = new Intl.Locale(identifier);
    return locale.region === targetRegion;
  });
}

const allLocales = ["en-US", "es-US", "en-GB", "fr-FR", "zh-CN"];
const usLocales = filterByRegion(allLocales, "US");

console.log(usLocales); // ["en-US", "es-US"]

يساعدك هذا في اختيار اللغات المناسبة للمستخدمين في بلد معين.

التحقق من توافق النظام الكتابي

عند اختيار الخطوط أو عرض النص، تحقق من النظام الكتابي لضمان التوافق:

function selectFont(identifier) {
  const locale = new Intl.Locale(identifier);
  const script = locale.script;

  if (script === "Hans" || script === "Hant") {
    return "Noto Sans CJK";
  } else if (script === "Arab") {
    return "Noto Sans Arabic";
  } else if (script === "Cyrl") {
    return "Noto Sans";
  } else {
    return "Noto Sans";
  }
}

console.log(selectFont("zh-Hans-CN")); // "Noto Sans CJK"
console.log(selectFont("ar-SA")); // "Noto Sans Arabic"
console.log(selectFont("en-US")); // "Noto Sans"

يضمن هذا عرض النص بشكل صحيح لكل نظام كتابة.

تطبيق اللغة الاحتياطية

عندما لا تكون اللغة المفضلة للمستخدم متاحة، ارجع إلى اللغة الأساسية:

function selectBestLocale(userPreference, supportedLocales) {
  const user = new Intl.Locale(userPreference);

  if (supportedLocales.includes(userPreference)) {
    return userPreference;
  }

  const languageMatch = supportedLocales.find(supported => {
    const locale = new Intl.Locale(supported);
    return locale.language === user.language;
  });

  if (languageMatch) {
    return languageMatch;
  }

  return supportedLocales[0];
}

const supported = ["en-US", "fr-FR", "es-ES"];

console.log(selectBestLocale("en-GB", supported)); // "en-US"
console.log(selectBestLocale("fr-CA", supported)); // "fr-FR"
console.log(selectBestLocale("de-DE", supported)); // "en-US"

يوفر هذا حلاً بديلاً مناسباً عندما لا تكون التطابقات الدقيقة متاحة.