.po مقابل .mo مقابل .pot: شرح ملفات ترجمة WordPress

عندما تفتح مجلد languages في قالب WordPress، ستجد ثلاثة ملفات تبدو متطابقة تقريبًا: twentytwentyfour.pot و twentytwentyfour-de_DE.po و twentytwentyfour-de_DE.mo. نفس القالب، نفس اللغة، ثلاثة امتدادات مختلفة. أي منها تقوم بتحريره؟ أي منها يقوم WordPress بتحميله بالفعل؟ ولماذا يؤدي تحرير الملف الخاطئ إلى اختفاء ترجماتك بصمت؟
إذا سبق لك أن تساءلت عن أي ملف هو الأهم في جدال ملفات po مقابل mo، فأنت لست وحدك. هذه الامتدادات الثلاثة هي العمود الفقري لكل موقع WordPress مترجم، ومع ذلك فإن الفرق بينها يربك المبتدئين والمطورين المخضرمين على حد سواء. حرر الملف الخطأ وسيظل زوارك الألمان يرون المحتوى باللغة الإنجليزية. حرر الملف الصحيح ولكن تخطيت خطوة ولن يتغير شيء أيضًا.
يشرح هذا الدليل بالتفصيل ماهية ملفات .pot و .po و .mo، وكيف ترتبط ببعضها ضمن سير عمل GNU Gettext، ومكان وجودها في WordPress، ولماذا يجب ألا تفتح أبدًا ملف .mo في محرر نصوص. بحلول النهاية، ستعرف أي ملف تتعامل معه وأي ملف تتركه وشأنه.
ما هي ملفات .pot و .po و .mo؟
باختصار: ملف .pot هو القالب الفارغ، وملف .po هو ترجمتك القابلة للتحرير، وملف .mo هو الملف الثنائي المترجم الذي يقرأه WordPress أثناء التشغيل. إنها تشكل سلسلة، ولكل حلقة وظيفة واحدة بالضبط.
تأتي هذه التنسيقات الثلاثة كلها من GNU Gettext، وهو نظام الترجمة الذي تعتمد عليه WordPress و Drupal وآلاف مشاريع PHP و C. يفصل Gettext سلاسل المصدر التي يكتبها المطور عن الترجمات التي يقدمها المترجم، بحيث يمكن لنفس قاعدة التعليمات البرمجية أن تتحدث عشرات اللغات دون لمس سطر واحد من PHP.
فكر في الأمر كبطاقة وصفة. .pot هي البطاقة الفارغة التي تحتوي على خانات المكونات ولكن بدون كميات. .po هي البطاقة المعبأة لطبق معين. .mo هي النسخة المصفحة والقابلة للمسح الآلي التي يستخدمها المطبخ بالفعل أثناء الخدمة. أنت تكتب على البطاقة الورقية؛ لا تكتب أبدًا على البطاقة المصفحة.
ملف .pot: القالب الرئيسي
يحتوي ملف .pot (Portable Object Template) على كل سلسلة نصية قابلة للترجمة في قالب أو إضافة مع ترك الترجمات فارغة. إنها القائمة الرئيسية التي يشحنها المطورون حتى يعرف المترجمون بالضبط ما يحتاج إلى ترجمة. تكون أسطر msgstr فارغة لأنه لم يتم اختيار أي لغة بعد.
#: includes/checkout.php:42
msgid "Add to Cart"
msgstr ""
#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr ""
لاحظ msgstr "" الفارغ. ملف .pot هو قالب، وليس ترجمة. تقوم بنسخه مرة واحدة لكل لغة وتملأ الفراغات. نادرًا ما تقوم بتحرير ملف .pot يدويًا؛ يتم إعادة إنشائه من التعليمات البرمجية المصدر كلما تغيرت السلاسل النصية.
ملف .po: ترجمتك القابلة للتحرير يدويًا
ملف .po (Portable Object) هو نسخة من ملف .pot مع تعبئة أسطر msgstr بلغة واحدة. هذا هو الملف الذي يقوم المترجمون والمطورون بتحريره بالفعل. إنه نص عادي، قابل للقراءة البشرية، ومتوافق مع التحكم في الإصدارات.
#: includes/checkout.php:42
msgid "Add to Cart"
msgstr "In den Warenkorb"
#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr "Ihre Bestellung wurde an %s versandt"
إن msgid هو سلسلة المصدر الإنجليزية الأصلية ويجب ألا تتغير أبدًا. msgstr هي ترجمتك. s% هو عنصر نائب يجب أن يبقى دون تغيير في الترجمة — إسقاطه أو إعادة ترتيبه هو السبب الأكثر شيوعًا لتلف التخطيطات، والذي نغطيه بالتفصيل في كيفية ترجمة ملفات PO دون كسر متغيرات التعليمات البرمجية.
ملف .mo: الملف الثنائي المترجم
ملف .mo (Machine Object) هو النسخة الثنائية المترجمة من ملف .po الخاص بك. لا يستطيع WordPress قراءة ملفات .po بكفاءة أثناء التشغيل، لذلك يقوم بتحميل ملف .mo المترجم مسبقًا بدلاً من ذلك. يؤدي فتح ملف .mo في محرر نصوص إلى إظهار بايتات غير قابلة للقراءة — إنه مخصص للآلات، وليس للبشر.
عندما يستدعي WordPress دالتي load_textdomain() أو load_theme_textdomain()، فإنه يبحث عن ملف .mo، ويحلل جدول التجزئة الثنائي الخاص به، ويستبدل كل msgid بـ msgstr المطابق في نفس اللحظة. يجعل هذا التنسيق الثنائي عمليات البحث سريعة حتى في المواقع التي تحتوي على آلاف السلاسل النصية.
كيف ترتبط الملفات الثلاثة في سير عمل Gettext؟
إنها تشكل مسارًا أحادي الاتجاه: التعليمات البرمجية المصدر تصبح ملف .pot، ويصبح ملف .pot ملف .po لكل لغة، ويتم تجميع كل ملف .po في ملف .mo. تتدفق الترجمات دائمًا في اتجاه واحد.
إليك دورة الحياة الكاملة بالترتيب:
- يقوم المطور بلف السلاسل النصية الموجهة للمستخدم داخل دوال Gettext مثل
__()و_e()داخل مصدر PHP. - تقوم أداة المسح بقراءة المصدر وتوليد قالب
.potالذي يحتوي على كل سلسلة نصية ملفوفة. - يقوم المترجم بنسخ ملف
.potإلى ملف.poخاص باللغة (على سبيل المثالde_DE.po) ويملأ كلmsgstr. - يتم تجميع ملف
.poالنهائي في ملف ثنائي.mo. - يقوم WordPress بتحميل ملف
.moأثناء التشغيل ويعرض الموقع المترجم.
عندما يضيف المطور سلاسل نصية جديدة لاحقًا، يتم إعادة إنشاء ملف .pot، ويتم دمج الإدخالات الجديدة في كل ملف .po موجود (مع الاحتفاظ بالترجمات القديمة)، ويقوم المترجم بملء الفجوات، ويتم إعادة تجميع ملف .po إلى .mo. تتكرر هذه الدورة طوال عمر المشروع.
الخلاصة الحاسمة: أنت تقوم بتحرير ملف .po، ثم تقوم بالتجميع إلى .mo. لا تقوم أبدًا بتحرير ملف .mo مباشرةً، ولا تقوم أبدًا بالترجمة داخل ملف .pot. إذا كنت تريد الصورة الشاملة العميقة، فإن الدليل الشامل لترجمة WordPress يستعرض العملية بأكملها مع الأمثلة.
اتفاقيات التسمية ومكان وجود الملفات
WordPress صارم بشأن أسماء الملفات. إذا أخطأت في التسمية، فسيتم تجاهل ملف .mo المترجم بشكل مثالي، لأن WordPress يبحث عن تطابق تام بناءً على نطاق النص (text domain) و اللغة المحلية (locale).
نمط التسمية لترجمات القوالب والإضافات هو:
# Pattern: textdomain-locale.po / .mo
twentytwentyfour-de_DE.po # German (Germany) translation
twentytwentyfour-de_DE.mo # compiled binary WordPress loads
twentytwentyfour-fr_FR.po # French (France)
twentytwentyfour.pot # template, no locale suffix
يتطابق textdomain مع السلسلة التي تم تمريرها كوسيطة ثانية لدوال Gettext مثل __( 'Add to Cart', 'twentytwentyfour' ). locale هو رمز لغة محلية لـ WordPress مثل de_DE أو fr_FR أو pt_BR. لا يحمل قالب .pot لاحقة لغة محلية لأنه محايد لغويًا.
الموقع لا يقل أهمية عن التسمية. يبحث WordPress في عدد قليل من المسارات المتوقعة:
- يتم شحن ترجمات القوالب في مجلد القالب الخاص
wp-content/themes/your-theme/languages/. - يتم شحن ترجمات الإضافات في
wp-content/plugins/your-plugin/languages/. - تهبط الترجمات من translate.wordpress.org والتجاوزات من المستخدم في الدلائل العامة
wp-content/languages/themes/وwp-content/languages/plugins/، والتي تحظى بالأولوية وتصمد أمام التحديثات.
ضع ملف de_DE.mo مسمى بشكل صحيح في المجلد الصحيح وسيرى الزوار الألمان المحتوى باللغة الألمانية. ضعه في مجلد أعمق من اللازم، أو أخطئ في تهجئة نطاق النص، وسيعود WordPress بهدوء إلى اللغة الإنجليزية دون رسالة خطأ. إذا لم تظهر ترجماتك، فإن عدم تطابق في التسمية أو المسار هو الجاني المعتاد، ويغطي دليل استكشاف الأخطاء وإصلاحها للترجمات المفقودة كل سبب شائع.
لماذا يجب ألا تقوم أبدًا بتحرير ملف .mo مباشرةً
نظرًا لأن ملف .mo هو ملف ثنائي مترجم، فلا توجد طريقة آمنة لتحريره يدويًا — وأي تغيير تجبره سيتم الكتابة فوقه في المرة التالية التي يتم فيها إعادة تجميع ملف .po. ملف .po هو مصدر الحقيقة؛ أما ملف .mo فهو ناتج بناء يمكن التخلص منه.
تفسر هذه القاعدة الواحدة جزءًا كبيرًا من تذاكر الدعم التي تقول "ترجمتي تغيرت ولكن الموقع لم يتم تحديثه". يقوم شخص ما بتعديل سلسلة نصية، ويحفظ ملف .po، وينسى إعادة تجميع ملف .mo. يستمر WordPress في تحميل الملف الثنائي القديم، لذلك لا يظهر النص الجديد أبدًا. الحل دائمًا هو: تحرير .po، إعادة التجميع إلى .mo، ثم إعادة التحميل.
يوجد سبب ثانٍ لأهمية هذه القاعدة: ملفات .mo ليست صديقة للمقارنة (diff-friendly) في التحكم في الإصدارات. نظرًا لأنها ثنائية، فإن تغييرًا بسيطًا في الصياغة ينتج عنه كتلة غير شفافة في سجل Git الخاص بك لا يمكن لأي مراجع قراءتها. الاحتفاظ بملف .po كمصدر الحقيقة المتتبع ومعاملة ملف .mo كناتج مُولَّد يحافظ على إمكانية مراجعة مستودعك وقابلية تدقيق ترجماتك.
القيام بذلك يدويًا عبر عشرات اللغات مرهق وعرضة للأخطاء. هذا هو المكان الذي يوفر فيه سير عمل سحابي وقتًا حقيقيًا. تقوم أدوات مثل SimplePoTranslate بترجمة سلاسل .po الخاصة بك وتعيد ملف ZIP واحدًا يحتوي على .po و .mo المطابقين معًا — تم تجميعهما بالفعل، ومسميان بشكل صحيح، وجاهزان للإسقاط في wp-content/languages/. لا يوجد شيء لتجميعه يدويًا ولا يوجد احتمال لملف .mo قديم.
كما يطبق أيضًا قفل بناء الجملة (Syntax Locking)، الذي يقوم بتجميد كل عنصر نائب مثل %s و %1$s و {name}، بالإضافة إلى علامات HTML، قبل الترجمة. تبقى متغيراتك سليمة، لذلك لا تقوم أبدًا بشحن ملف .mo يكسر التخطيط. ولأنه يعمل بالكامل في السحابة، فلا توجد إضافة إضافية تثقل موقعك — تقوم بتحميل ملف وتنزيل ترجمات مجمعة ومكتملة.
تجميع كل ذلك معًا
بمجرد أن يتضح الفرق بين ملفات po و mo، يتوقف نظام ترجمة WordPress بأكمله عن الشعور بالغموض. .pot هو قالب المطور، .po هي نسخة العمل القابلة للتحرير للمترجم، و .mo هي النسخة الثنائية المجمعة التي يقدمها WordPress بالفعل للزوار. تتدفق الترجمات في اتجاه واحد — من القالب إلى .po إلى .mo — وأنت تقوم بتحرير الملف الأوسط فقط يدويًا.
تذكر القواعد الثلاث التي تمنع تسعين بالمائة من مشاكل الترجمة: لا تترجم أبدًا داخل ملف .pot، أعد تجميع ملف .mo دائمًا بعد تحرير ملف .po، وطابق تسمية textdomain-locale بدقة. اتبع هذه القواعد وستظهر سلاسلك المترجمة في كل مرة.
هل أنت مستعد للتوقف عن عناء تجميع وتسمية ملفات الترجمة يدويًا؟ جرب SimplePoTranslate مجانًا — لا يلزم وجود بطاقة ائتمان. قم بتحميل ملف
.poأو.potالخاص بك واحصل على حزمة.po+.moجاهزة للاستخدام في دقائق ضمن الخطة المجانية.