البرمجة متوسط 11 دقيقة

كيفية إضافة دعم متعدد اللغات لتطبيق Laravel

بناء تطبيق Laravel يعمل بلغات متعددة أمر مباشر بمجرد أن تفهم أين يقع كل جزء: بادئات الروابط للتوجيه، ملفات الترجمة لنصوص الواجهة، middleware لضبط اللغة النشطة، وحزمة spatie/laravel-translatable لمحتوى قاعدة البيانات متعدد اللغات.

يغطي هذا الدليل الصورة الكاملة — من هيكل الروابط وصولًا إلى أعمدة Eloquent القابلة للترجمة — ويشمل دعم RTL للعربية وغيرها من اللغات.

هذا الأسلوب يتوسّع ليشمل أي عدد من اللغات دون تغيير وحدات التحكم أو منطق العمل.

الخطوات

  1. 1

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

    أنشئ أو حدّث config/app.php لتضمين اللغات التي تدعمها. إضافة مفتاح supported_locales مخصص يبقي منطق المسارات والـ middleware جافًا — يقرآن من الإعداد بدلًا من ترميز رموز اللغات بشكل مباشر.

    php
    // config/app.php
    'locale' => 'en',
    'fallback_locale' => 'en',
    'supported_locales' => ['en', 'ar'],
  2. 2

    تغليف المسارات ببادئة اللغة

    في routes/web.php، غلّف جميع المسارات العامة في مجموعة تستخدم {locale} كبادئة في الرابط. هذا يعطيك روابط نظيفة صديقة لـ SEO مثل /en/about و/ar/about دون أي تعديل على query string.

    php
    // routes/web.php
    Route::prefix('{locale}')
        ->middleware(['setLocale'])
        ->group(function () {
            Route::get('/', [HomeController::class, 'index'])->name('home');
            Route::get('/about', [AboutController::class, 'index'])->name('about');
            // ... all other public routes
        });
  3. 3

    إنشاء الـ Middleware الخاص بضبط اللغة

    هذا الـ middleware يقرأ مقطع {locale} من الرابط، يتحقق منه مقابل اللغات المدعومة، ويستدعي App::setLocale(). يخزّن اللغة في الجلسة أيضًا حتى يتمكن مبدّل اللغة من قراءة الاختيار الحالي.

    bash
    php artisan make:middleware SetLocale
  4. 4

    كتابة منطق الـ Middleware

    افتح app/Http/Middleware/SetLocale.php وأضف منطق ضبط اللغة. إذا كانت اللغة في الرابط غير مدرجة في قائمتك، ارجع إلى اللغة الافتراضية بدلًا من إرجاع 404.

    php
    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\App;
    
    class SetLocale
    {
        public function handle(Request $request, Closure $next)
        {
            $locale = $request->route('locale');
            $supported = config('app.supported_locales', ['en']);
    
            if (in_array($locale, $supported)) {
                App::setLocale($locale);
                session(['locale' => $locale]);
            } else {
                App::setLocale(config('app.locale'));
            }
    
            return $next($request);
        }
    }
  5. 5

    إنشاء ملفات الترجمة

    يحمّل Laravel نصوص الترجمة من resources/lang/{locale}/. أنشئ ملف PHP واحد لكل مجموعة منطقية — مثلًا common.php لنصوص الواجهة المشتركة. استخدم الدالة المساعدة __('common.save') في أي مكان بالكود أو قوالب Blade.

    php
    // resources/lang/en/common.php
    return [
        'save'       => 'Save',
        'cancel'     => 'Cancel',
        'welcome'    => 'Welcome, :name',
        'page_title' => 'My App',
    ];
    
    // resources/lang/ar/common.php
    return [
        'save'       => 'حفظ',
        'cancel'     => 'إلغاء',
        'welcome'    => 'مرحبًا، :name',
        'page_title' => 'تطبيقي',
    ];
  6. 6

    تثبيت spatie/laravel-translatable لمحتوى قاعدة البيانات

    نصوص الواجهة الثابتة تعيش في ملفات الترجمة، لكن المحتوى المخزّن في قاعدة البيانات — عناوين المدونة، أسماء المنتجات، محتوى الصفحات — يحتاج نهجًا مختلفًا. تخزّن spatie/laravel-translatable كل عمود قابل للترجمة كـ JSON مفتاحه رمز اللغة، وتمنحك واجهة برمجية نظيفة للقراءة والكتابة حسب اللغة.

    bash
    composer require spatie/laravel-translatable
  7. 7

    جعل نموذج Eloquent قابلًا للترجمة

    أضف الـ trait الخاص بـ HasTranslations إلى أي نموذج يحتوي على أعمدة متعددة اللغات، واذكر تلك الأعمدة في مصفوفة $translatable. يخزّن الـ migration هذه الأعمدة كـ json. عند استدعاء $post->title، تُعيد Spatie القيمة المناسبة للغة النشطة تلقائيًا.

    php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use Spatie\Translatable\HasTranslations;
    
    class Post extends Model
    {
        use HasTranslations;
    
        public array $translatable = ['title', 'slug', 'content'];
    }
    
    // Migration
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->json('title');
        $table->json('slug');
        $table->json('content');
        $table->timestamps();
    });
    
    // Writing translations
    $post->setTranslation('title', 'en', 'Hello World');
    $post->setTranslation('title', 'ar', 'مرحبا بالعالم');
    $post->save();
    
    // Querying by a specific locale
    Post::where('slug->en', 'hello-world')->first();
  8. 8

    إضافة مكوّن مبدّل اللغة

    أنشئ مكوّن Blade يولّد روابط تبديل اللغة عن طريق استبدال مقطع اللغة في الرابط الحالي. الدالة route() واسم المسار الحالي يجعلان هذا الأمر نظيفًا.

    html
    {{-- resources/views/components/language-switcher.blade.php --}}
    @foreach(config('app.supported_locales') as $lang)
        @php
            $params = array_merge(request()->route()->parameters(), ['locale' => $lang]);
            $url = route(request()->route()->getName(), $params);
        @endphp
        <a href="{{ $url }}" class="{{ App::getLocale() === $lang ? 'active' : '' }}">
            {{ strtoupper($lang) }}
        </a>
    @endforeach
  9. 9

    التعامل مع تخطيط RTL للعربية

    اللغة العربية وغيرها من لغات RTL تحتاج إلى تغيير خاصية dir في HTML إلى rtl. اضبط هذا في قالب Blade الرئيسي بناءً على اللغة النشطة. يمكنك بعدها استخدام محددات CSS مثل [dir="rtl"] لتطبيق أنماط معكوسة دون نسخ ورقة الأنماط بالكامل.

    html
    {{-- resources/views/layouts/app.blade.php --}}
    @php
        $rtlLocales = ['ar'];
        $isRtl = in_array(App::getLocale(), $rtlLocales);
    @endphp
    
    <html lang="{{ App::getLocale() }}" dir="{{ $isRtl ? 'rtl' : 'ltr' }}">

نصائح ومحاذير

  • استخدم دائمًا الدالة <code>route()</code> مع باراميتر <code>locale</code> لتوليد الروابط — لا تُرمّز <code>/en/</code> أو <code>/ar/</code> مباشرةً في قوالب Blade.
  • لعمود slug تحديدًا، استعلم باستخدام صياغة السهم JSON: <code>where("slug->{$locale}", $value)</code> — Spatie لا تُعيد تعريف <code>where()</code>، لذا تحتاج إلى مسار JSON المباشر.
  • استخدم <code>App::getLocale()</code> في وحدات التحكم لتحميل البيانات الخاصة باللغة؛ لا تعتمد على <code>session('locale')</code> وحده لأن الجلسة قد لا تكون مضبوطة في الطلب الأول.
  • نظّم ملفات الترجمة حسب الميزة لا حسب الصفحة — <code>auth.php</code>، <code>common.php</code>، <code>blog.php</code> — حتى تبقى قابلة للإدارة مع نمو التطبيق.

خاتمة

أصبح تطبيق Laravel يدعم الآن لغات متعددة من البداية إلى النهاية: توجيه قائم على اللغة في الرابط، ونصوص الواجهة عبر ملفات الترجمة، ومحتوى قاعدة البيانات عبر أعمدة Spatie القابلة للترجمة، مع دعم صحيح لـ RTL في العربية. من هنا، يمكنك إضافة إعادة توجيه اللغة عند / بناءً على ترويسة Accept-Language، أو حفظ تفضيل اللغة في ملف تعريف المستخدم.

#Laravel #i18n #Spatie
العودة إلى جميع الأدلة

هل تحتاج مساعدة في مشروعك؟

احجز استشارة مجانية لمدة 30 دقيقة لمناقشة تحدياتك التقنية واستكشاف الحلول معًا.