إدارة المحتوى متعدد اللغات في لارافيل

مقدمة

مع توسع الأعمال عالميًا، يصبح دعم اللغات المتعددة أمرًا مهمًا بشكل متزايد. واحدة من التحديات الرئيسية في تنفيذ الدعم المتعدد للغات هي إدارة ترجمة المحتوى الديناميكي، مثل أسماء المنتجات والوصف والمحتوى الذي يتم إنشاؤه من قبل المستخدمين الآخرين. هناك عدة استراتيجيات للتعامل مع ترجمة المحتوى الديناميكي، كل منها له مزايا وعيوبه الخاصة. في هذه المقالة، سنستكشف المنهجيات الأكثر شيوعاً لترجمة المحتوى الديناميكي، بما في ذلك تخزين الترجمات في نفس الجدول، استخدام تنسيق JSON، وتخزين المعلومات المترجمة في جدول منفصل.

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

الإفتراضات

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

المنهجيات و الإستراتيجيات

كما ذكرنا سابقاً، سيناقش هذا المقال ثلاث استراتيجيات مختلفة للتعامل مع مشكلتنا:

  • تخزين الترجمات في نفس الجدول باستخدام أعمدة مختلفة لكل سمة ولكل لغة
  • تخزين الترجمات في نفس الجدول باستخدام عمود واحد لكل سمة باستخدام JSON
  • تخزين السمات التي يمكن ترجمتها في جدول منفصل، والاحتفاظ بالسمات غير الترجمة في الجدول الأصلي
    دعونا نناقشها، واحداً تلو الآخر.

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

في هذه المنهجية، يتم تخزين كل سمة يمكن ترجمتها في عمود منفصل، ويتم تمثيل كل لغة في عمود منفصل لكل سمة.
على سبيل المثال، يمكن أن يكون لديك أعمدة “title_en” و “title_ar” لتخزين اسم المنتج باللغة الإنجليزية واللغة العربية على التوالي.

المزايا

الميزة الرئيسية لهذه الطريقة هي أنها تسمح بالاستعلام والفهرسة الفعالة للبيانات في جدول واحد؛ حيث ستسترد قيمة ذرية من قاعدة البيانات، دون الحاجة إلى إجراء عمليات انضمام (JOIN) أو تحليل أخرى.

العيوب

يمكن لهذه الطريقة أن تؤدي أيضاً إلى عدد كبير من الأعمدة ومخطط أكثر تعقيداً. كما يمكن أن يكون من الصعب الحفاظ على إتساق البيانات عبر اللغات، حيث يمكن أن تتطلب التحديثات للغة واحدة تكرارها يدوياً عبر كل الأعمدة الأخرى للغات الأخرى.
على سبيل المثال، إذا كان لديك (N) سمة يمكن ترجمتها و(M) لغة تريد دعمها، فهذا يعني أنه لكل سمة يتعين عليك (M) أعمدة مختلفة لتمثيل جميع الترجمات الخاصة بها، ويمكن القول بأمان أنه سيكون لديك (M * N) عمودًا لتمثيل الترجمات، لذلك إذا كان لديك 4 سمات قابلة للترجمة و10 لغات لدعمها، فستحتاج إلى 40 عمودًا لتمثيل جميع الترجمات لجميع السمات.
يمكن أن يصبح النمو هنا مشكلة أيضاً، حيث سيتعين عليك كل مرة أن تدعم لغة جديدة تمرير كل الجداول وإضافة الأعمدة الجديدة يدوياً لكل منها.

تخزين الترجمات في نفس الجدول باستخدام عمود واحد لكل سمة باستخدام JSON.

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

على سبيل المثال، يمكن تمثيل ترجمات سمة العنوان باستخدام الكائن JSON التالي:

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

المزايا

  • مرونة البنية: تخزين الترجمات كنص JSON يمكن أن يوفر مرونة أكبر لنموذج بيانات تطبيقك. لا يتعين عليك تحديد مخطط محدد لبيانات الترجمة، مما يجعل من الأسهل إضافة لغات جديدة أو مفاتيح ترجمة جديدة دون تعديل مخطط قاعدة البيانات.
  • سهولة التخزين و الإسترجاع: تخزين الترجمات كنص JSON يتيح لك القدرة على تخزينها واستردادها بسهولة من قاعدة البيانات. يمكنك ببساطة استخدام عمود TEXT أو VARCHAR لتخزين النص JSON، ثم استخدام استعلامات SQL لاسترداد بيانات الترجمة اللازمة.
  • السرعة العالية في إسترجاع الترجمات:  نظرًا لأن جميع الترجمات موجودة في نفس الجدول، فلا حاجة لعمليات الانضمام (JOIN) إلى أي جدول آخر لنفس الغرض.

العيوب

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

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

الحزمة البرمجية

في Laravel، توفر حزمة laravel-translatable التي أنشأتها شركة spatie وظيفة الترجمة لنماذج eloquent models باستخدام هذه الاستراتيجية، يمكنك الاطلاع على الحزمة هنا: https://spatie.be/docs/laravel-translatable/v6/introduction

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

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

المزايا

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

العيوب

  • فصل الترجمات في جدول منفصل يمكن أن يجعل من الصعب إدارة الإصدارات المتعددة للترجمات، مثل الحاجة إلى ترجمات مختلفة لمناطق مختلفة (على سبيل المثال, اللغة الإنكليزية في أمريكا و اللغة الإنكليزية في المملكة المتحدة). ويمكن أن يكون ذلك تحديًا في الإدارة، خاصة عند وجود العديد من الإصدارات المختلفة لنفس الترجمة.
  • فصل الترجمات في جدول منفصل يمكن أن يزيد أيضًا من متطلبات التخزين لقاعدة البيانات، حيث قد يكون هناك حاجة إلى جداول إضافية وفهارس لإدارة الترجمات. ويمكن أن يكون هذا مصدر قلق في التطبيقات التي تحتوي على سعة تخزين محدودة أو تلك التي من المتوقع أن تتوسع بسرعة.

  • فصل الترجمات في جدول منفصل يمكن أن يجعل من الصعب الحفاظ على سلامة الارتباط المرجعي بين الجدول الأصلي وجدول الترجمة. على سبيل المثال، إذا تم حذف سجل من الجدول الأصلي، قد يكون من الضروري أيضًا حذف السجلات المترجمة المقابلة لتجنب عدم تطابق البيانات. ويمكن أن يكون ذلك تحديًا في الإدارة، خاصة في القواعد البيانات الكبيرة التي تحتوي على العديد من العلاقات الرئيسية الخارجية.

الحزمة البرمجية

في Laravel، توفر حزمة laravel-translatable التي قدمتها astrotomic وظيفة الترجمة لنماذج eloquent models عن طريق هذه الاستراتيجية، يمكنك الاطلاع على الحزمة هنا: https://docs.astrotomic.info/laravel-translatable/

الخلاصة

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *