الذكاء الاصطناعي والتكنولوجيا

لماذا تُعطّل ملفات التوطين المترجَمة التطبيقات (وما الذي يجب ألّا يُمَسّ)

سبتمبر 23, 2026

لماذا تُعطّل ملفات التوطين المترجَمة التطبيقات (وما الذي يجب ألّا يُمَسّ)

ملف التوطين شيفرة بداخلها جمل

تبدو ملفات اللغة بصيغ PO وYAML و.properties وRESX وXLIFF وJSON كأنها قوائم من الجمل، لكن القيم وحدها هي النص. المفاتيح معرّفات تبحث عنها الشيفرة؛ والعناصر النائبة خانات تملؤها الشيفرة وقت التشغيل؛ وتسلسلات الهروب والوسوم صياغة يعتمد عليها المحلّل. المترجم الذي يعامل السطر كله كنص سينتج ملفًا يُقرأ بشكل رائع ثم يفشل في التحميل، أو يُحمَّل ثم ينهار في أول مرة تنسّق فيها شاشةٌ رقمًا. وعادةً ما يظهر العطل في لغة واحدة فقط، ما يجعله أصعب أنواع الأخطاء اكتشافًا أثناء المراجعة.

خمسة أشياء يجب أن تنجو من الترجمة دون تغيير

  • المفاتيح وأسماء الموارد — تبحث الشيفرة عن النصوص بمفاتيحها، لذا فالمفتاح المترجَم ليس سوى نص مفقود.
  • العناصر النائبة — %s و%1$d و{0} و{name} ووسائط ICU تملؤها الشيفرة؛ وإعادة تسمية أحدها أو حذفه تُفسد التنسيق أو تُطلق خطأً وقت التشغيل.
  • تسلسلات الهروب وقواعد الترميز — ملف .properties الذي يُقرأ بالطريقة الكلاسيكية Properties.load(InputStream) يُعامَل على أنه Latin-1، وتُكتب الأحرف الأخرى كتسلسلات هروب \uXXXX، لذا قد يتحول النص غير اللاتيني الخام إلى رموز مشوّهة (mojibake).
  • الوسوم داخل النصوص — يجب أن تبقى وسوم HTML والرموز المضمّنة في XLIFF وتنسيق Markdown متوازنة، وإلا فإن النص المعروض يُفسد الصفحة المحيطة به.
  • بنية الملف — المسافات البادئة في YAML والقيم الكتلية والمراسي والأسماء المستعارة وتداخل XML كلها صياغة؛ فإزاحة مسافة بادئة أو ترجمة اسم مرساة تغيّر معنى الملف.

الجمع ليس مفردًا مضافًا إليه حرف "s"

للإنجليزية صيغتا جمع، لذا من المغري الاعتقاد بأن كل اللغات كذلك. يوضح دليل GNU gettext سبب فشل هذا الافتراض: كل لغة تعلن قاعدة Plural-Forms الخاصة بها، والإنجليزية تستخدم nplurals=2، أما الروسية فتحتاج إلى ثلاث صيغ تُختار بحسب آخر أرقام العدد. ملف PO مترجَم إلى الروسية بصيغتين فقط يُصرَّف بنجاح ويعمل ويطبع قواعد نحوية خاطئة لكل عدد ينتهي بـ 2 أو 3 أو 4. التعامل الصحيح مع الجمع يعني إنتاج عدد مدخلات msgstr الذي تتطلبه اللغة الهدف، لا العدد الذي صادف أن كان في اللغة المصدر.

أحيانًا يجب أن تتحرك العناصر النائبة

يختلف ترتيب الكلمات بين اللغات، لذا كثيرًا ما تضطر جملة تحوي قيمتين إلى وضعهما بالترتيب المعاكس. العناصر النائبة الموضعية مثل %1$s و%2$s، أو المسمّاة مثل {count} و{user}، موجودة لهذا الغرض تحديدًا: يمكن للترجمة إعادة ترتيبها، لكن يجب أن يبقى كل منها حاضرًا مرة واحدة بالضبط. أما العناصر النائبة المجهولة مثل %s المجرد فلا يمكن إعادة ترتيبها بأمان، وهي مشكلة يجدر إصلاحها في النصوص المصدر قبل الترجمة لا بعدها.

قواعد الصيغ التي يجدر معرفتها قبل الترجمة

لكل صيغة مواضعها الحرجة. في YAML، تمنح المواصفة الكتلة الحرفية (|) والكتلة المطوية (>) سلوكًا مختلفًا في فواصل الأسطر، وتتيح المراسي (&) والأسماء المستعارة (*) لعقدة أن تعيد استخدام أخرى، لذا يجب أن يمر كلاهما دون مساس. وتغلّف XLIFF 2.1 التنسيق الأصلي في عناصر مضمّنة مثل <ph> و<pc>، ويجب أن تُبقيها الترجمة في مكانها حول الكلمات الصحيحة. وفي .NET، يُبحث عن موارد RESX بالاسم وقت التشغيل وفقًا لثقافة واجهة المستخدم الحالية، لذا فإن عنصر data المُعاد تسميته يرتد بصمت إلى اللغة الافتراضية. أما ملف .properties في Java فيعامل أول = أو : أو مسافة بيضاء غير مهرَّبة على أنه فاصل المفتاح، لذا فإن نقطتين رأسيتين شاردتين في مفتاح مترجَم تقسمانه إلى جزأين.

قائمة مراجعة تكشف معظم الأعطال

  1. عُدّ العناصر النائبة في كل نص مصدر وهدف — يجب أن تتطابق المجموعة المتعددة حتى لو لم يتطابق الترتيب.
  2. قارن المفاتيح لا القيم — أي مفتاح موجود في المصدر ومفقود أو مُعاد تسميته في الهدف هو خطأ.
  3. حمّل الملف المترجَم بالمحلّل الحقيقي (msgfmt، أو محمّل YAML، أو ResXResourceReader) قبل إطلاقه.
  4. تحقق من مدخلات الجمع وفق قاعدة اللغة الهدف، لا وفق اللغة المصدر.
  5. اعرض أطول ترجمة في أضيق عنصر من عناصر الواجهة — فالنص بلغات أخرى غالبًا ما يكون أطول من الإنجليزي.
لماذا ينهار التطبيق في لغة واحدة دون غيرها؟

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

لماذا تحتاج الروسية إلى ثلاثة نصوص للجمع بينما تحتاج الإنجليزية إلى اثنين؟

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

لماذا تتحول الأحرف ذات العلامات الصوتية إلى رموز مشوّهة في ملف .properties في Java؟

لأن الطريقة الكلاسيكية Properties.load(InputStream) تقرأ الملف بترميز Latin-1. يجب كتابة الأحرف الواقعة خارج هذا النطاق كتسلسلات هروب \uXXXX، أو تحميل الملف بقارئ يستخدم الترميز الصحيح.

هل يمكن للترجمة تغيير ترتيب العناصر النائبة؟

نعم، عندما تكون موضعية (%1$s، %2$s) أو مسمّاة ({count}، {user}) — بل كثيرًا ما تكون إعادة الترتيب ضرورية لترتيب طبيعي للكلمات. ومع ذلك يجب أن يظهر كل عنصر نائب مرة واحدة بالضبط. أما العناصر النائبة %s المجردة فلا يمكن إعادة ترتيبها بأمان.

لماذا يجب ألّا تُترجَم المفاتيح أبدًا؟

المفاتيح معرّفات وليست نصًا. تطلب الشيفرة النص بمفتاحه؛ والمفتاح المترجَم يعني فشل البحث، فيعرض التطبيق مفتاحًا خامًا أو يرتد إلى اللغة الافتراضية.

ترجِم القيم، واحتفظ بالشيفرة

ارفع ملف PO أو YAML أو .properties أو RESX واستلمه مع بقاء المفاتيح والعناصر النائبة وتسلسلات الهروب والبنية في أماكنها تمامًا.

ترجم ملف لغة مجانًا
كيفية ترجمة عرض PowerPoint عبر الإنترنتfeatured image

الذكاء الاصطناعي والتكنولوجيا

كيفية ترجمة عرض PowerPoint عبر الإنترنت

التحدي الحقيقي في ترجمة العروض التقديمية عرض PowerPoint أكثر من مجرد نص. كل شريحة هي لوحة مصمَّمة بدقة — مربعات النص مو…

صورة الملف الشخصي لـ Amanda Lee

Amanda Lee