menu-MENAmenu-MENA
الرئيسيةالأسعارالمدونةتواصل معناابدأ الآن
صفحة قائمة عامة على menu-MENA بالواجهة العربية: اسم المطعم مع علامة "موثّق" صغيرة بلون تيل على يمين الهيدر، وتابات الأقسام وخانة البحث وبطاقات الأصناف كلها مرتبة من اليمين للشمال

ليه ما اعتمدناش على مكتبة بتعكس القائمة عشان تبقى عربي

تصميم القائمة

بقلم فريق menu-MENA

نُشر في 29 أغسطس 2026


الحل اللي من سطر واحد ومش بيحل حاجة

في أغلب المشاريع ثنائية اللغة، حد بيقترح نفس الحل السريع: ضيف مكتبة RTL، اقلب dir لـ rtl، وسلّم الشغل. لواجهة ثابتة إحنا كاتبينها بنفسنا، الحل ده بيشتغل غالباً. لمنتج فيه أصحاب مطاعم بيبنوا تصميمات القائمة بنفسهم، بيرفعوا ملفات PDF بنفسهم، وبيختاروا خطوط بنفسهم، الحل ده بيوقف بسرعة. الجزء الخاص بالتصميم في القوائم العربية الأول اتكلمنا عنه في بوست سابق. البوست ده عن اللي فعلاً اتغير في الكود.

فين المكتبة اللي بتعكس فعلاً موجودة

إحنا فعلاً بنستخدم stylis-plugin-rtl، بس مش في المكان اللي متوقعه. هي متوصلة بـ Emotion cache بتاع موقعنا التسويقي: لما اللغة عربي، createEmotionCache بيبني cache بمفتاح muirtl وجواه prefixer وrtlPlugin في خط أنابيب stylis؛ غير كده بيبني cache عادي بمفتاح mui. ده بيغطي التنقل والفوتر وتخطيط المدونة بتوع الموقع نفسه، مجموعة صغيرة من العناصر إحنا كاتبينها مرة واحدة ومتحكمين فيها بالكامل. إعادة كتابة الـ CSS بعد ما يتبني قرار معقول هناك.

صفحات القائمة العامة اللي المطاعم بتعرضها لزبائنها مش محملة المكتبة دي أبداً.

الاتجاه قيمة، مش تخمين

في جانب المنتج، التخطيط الأساسي بيحط dir على <html> مباشرة من اللغة المحسومة: dir={locale === 'ar' ? 'rtl' : 'ltr'}. اللغة نفسها بتتحسم بترتيب ثابت: باراميتر ?lang= في الرابط الأول، بعدين كوكي locale، بعدين لغة المطعم الافتراضية. الباراميتر مش زينة. الـ CDN بتاعنا بيعمل cache حسب الرابط ومش بيهتم باختلاف الكوكيز، فتبديل لغة عن طريق كوكي بس ممكن يخلي نسخة محفوظة بلغة قديمة تتعرض للزائر اللي بعده. الاتجاه دايماً متربط بنفس اللغة دي في كل حتة تحت، فمصدر الحقيقة واحد بدل ما التخطيط يخمّن من محتوى الصفحة.

اختيار الأدمن في التصميم مش اتجاه قراية الزبون

أداة بناء القوالب بتخلي الأدمن يصمم قالب قائمة مخصص بأي اتجاه، متخزن في template.global.direction. بس ده اختيار وقت التصميم، مش اللي الزبون بياخده فعلاً. كل عنصر رندر بياخد prop اسمه directionOverride، والصفحة العامة الفعلية دايماً بتمرر اتجاه لغة الزبون الفعلي جواه، فقالب اتبنى LTR لسه بيتقرا صح لزبون بيتصفح بالعربي، والعكس صحيح. جوه أداة بناء القوالب نفسها، لو اتجاه القالب النشط اللي اتصمم بيه مش متطابق مع لغة المطعم الافتراضية الحالية، صفحة إعدادات الثيم بتعرض تحذير تعارض اتجاه بدل ما تختار واحد بصمت. الأدمن المفروض يعرف بالتعارض ده، مش يكتشفه من سكرين شوت زبون.

اللي مكتبة العكس مش هتوصله

لما خاصية CSS منطقية (logical property) تعمل المطلوب، بنستخدمها ونوقف. شارة "مختار" على كارت القالب متحطوطة على insetInlineEnd، وده المتصفح بيقلبه لوحده لما direction يتغير من غير أي جافاسكريبت. بس جزء كبير من تخطيط القائمة شغال عن طريق prop اسمه sx بتاع MUI، وstylis-plugin-rtl بيعيد كتابة ورقة الأنماط اللي بيشوفها بس، مش اختصار sx المتولد لكل عنصر لوحده. فرندرر كارت الصنف بيتشيك على isRtl مباشرة: اتجاه الكارت بيبقى row-reverse بدل row لما التخطيط بيحط الصورة جنب النص، textAlign بيتبدل بين right وleft، ودالة محاذاة بتحول left المكتوبة في القالب لـ right (والعكس) تحت RTL وتسيب center زي ما هي، لأن المحتوى في النص مالوش جنب يتقلب. مفيش من ده حاجة واحدة بتحل الموضوع كله. دي مجموعة قرارات صغيرة اتاخدت مرة واحدة في الرندرر، وأي قالب مبني فوقه بيورث القرارات دي مجاناً.

الأجزاء اللي أصلاً ملهاش علاقة بـ CSS

بعض الحاجات مالهاش علاقة بالتخطيط أصلاً. لما خط القالب مش من الخطوط الآمنة الافتراضية، بنحمّله من Google Fonts، ولو الخط ده موجود في قايمتنا للخطوط اللي بتدعم العربي (Cairo، Tajawal، Almarai، Noto Kufi Arabic، وغيرهم)، الطلب بيتضاف له &subset=arabic. أدمن بيختار خط عرض لاتيني شيك لبنائه، المفروض ما يخسرش حروف عربية بصمت لأن محدش طلب مجموعة الحروف دي. الأسعار بتتنسق عن طريق Intl.NumberFormat بلغة ar-EG بالعربي وen-US بالإنجليزي، فتنسيق الأرقام والعملة بيتبع اللغة بدل ما يتقلب يدوي زي خاصية CSS. وفليب بوك الـ PDF بيحسم اتجاه قلب الصفحة بثلاث خطوات: اتجاه متحدد لملف الـ PDF ده وقت الرفع، بعدين خيار اتجاه قلب عام، بعدين رجوع للغة اللي الزبون بيقرا بيها دلوقتي. الفليب بوك بيقلب صفحاته بأنيميشن حقيقي؛ مفيش قاعدة CSS بتقلب ده صح، فلازم يتحدد كبيانات قبل ما العنصر يترندر أصلاً.

اجمع كل ده ومش هيبان زي خاصية تتكتب في صفحة الأسعار. ده السبب إن القائمة العربية على menu-MENA بتشتغل صح لما الزبون يفتحها: مش لأن مكتبة عكست الصفحة، لأن الاتجاه اتعامل معاه كحاجة الكود لازم يعرفها، مش حاجة يخمّنها.

الأسئلة الشائعة

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

بالترتيب ده: باراميتر ?lang= في الرابط الأول، بعدين كوكي اللغة، بعدين لغة المطعم الافتراضية. الباراميتر مش زيادة؛ الـ CDN بتاعنا بيعمل cache حسب الرابط ومش بيفرّق بين اختلافات الكوكيز، فتبديل اللغة عن طريق كوكي بس ممكن يخلي نسخة محفوظة بلغة قديمة تتعرض للزائر اللي بعده.

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

بيوصل للفليب بوك كمان. اتجاه قلب الصفحة بيتحدد بترتيب: اتجاه متحدد لملف الـ PDF ده تحديداً وقت الرفع، بعدين خيار اتجاه القلب العام، بعدين رجوع للغة اللي الزبون بيتصفح بيها دلوقتي. الفليب بوك فيه أنيميشن قلب صفحة فعلي، فده مستحيل يتحل بـ CSS؛ لازم يتحدد كبيانات قبل ما العنصر يترندر أصلاً.

أيوه. الأسعار بتعدي على Intl.NumberFormat بلغة ar-EG بالعربي و en-US بالإنجليزي، فمكان علامة العملة وتنسيق الأرقام بيتبع اللغة تلقائياً بدل ما يتقلب يدوي زي خاصية تخطيط عادية.

ده السلوك الافتراضي للمنتج، متضمن في كل مستوى اشتراك. تجربة 14 يوم مجانية من غير كارت ائتمان، وبعدها 90 جنيه في الشهر أو 1000 جنيه في السنة للفرع الأول، مع خصم 50% على أي فرع إضافي.