Skip to content

Tutorial 5 Localization ar

James Morris edited this page Jul 29, 2026 · 1 revision

الدرس 5 · التوطين (i18n)

🌎 اللغة: العربيةشاهد كل اللغات الـ33

الهدف: افهم كيف تتحدث LockedIn CLI 33 لغة — وتمرّن على توجيه وكيل لإضافة لغة أخرى. التوطين مهمة وكيل رائعة: آلية بما يكفي للتفويض، لكن لها قيود حقيقية (بوابة اختبار، وقواعد تخطيط، ومراجعة نحوية) تعلّمك أن تراجع.

← السابق: الدرس 4 التوجيه والمراجعة · عودة إلى الرئيسية


ماذا يعني «موطَّن» هنا

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

lockedin --lang ar post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh aura

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

  1. الراية --lang (--lang ar، --lang=fr، -l ja)
  2. متغير البيئة LOCKEDIN_LANG
  3. لغتك المحلية (LC_ALL / LC_MESSAGES / LANG، ثم لغة نظام التشغيل/بيئة التشغيل)
  4. الإنجليزية، كخيار احتياطي

normalizeLang() يستخدم عادة الوسم الفرعي الأساسي للغة المحلية. هذا يعني أن de-DE يختار de، لكن tlh لا يصير tl بالخطأ؛ والاسمان البديلان الحقيقيان fil وtgl يقابلان التاغالوغية (tl) عمدا، والنرويجيان nb وnn يقابلان no، والإندونيسي القديم in يقابل id، والعبري القديم iw يقابل he. رمزان إقليميان يُحفَظان حرفيا بدل طيّهما إلى وسمهما الفرعي الأساسي: pt-BR/pt_BR يختاران الرمز الإقليمي القانوني بينما يبقى pt العام حزمة البرتغالية البرازيلية المتوافقة مع السابق (كلاهما برتغالية برازيلية ويتشاركان المجمّعات/الواجهة نفسها)، وen-SG/en_SG يبقيان السنغليزية (يبقى en العام إنجليزية). الصينية التقليدية لهونغ كونغ استثناء من النوع نفسه: zh-HK، وzh_HK.UTF-8، وzh-Hant-HK تختار zh-HK، بينما zh العام والأوسمة الأصلية تختار الصينية المبسّطة (zh).

التبديل أثناء الطيران — لوحة /language. كان بإمكان الأداة دائما أن تبدأ بلغة أخرى (--lang، LOCKEDIN_LANG)؛ والآن تستطيع أن تبدّل في منتصف الجلسة. اكتب /language (الاسمان البديلان /lang و/languages) لسرد الـ33 لغة كلها بالرمز، كل واحدة بخطها الخاص؛ و/language el يبدّل لبقية الجلسة. النقطة هي مخرج الطوارئ: بعد التبديل يعيد الرسم باللغة الجديدة ثم، باللغة التي غادرتها للتو، يطبع طريق العودة بالضبط — /language en الآن، lockedin --lang en المرة القادمة — حتى لا يتركك الهبوط بالخطأ في 日本語 أو ಕನ್ನಡ عالقا. (بدّل مرتين فتُعرَض عليك أيضا اللغة التي يسمّيها LOCKEDIN_LANG.) --lang وLOCKEDIN_LANG دون تغيير. مثل /a11y، إنها أداة صادقة، لا جزء من السخرية.

الفكرة: حزم اللغة

كل النص القابل للترجمة يقيم في حزم، واحدة لكل لغة، كل واحدة على هذا الشكل:

{ meta: { lang: 'ar', name: 'العربية', dir: 'rtl' },
  pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
  ui:    { buzzwordDensity: 'كثافة الكلمات الطنانة: ', /* تسميات، عناوين */ } }
  • pools هي مصفوفات المحتوى (النكات) التي قابلتها في الفصل 2.
  • ui هي سلاسل الزخرفة النصية: التسميات، والعناوين، والقوالب الصغيرة.

الإنجليزية هي الحزمة المرجعية داخل src/lockedin.js؛ وتقيم وحدات الحزم الـ32 الأخرى في src/content/*.js: ar، bn، bo، de، el، en-SG، es، eu، fa، fi، fr، he، hi، id، is، it، ja، kn، ms، nl، no، pl، pt، pt-BR، ru، sv، tl، tr، uk، ur، zh، وzh-HK (pt-BR يعيد استخدام مجمّعات/واجهة pt لكنه مسجَّل على حدة). كل واحدة مسجَّلة في BUNDLES؛ ويُولَّد SUPPORTED_LANGS من تلك المفاتيح، ويطبع renderHelp() قائمة الرموز المولَّدة تلك. لا حزمة واجهة تضمّن القائمة بالشيفرة.

setLang('fr');       // وجّه اللغة النشطة إلى الحزمة الفرنسية
// L = المجمّعات النشطة، U = واجهة المستخدم النشطة
pick(L.HOOKS)        // افتتاحية فرنسية
U.buzzwordDensity    // "Densité de jargon : "

لأن كل عارض يقرأ L وU (لا سلسلة نصية مضمّنة بالشيفرة أبدا)، فإن setLang وحده يغيّر التجربة كلها. تلك هي الحيلة بأكملها.

شبكة الأمان: تكافؤ المفاتيح

هذا هو الثابت الذي يجعل إضافة لغة آمنة:

كل حزمة يجب أن تكشف مفاتيح pools وui نفسها بالضبط كالإنجليزية.

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

الجزء الصعب: تخطيط الطرفية

اللغات تجهد تخطيط الطرفية بطرق مختلفة:

  • اليابانية، والصينية المبسّطة، والصينية التقليدية لهونغ كونغ تستخدم أحرف شرق آسيا العريضة / كاملة العرض. vw() يعدّها عمودين، وwrap() يكسر بقوة الرموز الطويلة بلا مسافات حتى يبقى نص CJK داخل البطاقات والصناديق.
  • الهندية والكنّادية تستخدمان علامات تشكيل مدمجة غير متباعدة/محيطة (Mn / Me)، مثل الماترات والفيرامات. vw() يعدّها صفر أعمدة حتى لا تضخّم العرض المقيس.
  • box() يلفّ كل سطر متن قبل حشوه، فلا يستطيع لافتة مترجمة طويلة أن تخترق الحدّ بعد.
  • كل حزمة تضبط sentenceEnd وlistSep (مثلا . / ، , / ) حتى تُقرأ الجمل التي يؤلّفها المولّد طبيعيا.

حين تضيف لغة، يجب أن تبقى سلاسل رأس البطاقة (cardSubtitle، cardMeta، cardFooter) ملائمة لـ≤ 60 عمودا مرئيا. العربية والفارسية والعبرية والأردية تضبط meta.dir: 'rtl'. المخرجات لا تحوي عناصر تحكم ثنائية الاتجاه افتراضيا، لأن بعض الطرفيات تعرضها كتسميات محاطة بصناديق. LOCKEDIN_BIDI=on يفعّل صراحة عوازل متوازنة بعد اللفّ للطرفيات المعروف أنها تدعمها، مع الحفاظ على ANSI، وأوامر ASCII، وترتيب النسخ/اللصق المنطقي. مخرجات قارئ الشاشة تزيل تلك العناصر دائما. بلا هذا الاشتراك، قد يكون الترتيب المختلط بين اليمين واليسار أقل تطورا؛ فلا تسبر الدعم ولا تستنتجه أبدا.

الجزء الماكر: النحو حول مدخلات المستخدم الخام

بعض قوالب الواجهة تدسّ جملا خاما من المستخدم عبر عناصر نائبة مثل {cap}. لا تترجمها فتحة بفتحة. يجب أن تبقى الجملة صحيحة نحويا حين يكون العنصر النائب عبارة كتبها المستخدم، لا اسما مرتّبا.

علّة تحذيرية حقيقية: القوالب اليابانية التي تضع مباشرة بعد {cap} قد تبدو خاطئة حين يكون {cap} جملة كاملة. الإصلاح ليس «ترجم بجهد أكبر»؛ بل إعادة هيكلة القالب (مثلا أضف مُصدّرا اسميا أو انقل العنصر النائب) حتى يبقى أي مدخل مستخدم عشوائي ملائما.

✅ جرّبه مع وكيلك — أضف لغة

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

أضف الدنماركية (da). أنشئ src/content/da.js كحزمة { meta, pools, ui } بـالمفاتيح نفسها كالإنجليزية، مترجما كل مدخلة (مجمّعات محتوى بنحو 25 لكل واحد، وكل سلاسل الواجهة). سجّل da في BUNDLES في src/lockedin.js. يجب أن يختارها --lang da ولغة محلية da-*. أبقِ سلاسل رأس البطاقة ضمن حدّ العرض. npm test يجب أن يبقى أخضر، وأضف ثوابت دنماركية + اختبارات اكتشاف تحاكي القائمة الموطّنة الموجودة.

ثم شغّل الحلقة من الفصلين 3–4:

  1. الخطة أولا. «قبل كتابة الشيفرة، أخبرني الملفات التي ستغيّرها وكيف ستحافظ على تكافؤ المفاتيح مع الإنجليزية.»
  2. الاختبارات أولا. «أضف اختبارات فاشلة: اكتشاف da، وتكافؤ المفاتيح لـda، وثابت reflect/connect دنماركي. لا تنشئ الحزمة بعد.»
  3. نفّذ. «الآن أنشئ src/content/da.js بترجمة حزمة موجودة مفتاحا بمفتاح، وسجّلها، واجعل الاختبارات تنجح. pick/shuffle فقط للعشوائية.»
  4. البوابة + المراجعة. npm test، ثم lockedin --lang da post — واقرأ الفرق: هل تُرجم كل مفتاح؟ هل ما زالت حدود البطاقة تصطف؟ هل تنجو القوالب التي فيها {cap} من جمل المستخدم الخام؟

تمارين إحماء أصغر إن كانت لغة كاملة أكثر من اللازم:

  • «أضف TAGLINE واحدا إضافيا إلى الحزم الـ33 كلها، مبقيا الأعداد متساوية.»
  • «تحقق هل cardFooter الكنّادي ≤ 60 عمودا مرئيا واشرح كيف قيست علامات التشكيل المدمجة.»
  • «أرني الاختبار الذي سيفشل إن حذفت مفتاح ui من ja.js

إلى أين تذهب بعد ذلك

  • تصفّح src/content/es.js — لا يزال قالبا ودودا لحزمة جديدة.
  • أعد قراءة docs/HANDOFF.md ← «Adding a language».
  • استمتع بالنكات متعددة اللغات في مرجع الأوامر.

هذا هو الدرس كاملا. تستطيع الآن توجيه وكيل ذكاء اصطناعي لبناء ميزات وتوطينها خلف بوابة اختبار — في 33 لغة وجاهز للمزيد. موافق؟ 👇

📘 LockedIn CLI wiki

Tutorial

Reference


Satire · Sátira · 風刺. Not affiliated with LinkedIn. GPL-3.0-or-later.

Clone this wiki locally