
ليه ما اعتمدناش على مكتبة بتعكس القائمة عشان تبقى عربي
بقلم فريق 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 بتشتغل صح لما الزبون يفتحها: مش لأن مكتبة عكست الصفحة، لأن الاتجاه اتعامل معاه كحاجة الكود لازم يعرفها، مش حاجة يخمّنها.