آموزش ساخت سایت چندزبانه با استفاده از قابلیت محلی سازی در لاراول

در این مقاله یاد میگیریم سایت چند زبانه با استفاده از قابلیت محلی سازی (localization) را پیاده‌سازی کنیم. با ما همراه باشید.

قابلیت محلی سازی لاراول روش مناسبی برای بازیابی استرینگ‌ها به زبان‌های مختلف را برای ما فراهم می‌کند. در واقع با استفاده از این قابلیت است که می‌توانیم با کمترین اتلاف وقت، از چند زبان در وب سایت خود پشتیبانی کنیم.

فایل‌ها و استرینگ‌های زبان در مسیر resources/lang ذخیره می‌شوند. اگر می‌خواهید سایت چندزبانه داشته باشید، باید در این دایرکتوری یک ساب دایرکتوری برای هر زبان داشته باشید.

ما یک میدلور ایجاد خواهیم کرد تا زبان را بررسی و تغییر دهد.

 

نصب لاراول

 

دستور زیر را در ترمینال خود تایپ کنید.

 

laravel new localization

or

composer create-project laravel/laravel localization

برای این پروژه نیازی به اتصال لاراول به دیتابیس نداریم، زیرا تنها می‌خواهیم ساختار سایت را که بخش ثابت آن است به چند زبان در دسترس باشند. بنابراین برنامه لاراول را به دیتابیس متصل نمی کنیم.
زبان محلی برنامه ما به صورت پیش فرض انگلیسی یا en است.
زبان پیش فرض از مسیر config >> app.php قابل دسترسی است.

// app.php 

/*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'en',

همانطور که مشاهده می‌کنید زبان پیش فرض روی en ست شده است.

حالا در مسیر resources >> lang، پوشه‌ای با نام en داریم. در این پوشه فایل‌هایی مانند auth.php, pagination.php, passwords.php, validation.php هم وجود دارد.

این فایل‌ها، فایل‌های ترجمه هستند. اجازه دهید فایل auth.php را با هم بررسی کنیم.

<?php

// auth.php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed' => 'These credentials do not match our records.',
    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',

];

این فایل آرایه‌ای که دارای key-value خاصی است را بر می‌گرادند. در این بخش می‌توانید کلیدهای دلخواه خود را وارد کنید، اما مقادیر با توجه به زبان شما متغیر هستند.

نام پوشه روت app.php در این مثال en است. بنابراین ترجمه به زبان انگلیسی است. اگر پوشه روت fa باشد، به معنای ترجمه فارسی است. پوشه app.php هم برای زبان فارسی، چیزی شبیه کدهای زیر خواهد بود.

<?php

// auth.php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed' => 'نام کاربری و یا رمز عبور اشتباه می باشد',
    'throttle' => 'شما تلاش های زیادی برای ورود به سیستم کرده اید . لطفا :seconds صبر نمایید و دوباره تلاش کنید.',

];

توجه

به یاد داشته باشید، شما باید تمامی کلیدهای ترجمه خود را در همه زبان‌های مختلف، یکسان اضافه کنید ولی مقادیر مربوط به زبان‌های خود را تغییر دهید.

در کد بالا ، دو کلید failed و throttle را داشتیم که مقادیر به زبان فارسی ترجمه شده‌اند. بنابراین وقتی کاربر زبان سایت را به فارسی تغییر دهد، این پیغام‌ها نمایش داده می‌شوند. چون در فایل ویو، با کلید فراخوانی می‌کنیم و میدلور با توجه به زبان، اطلاعات درست را نمایش می‌دهد.

ایجاد فایل‌های ترجمه

حالا قصد داریم علاوه بر زبان انگلیسی، چهار زبان دیگر را تعریف کنیم.

  1. فارسی
  2. فرانسوی
  3. اسپانیایی
  4. ژاپنی

در مسیر  resources >> lang یک فایل ایجاد کنید.

پوشه‌های زبان

در هر 4 پوشه  فایلی با نام sentence.php ایجاد کنید و کدهای زیر را در آن قرار دهید.

برای فایل fa>>sentence.php:

<?php

// sentence.php

return [
  'welcome' => 'خوش آمدید دوست عزیز'
];

برای فایل en>>sentence.php:

<?php

// sentence.php

return [
  'welcome' => 'Welcome Friend'
];

 

برای فایل es>>sentence.php:

<?php

// sentence.php

return [
  'welcome' => 'Bienvenido amigo'
];

 

برای فایل fr>>sentence.php:

<?php

// sentence.php

return [
  'welcome' => 'Bienvenue mon ami'
];

 

برای فایل jp>>sentence.php:

<?php

// sentence.php

return [
  'welcome' => 'ようこそ友達'
];

می‌توانید متن‌های متفاوتی قرار دهید. این متن صرفا جهت نمایش و دمو است.

تمام فایل‌های ترجمه را در مسیر درست قرار دادیم. قدم بعدی کار کردن با ویوها است.

ساخت ویو

ابتدای کار پوشه layouts را در مسیر resources >> views بسازید. داخل آن فایل app.blade.php را ساخته و کدهای زیر را در آن قرار دهید.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item dropdown">
                            <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                Language <span class="caret"></span>
                            </a>
                            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                <a class="dropdown-item" href="lang/en"><img src="{{asset('img/us.png')}}" width="30px" height="20x"> English</a>
                                <a class="dropdown-item" href="lang/fr"><img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French</a>
                                <a class="dropdown-item" href="lang/es"><img src="{{asset('img/es.png')}}" width="30px" height="20x"> Spanish</a>
                                <a class="dropdown-item" href="lang/jp"><img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese</a>
                            </div>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>

فایل welcome.blade.php را در مسیر resources >> views باز کنید و کدهای زیر را در آن کپی کنید.

 

ساخت میدلور و روت و کنترلر

 

کد زیر را در routes >> web.php کپی کنید.

Route::get('lang/{locale}', 'HomeController@lang');

متد lang را در HomeController.php تعریف کنید. می‌توانید با استفاده از دستور زیر یک کنترلر ایجاد کنید. 

php artisan make:controller HomeController

کدهای زیر را داخل فایل کپی کنید.

<?php

// HomeController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App;

class HomeController extends Controller
{
    public function lang($locale)
    {
        App::setLocale($locale);
        session()->put('locale', $locale);
        return redirect()->back();
    }
}

این تابع زبان محلی را دیده و در یک session قرار خواهد داد.

با استفاده از دستور زیر یک میدلور بسازید.

php artisan make:middleware Localization

در مسیر app >> Http >> Middleware ساخته خواهد شد.

حالا وقت آن است که فایل Localization.php را باز کرده و آن را طبق کدهای زیر آپدیت کنید.

<?php

// Localization.php

namespace App\Http\Middleware;

use Closure;
use App;

class Localization
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (session()->has('locale')) {
            App::setLocale(session()->get('locale'));
        }
        return $next($request);
    }
}

رجیستر کردن میدلور Localization

میدلور را در مسیر App\Http\Kernel به آرایه $middlewareGroup اضافه کنید.

کدهای شما باید چیزی شبیه به این باشد.

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\Localization::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

در نهایت کدهای زیر را در مسیر resources >> views >> layouts >> app.blade.php قرار دهید.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        @php $locale = session()->get('locale'); @endphp
                        <li class="nav-item dropdown">
                            <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                Language <span class="caret"></span>
                            </a>
                            @switch($locale)
                                @case('fr')
                                <img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French
                                @break
                                @case('es')
                                <img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Spain
                                @break
                                @case('jp')
                                <img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese
                                @break
                                @default
                                <img src="{{asset('img/us.png')}}" width="30px" height="20x"> English
                            @endswitch
                            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                <a class="dropdown-item" href="lang/en"><img src="{{asset('img/us.png')}}" width="30px" height="20x"> English</a>
                                <a class="dropdown-item" href="lang/fr"><img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French</a>
                                <a class="dropdown-item" href="lang/es"><img src="{{asset('img/es.png')}}" width="30px" height="20x"> Spanish</a>
                                <a class="dropdown-item" href="lang/jp"><img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese</a>
                            </div>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>

در کدهای بالا یک منوی کشویی تعریف کرده‌ایم. با این کار بعد از اینکه کاربر زبان را تغییر داد، باز هم زبان‌ها برای او نمایش داده می‌شود و صرفا محدود به زبان انتخاب شده نیست.

حالا کدهای زیر را در مسیر resources >> views >> welcome.blade.php قرار دهید.

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-body">
                <p>{{ trans('sentence.welcome')}}</p>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

در این قسمت از فانکشن trans() استفاده شده است که یک آرگومنت با نام filename.array_key_name را می گیرد.

بخش هیجان انگیز این آموزش، خروجی آن است. چنانچه مراحل را به درست رفته باشید، بعد از وارد شدن در صفحه اصلی سایت منوی کشویی با 4 زبان را مشاهده خواهید کرد.

// app.php 

/*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'en',
رقیه اباذری

رقیه اباذری

تو دانشگاه IT خوندم و اکثر منابع کتاب‌های ترجمه شده بودند و صدالبته مبهم :( مثلا element رو "عنصر" ترجمه می‌کردن و من همیشه می‌رفتم تو شیمی و جدول مندلیف. تو باورژن سعی کردم تا حد ممکن مطالب رو با زبان ساده و قابل درک بنویسم. باشد که کسانی که تازه پا به عرصه برنامه‌نویسی گذاشتن، راغب‌تر بشن و با نظرات و فیدبک‌های شما راه هموارتر بشه:)

دیدگاه‌ها


ثبت دیدگاه