العودة إلى المدونة

Django i18n: الدليل الشامل لأتمتة ترجمة ملفات .po

2026-01-28 8 دقيقة قراءة
Django i18n: الدليل الشامل لأتمتة ترجمة ملفات .po

إذا سبق لك أن أطلقت تطبيق Django بأكثر من لغة واحدة، فأنت تعرف الروتين. تغلّف نصوصك في gettext()، وتشغّل makemessages، وتفتح ملف .po يحتوي على مئات الإدخالات، وتبدأ بالترجمة سطراً بسطر. للغتين وخمسين نصاً، هذا محتمل. لست لغات وخمسمائة نص، هذا يوم عمل كامل لن تستعيده أبداً.

يغطي هذا الدليل خط أنابيب التدويل (i18n) في Django من البداية إلى النهاية، ويشرح أين ينهار، ويوضح كيفية أتمتة الجزء المؤلم باستخدام الترجمة المدعومة بالذكاء الاصطناعي.

سير عمل Django i18n القياسي

نظام i18n المدمج في Django مصمم بشكل جيد. الحلقة الأساسية تبدو هكذا:

الخطوة 1: حدد النصوص للترجمة في كود Python والقوالب:

from django.utils.translation import gettext as _

def dashboard(request):
    welcome = _("Welcome back, %(name)s!") % {"name": request.user.first_name}
    return render(request, "dashboard.html", {"welcome": welcome})
{% load i18n %}
<h1>{% trans "Account Settings" %}</h1>
<p>{% blocktrans %}You have {{ count }} unread messages.{% endblocktrans %}</p>

الخطوة 2: استخرج النصوص إلى ملفات .po:

python manage.py makemessages -l de -l fr -l nl

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

#: myapp/views.py:4
msgid "Welcome back, %(name)s!"
msgstr ""

#: templates/dashboard.html:2
msgid "Account Settings"
msgstr ""

الخطوة 3: ترجم كل msgstr فارغ يدوياً.

الخطوة 4: اجمع ملفات .po المنتهية إلى ملفات .mo ثنائية:

python manage.py compilemessages

الخطوات 1 و2 و4 سريعة. الخطوة 3 هي حيث تنهار العملية.

لماذا لا تتوسع الترجمة اليدوية

يحتوي تطبيق Django نموذجي على ما بين 200 و2,000 نص قابل للترجمة. اضرب ذلك في عدد اللغات المستهدفة، وستجد نفسك أمام التزام زمني كبير.

هذه ليست شكوى نظرية. في موضوع معروف على Django Forum، أفاد مطور بأنه قضى أكثر من 8 ساعات لكل ملف .po في الترجمة اليدوية. ووصف أحد المساهمين الأساسيين في Django قضاء أكثر من 10 ساعات لدمج الترجمات المقدمة من المجتمع في إصدار واحد، معظمها في المراجعة وتصحيح التنسيق وإصلاح العناصر النائبة المعطوبة.

تتفاقم المشاكل مع مرور الوقت:

السبب الجذري هو أن الترجمة تُعامل كحدث لمرة واحدة بدلاً من عملية تدريجية قابلة للتكرار.

أتمتة الترجمة بالذكاء الاصطناعي

الفكرة واضحة: بدلاً من أن يفتح إنسان كل ملف .po ويملأ قيم msgstr، تقرأ أداة الملف، وترسل النصوص غير المترجمة إلى نموذج ذكاء اصطناعي أو واجهة برمجة تطبيقات للترجمة، وتكتب النتائج مرة أخرى، وتحافظ على كل شيء آخر (التعليقات، هيكل الملف، العناصر النائبة، صيغ الجمع).

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

الإعداد خطوة بخطوة

1. ثبّت الحزمة

pip install translatebot-django

أو، إذا كنت تستخدم uv (موصى به):

uv add --dev translatebot-django

تثبيتها كتبعية تطوير مقصود. تحتاج TranslateBot فقط عند إنشاء الترجمات، وليس في وقت التشغيل في الإنتاج.

2. أضف إلى INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    # ...
    "translatebot_django",
]

3. اضبط مزود الذكاء الاصطناعي

# settings.py
import os

TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"

يستخدم TranslateBot LiteLLM في الخلفية، مما يعني أنه يمكنك التبديل إلى أي من أكثر من 100 نموذج بتغيير نص واحد:

المزود قيمة TRANSLATEBOT_MODEL
OpenAI gpt-4o-mini, gpt-4o
Anthropic claude-sonnet-4-5-20250929
Google gemini/gemini-2.5-flash
Azure OpenAI azure/gpt-4o-mini
DeepL استخدم TRANSLATEBOT_PROVIDER = "deepl" بدلاً من ذلك

لـ DeepL، ثبّت الإضافة: pip install translatebot-django[deepl]. يمنحك المستوى المجاني من DeepL 500,000 حرف شهرياً بدون تكلفة، وهو كافٍ لمعظم المشاريع الصغيرة إلى المتوسطة.

4. حدد لغاتك

# settings.py
LANGUAGES = [
    ("en", "English"),
    ("de", "German"),
    ("fr", "French"),
    ("nl", "Dutch"),
    ("ja", "Japanese"),
]

5. شغّل الترجمة

python manage.py translate

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

لترجمة لغة واحدة:

python manage.py translate --target-lang nl

يبدو المخرج هكذا:

Translating to Dutch (nl)...
Found 42 strings to translate
Translating batch 1/2...
Translating batch 2/2...
Successfully translated 42 strings

6. اجمع كالمعتاد

python manage.py compilemessages

سير عملك الكامل الآن هو:

python manage.py makemessages -l de -l fr -l nl -l ja
python manage.py translate
python manage.py compilemessages

ثلاثة أوامر. كل لغة. كل سبرنت.

تدريجي بالتصميم

الميزة الأهم لسير عمل قابل للتكرار هي الترجمة التدريجية. يترجم TranslateBot فقط الإدخالات حيث msgstr فارغ. إذا كان لديك 500 نص و15 جديدة هذا السبرنت، فقط تلك الـ 15 تُرسل إلى واجهة البرمجة.

هذا مهم لأسباب عملية:

  1. التكلفة. تدفع فقط مقابل النصوص الجديدة، وليس الملف بالكامل.
  2. السرعة. ترجمة 15 نصاً تستغرق ثوانٍ، وليس دقائق.
  3. الاستقرار. الترجمات التي راجعتها ووافقت عليها بالفعل لا تُستبدل أبداً (ما لم تمرر --overwrite صراحة).

سلامة العناصر النائبة

يستخدم Django عدة تنسيقات للعناصر النائبة: %(name)s، %s، %d، {0}، {name}، ووسوم HTML مضمّنة مثل <strong> أو <a href="...">. إذا تلف أي منها في الترجمة، ستحصل على أخطاء وقت التشغيل أو ترميز معطوب.

يوجّه TranslateBot نموذج الذكاء الاصطناعي للحفاظ على جميع تنسيقات العناصر النائبة ويتحقق من المخرجات. نص مثل:

Welcome to %(site_name)s! You have <strong>%(count)d</strong> new messages.

يُترجم إلى الهولندية كالتالي:

Welkom bij %(site_name)s! Je hebt <strong>%(count)d</strong> nieuwe berichten.

كل عنصر نائب يبقى سليماً.

التحكم بالجودة باستخدام TRANSLATING.md

تترجم نماذج الذكاء الاصطناعي بشكل أفضل عندما تفهم السياق. يبحث TranslateBot عن ملف TRANSLATING.md في جذر مشروعك ويُدرج محتواه في كل طلب ترجمة.

# Translation Context

## About This Project
A B2B project management tool for construction companies.

## Terminology
- "project" means a construction project, not a software project
- "plan" means a building plan/blueprint, not a subscription plan
- Keep "Gantt chart" as-is in all languages

## Tone
- German: use formal "Sie" form (business context)
- French: use formal "vous" form
- Dutch: use informal "je" form

## Do Not Translate
- Brand name: "BuildFlow"
- Feature names: "SmartSchedule", "CostTracker"

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

معاينة قبل الحفظ

يعرض علم --dry-run بالضبط ما سيُترجم دون إجراء أي استدعاءات لواجهة البرمجة أو تعديل الملفات:

python manage.py translate --target-lang fr --dry-run
Found 15 untranslated entries
Dry run mode: skipping LLM translation

Would translate 'Welcome to our site'
Would translate 'Hello, %(name)s!'
...

Dry run complete: 15 entries would be translated

هذا مفيد قبل عملية ترجمة كبيرة أو عندما يريد عضو جديد في الفريق فهم ما يفعله الأمر قبل الالتزام بتكاليف واجهة البرمجة.

تكامل CI/CD

تقادم الترجمات أمر حتمي بدون فرض. يتضمن TranslateBot أمر إدارة check_translations مصمم لخطوط أنابيب CI:

# .github/workflows/ci.yml
jobs:
  translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v4
        with:
          enable-cache: true
      - run: uv python install
      - run: uv sync --frozen
      - name: Install gettext
        run: sudo apt-get update && sudo apt-get install -y --no-install-recommends gettext
      - name: Check translations
        run: uv run python manage.py check_translations --makemessages

يشغّل علم --makemessages أولاً makemessages -a --no-obsolete، مما يضمن أن ملفات .po تعكس الكود المصدري الحالي قبل الفحص. إذا كان أي إدخال غير مترجم أو ضبابي، يخرج الأمر بكود 1 ويُفشل البناء:

locale/de/LC_MESSAGES/django.po: 2 untranslated, 0 fuzzy
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 1 fuzzy
CommandError: Translation check failed

يصبح سير عمل المطور النموذجي:

  1. إضافة نصوص جديدة قابلة للترجمة في فرع ميزة.
  2. يفشل CI لأن تلك النصوص غير مترجمة.
  3. تشغيل python manage.py translate محلياً.
  4. حفظ ملفات .po المحدّثة.
  5. ينجح CI.

الترجمات لا تخرج عن التزامن بصمت أبداً.

ترجمة محتوى قاعدة البيانات

إذا كان تطبيقك يخزن محتوى قابلاً للترجمة في قاعدة البيانات (أسماء المنتجات، عناوين المقالات، تسميات الفئات)، فإن TranslateBot يتكامل أيضاً مع django-modeltranslation:

pip install translatebot-django[modeltranslation]
# Translate all registered model fields
python manage.py translate --target-lang de --models

# Translate specific models only
python manage.py translate --target-lang de --models Product Category

نفس المنطق التدريجي ينطبق: فقط الحقول التي تكون فيها قيمة اللغة المستهدفة فارغة تُترجم.

مقارنة التكاليف

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

النهج التكلفة المقدرة استثمار الوقت
يدوي (وقت المطور) $0 من الجيب، 20-40+ ساعة مرتفع جداً
خدمة ترجمة احترافية $500-2,000+ منخفض (لكن بطيء التسليم)
منصة توطين SaaS $50-200/شهر متوسط
TranslateBot + GPT-4o-mini ~$0.05 (مرة واحدة) دقائق
TranslateBot + DeepL Free $0 (حتى 500 ألف حرف/شهر) دقائق
TranslateBot + Claude/GPT-4o ~$0.30 (مرة واحدة) دقائق

تتغير الأرقام حسب عدد النصوص واللغات المستهدفة، لكن الفرق في رتبة الحجم ثابت. للصيانة المستمرة (ترجمة 20-50 نصاً جديداً يُضاف كل سبرنت)، تكلفة الذكاء الاصطناعي تكاد تكون صفراً.

أفضل الممارسات

ابدأ بـ --dry-run. قبل أول عملية ترجمة حقيقية، استعرض ما سيحدث. هذا يبني الثقة ويكشف مشاكل الإعداد مبكراً.

احفظ ملفات .po قبل الترجمة. إذا حدث خطأ ما، git checkout يعيدك إلى حالة نظيفة فوراً.

اكتب TRANSLATING.md من اليوم الأول. حتى ملف مختصر يحتوي على وصف مشروعك وبعض قواعد المصطلحات يحسّن جودة الترجمة بشكل ملموس.

أضف check_translations إلى CI. هذه الخطوة الواحدة تمنع أكثر أنماط فشل i18n شيوعاً: النصوص التي تم تحديدها للترجمة لكن لم تُترجم فعلياً أبداً.

استخدم gpt-4o-mini أو DeepL لكفاءة التكلفة. احتفظ بالنماذج المتميزة مثل GPT-4o أو Claude للمشاريع التي تهم فيها الدقة، مثل النصوص التسويقية والنصوص القانونية والمصطلحات المتخصصة.

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

من ساعات إلى ثوانٍ

إطار عمل i18n في Django ممتاز في استخراج وتجميع الترجمات. الفجوة كانت دائماً في خطوة الترجمة نفسها، العمل الممل والمعرض للأخطاء في ملء مئات قيم msgstr عبر لغات متعددة.

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

ملفات .po تتوقف عن كونها عبئاً وتصبح مجرد جزء آخر من عملية البناء.

pip install translatebot-django

ابدأ في translatebot.dev.

توقف عن تحرير ملفات .po يدويًا

يُؤتمت TranslateBot ترجمات Django بالذكاء الاصطناعي. أمر واحد، جميع لغاتك، بتكلفة زهيدة لكل ترجمة.