تخطَّ إلى المحتوى
Uttra

حل مشاكل العربي والاتجاه في Replit

مشاكل العربي في Replit تأتي غالباً من قالب الصفحة الرئيسي الذي يبدأ بالقيمة lang="en" دون اتجاه، ومن CSS مكتوب بخصائص يسار ويمين. أضف dir="rtl" في القالب الأساسي لإطارك، واستخدم margin-inline و padding-inline، وتأكد من الترميز UTF-8، وطبّع النص العربي قبل البحث، وأضف BOM لملفات CSV.

آخر تحديث:

لماذا يحدث هذا

Replit بيئة عامة تشغّل لغات كثيرة، ووكيلها يختار الإطار حسب طلبك: قد يبني لك تطبيق Flask بقوالب Jinja، أو خادم Express مع قوالب EJS، أو واجهة React. هذا التنوع ميزة، لكنه يعني أن مكان إصلاح الاتجاه يختلف من مشروع لآخر، وأن الحل الذي قرأته لمشروع React قد لا يجد له ملفاً مطابقاً عندك.

في كل الحالات تقريباً يوجد قالب أساسي واحد تمر منه كل الصفحات، وهو الذي يحدد اللغة والاتجاه. إذا بقي على lang="en" بلا dir، يرسم المتصفح الصفحة من اليسار إلى اليمين. ثم يأتي ملف CSS مكتوب بخصائص مثل margin-left و float: right و text-align: left، وهذه لا تنقلب مع الاتجاه.

وفي المشاريع التي فيها خادم وقاعدة بيانات تظهر مشاكل عربية لا علاقة لها بالتصميم، ويخلط الناس بينها وبين مشكلة الاتجاه:

  • حروف مشوّهة مثل الرياض بدل «الرياض»: النص قُرئ بترميز غير UTF-8 في مكان ما بين قاعدة البيانات والمتصفح.
  • بحث لا يجد النتائج: العميل كتب «احمد» والاسم محفوظ «أحمد»، أو كتب «مكه» والمحفوظ «مكة».
  • ملف CSV يفتح رموزاً في Excel: الملف سليم لكنه بلا علامة BOM، فيقرؤه Excel بترميز قديم.
  • ترتيب أبجدي غريب: الأسماء التي تبدأ بهمزة تأتي في آخر القائمة لأن الترتيب يتم بالرموز لا باللغة.

كل واحدة من هذه لها إصلاح صغير ومستقل، والخطوات أدناه مرتبة من الواجهة إلى البيانات.

وفي المشاريع التي فيها واجهة منفصلة وخادم منفصل، يكون عندك أحياناً موضعان للاتجاه: صفحة الواجهة نفسها، وأي صفحات يولّدها الخادم مباشرة مثل صفحة تسجيل الدخول أو صفحة الخطأ 404 أو صفحة إعادة تعيين كلمة المرور. هذه الصفحات الثانوية تُنسى كثيراً، فيدخل العميل من رابط في بريده فيرى صفحة إنجليزية الاتجاه وسط موقع عربي. ابحث عن كل ملف فيه وسم <html في المشروع، لا عن الملف الرئيسي فقط.

الحل خطوة بخطوة في Replit

ابدأ بمعرفة القالب الأساسي في مشروعك. افتح شجرة الملفات في Replit وابحث عن أحد هذه الملفات حسب الإطار الذي اختاره الوكيل:

أين يقع القالب الأساسي
الإطارالملف الذي تعدّلهماذا تبحث عنه
Flask / Jinjatemplates/base.html أو layout.html{% block content %}
Djangotemplates/base.html{% block %}
Express / EJSviews/layout.ejs أو partials/head.ejs<%- body %>
React / Viteindex.html في الجذر أو client/<div id="root">
HTML بسيطindex.html<body>
  1. اضبط اللغة والاتجاه والترميز في القالب

    أضف السطرين معاً، فوسم meta charset يجب أن يكون أول ما في head حتى لا يقرأ المتصفح بداية الصفحة بترميز خطأ.

    code
    <!doctype html>
    <html lang="ar" dir="rtl">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>{% block title %}صالون لمسة، جدة{% endblock %}</title>
  2. حوّل CSS إلى خصائص منطقية

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

    code
    /* قبل */
    .card { margin-left: 16px; padding-right: 24px; text-align: left; border-left: 3px solid var(--accent); }
    .badge { position: absolute; right: 8px; }
    
    /* بعد */
    .card { margin-inline-start: 16px; padding-inline-end: 24px; text-align: start; border-inline-start: 3px solid var(--accent); }
    .badge { position: absolute; inset-inline-end: 8px; }
  3. تحقق من ترميز قاعدة البيانات

    قاعدة Postgres المدمجة في Replit تُدار عبر Neon، وترميزها الافتراضي UTF8 عادة، لكن تحقق بأمر واحد. وإن رأيت الحروف المشوّهة فالخلل غالباً في الاتصال أو في ملف أُدخل بترميز آخر، لا في القاعدة.

    code
    SHOW server_encoding;   -- المتوقع: UTF8
    SHOW client_encoding;   -- المتوقع: UTF8
  4. طبّع النص العربي قبل البحث

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

    code
    import re
    
    def normalize_ar(text: str) -> str:
        text = re.sub(r"[\u064B-\u0652\u0640]", "", text)   # التشكيل والتطويل
        text = re.sub(r"[أإآ]", "ا", text)
        text = text.replace("ة", "ه").replace("ى", "ي")
        return text.strip()
    
    # عند الحفظ: customer.name_search = normalize_ar(customer.name)
    # عند البحث: WHERE name_search ILIKE %s  مع  f"%{normalize_ar(q)}%"
  5. صدّر CSV يفتح سليماً في Excel

    أضف علامة BOM في بداية الملف. في Python يكفي اختيار الترميز utf-8-sig، وفي Node أضف المحرف في أول النص.

    code
    # Python
    with open("orders.csv", "w", encoding="utf-8-sig", newline="") as f:
        csv.writer(f).writerows(rows)
    
    // Node / Express
    res.setHeader("Content-Type", "text/csv; charset=utf-8");
    res.send("\uFEFF" + csvText);
  6. رتّب الأسماء ترتيباً عربياً

    في الواجهة استخدم المقارنة حسب اللغة بدل المقارنة بالرموز، فتأتي «أحمد» مع الأسماء التي تبدأ بالألف.

    code
    names.sort((a, b) => a.localeCompare(b, "ar"));

ولتطبيق كل ذلك عبر وكيل Replit، الصق هذا البرومبت كما هو، فهو يذكر الإطار بالاسم حتى لا يبحث الوكيل في ملفات خطأ:

برومبت جاهز لوكيل Replitجرّبه في أوترا

المشروع واجهته عربية للسوق السعودي. أصلح التالي دون تغيير التصميم: 1. في القالب الأساسي لإطار المشروع (base.html أو layout.ejs أو index.html) اجعل <html lang="ar" dir="rtl"> وضع <meta charset="utf-8"> أول وسم في head. 2. حوّل كل خصائص CSS الفيزيائية إلى منطقية: margin-inline-start/end و padding-inline و inset-inline و text-align: start. 3. أضف حقلاً مطبّعاً للبحث في أسماء العملاء يوحّد أ إ آ إلى ا، و ة إلى ه، و ى إلى ي، ويحذف التشكيل، واستخدمه في البحث. 4. اجعل تصدير CSV بترميز UTF-8 مع BOM ليفتح في Excel بالعربي. 5. رتّب القوائم عبر localeCompare مع اللغة ar. اعرض لي قائمة الملفات التي غيّرتها.

إن كان مشروعك في Replit مبنياً على React و Tailwind، فخطوات الأصناف المنطقية وقلب الأيقونات مشروحة بالتفصيل في صفحة RTL في Lovable، وهي تنطبق كما هي.

وهناك مكان ينساه أغلب الناس: رسائل البريد التي يرسلها تطبيقك، مثل تأكيد الحجز أو إشعار الطلب. برامج البريد مثل Gmail و Outlook تتجاهل ملفات CSS الخارجية، فلا يصلها اتجاه موقعك. اجعل الاتجاه والخط داخل الرسالة نفسها:

قالب بريد عربي
<div dir="rtl" style="text-align:right; font-family:Tahoma, Arial, sans-serif; line-height:1.7;">
  <p>أهلاً نورة،</p>
  <p>تم تأكيد موعدك في صالون لمسة يوم الخميس الساعة 5 مساءً.</p>
  <p>رقم الحجز: <span dir="ltr">BK-2207</span></p>
</div>

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

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

الحل الأسرع: أوترا

في أوترا تبني بالعربية من البداية: الواجهة والمحتوى والاتجاه RTL جزء أصيل من التجربة، والمنصة تفهم طلبك بالفصحى أو اللهجة. وهي مثل Replit بيئة مفتوحة تقبل Python أو Node أو PHP أو غيرها، فلا تخسر حرية اختيار الإطار.

قبل: الصفحة بدون dir
اكتب اسمكإرسال ←
بعد: dir="rtl" وخصائص منطقية
اكتب اسمكإرسال ←
عرض حيّ يرسمه متصفحك الآن، وليس لقطة شاشة.

وحين يستخدم مشروعك قاعدة بيانات SQLite أو PostgreSQL أو MySQL، تعرض المنصة جداولها في معاينة «قاعدة البيانات»، فترى بعينك هل حُفظت الأسماء العربية سليمة دون أداة إضافية. وإن أردت نقل مشروع قائم، فاستورده من GitHub عبر خطوات نقل مشروعك من Replit.

أسئلة شائعة

لأن النص المحفوظ بترميز UTF-8 قُرئ في خطوة ما بترميز آخر مثل Latin-1. تأكد أن وسم meta charset موجود وقيمته utf-8، وأن ترويسة الاستجابة تذكر charset=utf-8، وأن الملفات المستوردة إلى القاعدة محفوظة بالترميز نفسه.

صفحات ذات صلة