كل مرة يجيلك طلب «عايز الموقع عربي وإنجليزي»، أول حاجة بتيجي في بالك إضافة ترجمة وسعر رخصتها السنوي. بس فيه حالات كتير — منيو مطعم، ووردبريس للمحتوى المؤرخ مثل التدوينات والأخبار والشروحات. تُرتّب زمنيًا وتُنظَّم بالتصنيفات والوسوم وتظهر في الأرشيف وخلاصات RSS، بخلاف الصفحات الثابتة.">صفحة خدمات، كتالوج صغير — المحتوى فيها منظم ومحدود لدرجة إن الإضافة دي بتبقى سلاح أكبر من الهدف بكتير. المطوّر Muhammad Medhat بنى منيو QR لمطعم بلغتين باستخدام حقول مخصصة وقالب خفيف بس، والنتيجة تستاهل نتكلم عنها.
السؤال الحقيقي ليس «كم إضافة؟»
الإضافات (Plugins) هي سبب مرونة ووردبريس أصلاً، وليس عيباً فيه. لكن كل إضافة تضيفها تجرّ معها ملفات CSS و JavaScript وإعدادات وتحديثات ومسائل توافق مع غيرها.
المعيار العملي ليس عدد الإضافات بل ما تفعله كل واحدة منها. إضافة واحدة تحمّل مكتبة كاملة على كل صفحة قد تكون أثقل من خمس إضافات صغيرة لا تعمل إلا في لوحة التحكم.
قبل تثبيت أي إضافة، اسأل نفسك خمسة أسئلة:
- هل هذه الوظيفة أساسية للمشروع فعلاً أم «كويسة لو موجودة»؟
- هل يمكن تنفيذها داخل القالب في Elementor تصميم محفوظ يُعاد استخدامه، مثل رأس الموقع أو التذييل أو صفحة المقالة أو صفحة المنتج. تصممه مرة وتحدد شروط ظهوره، فيُطبَّق على كل…">القالب ببساطة وأمان؟
- هل تقدم الإضافة الجاهزة قيمة حقيقية تفوق كلفة الاعتماد عليها؟
- هل سيكون الحل قابلاً للصيانة بعد سنتين؟
- هل الوظيفة معقدة لدرجة تستدعي نظاماً ناضجاً مجرّباً؟
الدفع، والحجوزات، وإدارة ترجمة معقدة: هذه ميادين الإضافات الجاهزة بلا نقاش. أما شكل عرض قائمة طعام، فهذا شغل القالب (Theme).
بصراحة: «موقع بإضافات أقل» ليس وعداً بموقع أسرع. الاستضافة، وحجم الصور، والتخزين المؤقت (Cache)، وجودة الكود تتحكم في السرعة أكثر بكثير من عدّاد الإضافات في لوحة التحكم.
بنية المشروع: قالب خفيف مفصّل على الحاجة
بدل قالب متعدد الأغراض تُطفئ نصف مميزاته، بُني قالب صغير يحتوي على ما يحتاجه المشروع فقط:
- قالب ووردبريس خفيف مطوّر خصيصاً للمشروع.
- بنية منيو منظمة تُدار عبر الحقول المخصصة (Custom Fields).
- دعم لغتين.
- واجهة متجاوبة (Responsive) مصممة أساساً للهاتف، لأن الزائر يفتح المنيو من كود QR وهو جالس على الطاولة.
- بنية محتوى مرتبطة بمتطلبات المطعم لا أكثر.
هذه هي فكرة «ابنِ موقعك قطعة قطعة» في أبسط صورها: كل قطعة موجودة لأن لها وظيفة، ولا قطعة زائدة تحملها معك في كل تحديث.
إدارة المحتوى بالحقول المخصصة
الأداة المحورية هنا هي Advanced Custom Fields، المعروفة اختصاراً بـ ACF، وهي إضافة تتيح لك إنشاء حقول منظمة تظهر في شاشة تحرير المقالة أو نوع المحتوى المخصص (Custom Post Type).
كل صنف في المنيو له خصائص ثابتة: الاسم، الوصف، السعر، التصنيف، الصورة. بدل إدخال هذه البيانات داخل محرر نصوص حر أو منشئ صفحات، تصير كل خاصية حقلاً مستقلاً.
الفائدة الأهم ليست في التنظيم فحسب، بل في فصل المحتوى عن شكل عرضه. صاحب المطعم يغيّر السعر من خانة واحدة، والقالب هو من يقرر كيف يظهر هذا السعر على الشاشة. لا أحد يكسر التصميم بالخطأ وهو يعدّل سعر طبق.
في JetEngine: نفس البنية تُنفَّذ في حزمة ArabCMS بحقول الميتا (Meta Fields) داخل JetEngine مع نوع محتوى مخصص للأصناف، ثم قالب القائمة (Listing) لعرضها. الفارق أن JetEngine يعطيك العرض والاستعلام في نفس الأداة، بينما مع ACF تكتب قالب العرض بنفسك.
اللغتان بدون إضافة ترجمة
هنا الجزء الأهم للقارئ العربي. بدل إضافة ترجمة كاملة، أُنشئ حقلان لكل معلومة، واحد لكل لغة:
| الحقل | الغرض |
|---|---|
name_en | اسم الصنف بالإنجليزية |
name_ar | اسم الصنف بالعربية |
description_en | الوصف بالإنجليزية |
description_ar | الوصف بالعربية |
ثم يعرض القالب الحقل المناسب حسب اللغة التي اختارها الزائر. هذا الاصطلاح في التسمية — اسم الحقل ثم شرطة سفلية ثم رمز اللغة — هو ما يجعل الكود قابلاً للتعميم بدل كتابة شرط لكل حقل.
الخطوة الأولى: تحديد اللغة النشطة
/**
* Resolve the active language from the query string, then the cookie.
* Defaults to Arabic.
*/
function acms_current_lang() {
$allowed = array( 'ar', 'en' );
$lang = isset( $_GET['lang'] ) ? sanitize_key( wp_unslash( $_GET['lang'] ) ) : '';
if ( in_array( $lang, $allowed, true ) ) {
return $lang;
}
if ( isset( $_COOKIE['acms_lang'] ) && in_array( $_COOKIE['acms_lang'], $allowed, true ) ) {
return $_COOKIE['acms_lang'];
}
return 'ar';
}
الخطوة الثانية: دالة واحدة تقرأ الحقل الصحيح
/**
* Return a bilingual ACF field for the active language,
* falling back to English when the translation is empty.
*/
function acms_bi_field( $name, $post_id = null ) {
$lang = acms_current_lang();
$value = get_field( "{$name}_{$lang}", $post_id );
if ( '' === $value || null === $value ) {
$value = get_field( "{$name}_en", $post_id );
}
return $value;
}
الاحتياط في السطر الأخير مهم عملياً: صاحب المطعم يضيف صنفاً جديداً بالإنجليزية وينسى العربية، فلا تظهر خانة فارغة للزائر.
بعدها يصير استدعاء المحتوى في القالب سطراً واحداً:
echo esc_html( acms_bi_field( 'name' ) );
الخطوة الثالثة: ضبط الاتجاه للعربية
هذه الخطوة تُنسى كثيراً وهي التي تفرّق بين موقع عربي حقيقي وموقع إنجليزي مكتوب بحروف عربية:
add_filter( 'language_attributes', function ( $output ) {
return 'ar' === acms_current_lang()
? 'lang="ar" dir="rtl"'
: 'lang="en" dir="ltr"';
} );
add_filter( 'body_class', function ( $classes ) {
$classes[] = 'acms-lang-' . acms_current_lang();
return $classes;
} );
تنبيه: أسعار المنيو تحديداً تخلط أرقاماً لاتينية بنص عربي، وهذا أكثر موضع ينكسر فيه ترتيب العرض. أضف هذا السطر للحقول المختلطة:
.acms-price,
.acms-item-name {
unicode-bidi: plaintext;
}
وللخطوط، استخدم Cairo أو Tajawal أو IBM Plex Arabic. حمّلها محلياً من مجلد القالب بدل استدعائها من خدمة خارجية، فهذا يوفّر طلب اتصال إضافياً ويحسّن زمن التحميل على شبكات الهاتف في مصر والمنطقة.
متى لا يصلح هذا الأسلوب؟
الصدق هنا أهم من الترويج للطريقة. أسلوب الحقول المنفصلة يناسبك عندما:
- المحتوى منظم ومحدود الأنواع (منيو، خدمات، كتالوج صغير).
- عدد اللغات لغتان.
- التحديثات على المحتوى غير يومية.
ويفشل عندما:
- تحتاج رابطاً دائماً (Permalink) مستقلاً لكل لغة، وخريطة موقع (Sitemap) لكل لغة، ووسوم
hreflang. - عندك مدونة بمئات المقالات وتصنيفات مترجمة.
- فريق تحرير يعمل بسير عمل ترجمة فيه مراجعة واعتماد.
- تحتاج ترجمة نصوص القالب نفسه وليس المحتوى فقط.
في الحالات الأخيرة، إضافة متخصصة مثل Polylang أو WPML أوفر من محاولة إعادة بنائها بيدك. الحكم على المشروع لا على المبدأ.
الأداء والصيانة على أرض الواقع
المنيو يُفتح من الهاتف على بيانات الجوال في الغالب، غالباً داخل مطعم إشارته ضعيفة. لذلك أهم ثلاث نقاط عملية:
- لا تحمّل أي ملف CSS أو JavaScript لا تستخدمه الصفحة الحالية.
- اضغط صور الأطباق وقدّمها بصيغة WebP بأبعاد العرض الفعلية لا بأبعاد الأصل.
- استخدم مكوّنات قالب قابلة لإعادة الاستخدام عبر
get_template_part()بدل تكرار HTML في كل ملف.
وللقارئ في مصر والخليج تحديداً: استضافة قريبة جغرافياً مثل مراكز بيانات فرانكفورت مع شبكة توصيل محتوى (CDN) أمامها تفرق في زمن الاستجابة أكثر مما تفرق إضافة تخزين مؤقت إضافية.
الخلاصة
المشروع لا يثبت أن الإضافات سيئة، بل يثبت أن اختيار الأداة يجب أن يتبع حجم المتطلب. منيو بلغتين وبنية محتوى ثابتة لا يحتاج نظام ترجمة كاملاً، ويحتاج بدلاً منه حقولاً منظمة وقالباً يعرف ماذا يعرض ومتى.
جرّب الطريقة دي في أصغر مشروع عندك الأول — صفحة خدمات بلغتين مثلاً — وشوف الفرق في سرعة الصفحة وفي راحة العميل وهو بيعدّل المحتوى بنفسه.
المصدر الأصلي: Building a Lightweight Bilingual WordPress Website Without Too Many Plugins — https://dev.to/muhammadmedhat/building-a-lightweight-bilingual-wordpress-website-without-too-many-plugins-e6f
اقرأ أيضًا
الأسئلة الشائعة
هل أقدر أعمل موقع عربي-إنجليزي من غير إضافة ترجمة؟
نعم، لو المحتوى محدود ومنظم مثل منيو مطعم أو صفحة خدمات. تنشئ حقلاً مخصصاً لكل لغة وتعرض الحقل المناسب حسب لغة الزائر. أما المواقع الكبيرة بمحتوى متغير وتصنيفات كثيرة فتحتاج إضافة متخصصة.
ما الفرق بين ACF وإضافة ترجمة مثل WPML؟
ACF يمنحك حقولاً منفصلة لكل لغة داخل نفس المقالة، بينما إضافات الترجمة تنشئ نسخة كاملة من كل مقالة وتربطها بالأصل وتتعامل مع الروابط الدائمة وخريطة الموقع لكل لغة. الأول أخف والثاني أشمل.
كم إضافة تعتبر كثيرة في موقع ووردبريس؟
لا يوجد رقم سحري. المهم ما تفعله الإضافة لا عددها: إضافة واحدة ثقيلة تحمّل ملفات على كل صفحة قد تكون أسوأ من خمس إضافات صغيرة. قِس بأدوات الأداء بدلاً من العدّ.
كيف أضمن ظهور المحتوى العربي بشكل صحيح من اليمين لليسار؟
غيّر قيمة dir في وسم html حسب اللغة النشطة، وأضف صنفاً للجسم لتبديل الاتجاه في CSS، واستخدم unicode-bidi: plaintext في الحقول التي تخلط عربي وإنجليزي مثل الأسعار وأسماء الأطباق.
هل الحقول المخصصة تضر بالسيو؟
لا بذاتها، لكن محتوى الحقول لا يُفهرس تلقائياً كما يُفهرس محتوى المقالة. تأكد أنك تطبع الحقول داخل HTML الصفحة فعلاً، وأضف بيانات منظمة للقوائم والأسعار حتى تفهمها محركات البحث.



