Локализация приложения Laravel

Ромчик
16

laravelДоброго времени суток. В данной статье мы рассмотрим как создать мультиязычный сайт на Laravel. В качестве исходных данных мы будем использовать примеры из статей «Регистрация, активация и авторизация в Laravel (часть 1)» и «Регистрация, активация и авторизация в Laravel (часть 2)». Рассматривать теорию я не буду, по локализации Laravel вы можете прочитать в официальной документации. А в данной статье мы рассмотрим пример как на практике реализовать мультиязычность в Laravel.

Для упрощения нашей задачи воспользуемся пакетом mcamara/laravel-localization.

Установка пакета mcamara/laravel-localization в Laravel

Открываем файл composer.json и в раздел «require-dev» вставляем строку:


"mcamara/laravel-localization":"1.0.*"

Если у Вас Laravel 5.2.x-5.4.x, то замените версию пакета на 1.2.*

После запускаем команду:

    composer update

После установки открываем файл config/app.php и добавляем провайдера:

    Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class

А также добавляем алиас:

'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class

Отлично установка завершена. Переходим к настройке.

Настройка пакета mcamara/laravel-localization в Laravel

Первое, что нам надо сделать это создать в папке config конфигурационный файл пакета. Для этого воспользуемся командой artisan:

    artisan vendor:publish

После выполнения этой команды в папке config у нас появился файл конфигурации для данного пакета laravellocalization.php. В которм перечисляются все поддерживаемые локали. Не будем усложнять задачу и сделаем поддержку только двух локалей: ru и en. Для этого раскоментируйте строку с русской и английской локалью, а все остальные закоментируйте.

В пакете уже есть middleware, которые обеспечивают правильный переход по ссылкам, т. е. если пользователь переходит по ссылке http://lesson.loc, то пакет исправит ссылку в соответствии с локалью, например для русской локали, ссылка станет http://lesson.loc/ru

Давайте подключим эти middleware. Для этого откроем файл app/Http/Kernel.php и добавим в свойство $routeMiddleware:

    'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
    'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
    'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
    'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class

Ну вот и все. Настройка пакета завершена. Переходим к настройке роутов.

Настройка роутов.

Вот как сейчас выглядит наш файл routes.php

<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
Route::get('auth/activate','Auth\AuthController@activate');

Отредактируем его следующим образом:

<?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It's a breeze. Simply tell Laravel the URIs it should respond to | and give it the controller to call when that URI is requested. | */ Route::group( [ 'prefix' =>; LaravelLocalization::setLocale(),
        'middleware' => [ 'localeSessionRedirect', 'localizationRedirect' ]
    ],
    function()
    {
        Route::get('/', function () {
	    return view('welcome');
	});
	Route::get('auth/login', 'Auth\AuthController@getLogin');
	Route::post('auth/login', 'Auth\AuthController@postLogin');
	Route::get('auth/register', 'Auth\AuthController@getRegister');
	Route::post('auth/register', 'Auth\AuthController@postRegister');
	Route::get('auth/logout', 'Auth\AuthController@getLogout');
	Route::get('auth/activate','Auth\AuthController@activate');
    }
);

Роуты настроены.

Следующим шагом будет создание папки в которой будут содержаться переводы. Более подробно читайте в документации.

Создание переводов.

В папке resources/lang создадим папку ru, а в ней создадим файл auth.php. В этом файле и будет лежать переводы для авторизации:

<?php return [ 'registration' => 'Регистрация',
    'email' => 'Email',
    'password' => 'Пароль',
    'log_in' => 'Войти',
];

Аналогичным образом сделаем и для английской локали в папке resources/lang уже есть папка en с файлом auth.php. Исправим этот файл:

<?php return [ 'registration' => 'Registration',
    'email' => 'Email',
    'password' => 'Password',
    'log_in' => 'Log In',
];

И все. Осталось поправить наш шаблон.

Получение перевода в шаблоне.

Для получения перевода из файла переводов используется функция trans(‘<имя файла>.<ключ>’).

Открываем наш шаблон resources/view/auth login.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Авторизация</title>
    <link href="{{ asset('/css/bootstrap.css') }}" rel="stylesheet">
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%7B%7B%20asset('%2Fjs%2Fjquery.js')%20%7D%7D%22%20type%3D%22text%2Fjavascript%22%20charset%3D%22utf-8%22%20%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%7B%7B%20asset('%2Fjs%2Fbootstrap.js')%20%7D%7D%22%20type%3D%22text%2Fjavascript%22%20charset%3D%22utf-8%22%20%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body>
    
<div class="container">
        
<nav class="navbar" role="navigation">
            
<ul class="nav navbar-nav">
                
<li class="active">
                    <a href="{{ url('auth/register') }}">Регистрация</a>
                </li>

            </ul>

        </nav>

        {{--Ошибки --}}
        @if ($errors->has())
            
<div class="row">
                
<div class="col-md-8 col-md-offset-2">
                    
<div class="alert alert-danger" role="alert">
                        <button class="close" aria-label="Close" data-dismiss="alert" type="button">
                             <span aria-hidden="true">×</span>
                        </button>
                        
<ul>
                            @foreach($errors->all() as $error)
                                
<li> {{{ $error }}}</li>

                            @endforeach
                        </ul>

                   </div>

                </div>

            </div>

        @endif
        {{--Успех --}}
        @if (Session::has('message'))
            
<div class="row">
                
<div class="col-md-8 col-md-offset-2">
                    
<div class="alert alert-success" role="alert">
                        <button class="close" aria-label="Close" data-dismiss="alert" type="button">
                            <span aria-hidden="true">×</span>
                        </button>
                        {{ Session::get('message') }}
                    </div>

                </div>

            </div>

        @endif
        
<form role="form" method="post" action="{{ url('auth/login') }}">
            {!! csrf_field() !!}
            
<div class="form-group">
                 <label for="email">Email</label>
                 <input type="email" class="form-control" id="email" placeholder="Email" name='email'>
            </div>

            
<div class="form-group">
                 <label for="password">Пароль</label>
                 <input type="password" class="form-control" id="password" placeholder="Пароль" name="password">
            </div>

            <button type="submit" class="btn btn-default">Войти</button>
        </form>

    </div>

</body>
</html>

И исправляем его:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Авторизация</title>
    <link href="{{ asset('/css/bootstrap.css') }}" rel="stylesheet">
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%7B%7B%20asset('%2Fjs%2Fjquery.js')%20%7D%7D%22%20type%3D%22text%2Fjavascript%22%20charset%3D%22utf-8%22%20%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%7B%7B%20asset('%2Fjs%2Fbootstrap.js')%20%7D%7D%22%20type%3D%22text%2Fjavascript%22%20charset%3D%22utf-8%22%20%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body>
    
<div class="container">
         
<nav class="navbar" role="navigation">
             
<ul class="nav navbar-nav">
                 
<li class="active">
                      <a href="{{ url('auth/register') }}">{{ trans('auth.registration') }}</a>
                 </li>

             </ul>

         </nav>

        {{--Ошибки --}}
        @if ($errors->has())
            
<div class="row">
                 
<div class="col-md-8 col-md-offset-2">
                      
<div class="alert alert-danger" role="alert">
                          <button class="close" aria-label="Close" data-dismiss="alert" type="button">
                              <span aria-hidden="true">×</span>
                          </button>
                          
<ul>
                              @foreach($errors->all() as $error)
                                  
<li> {{{ $error }}}</li>

                              @endforeach
                          </ul>

 
                      </div>

                  </div>

             </div>

         @endif
        {{--Успех --}}
        @if (Session::has('message'))
            
<div class="row">
                
<div class="col-md-8 col-md-offset-2">
                    
<div class="alert alert-success" role="alert">
                        <button class="close" aria-label="Close" data-dismiss="alert" type="button">
                            <span aria-hidden="true">×</span>
                        </button>
                        {{ Session::get('message') }}
                    </div>

                </div>

            </div>

        @endif
        
<form role="form" method="post" action="{{ url('auth/login') }}">
            {!! csrf_field() !!}
            
<div class="form-group">
                <label for="email">{{ trans('auth.email') }}</label>
                <input type="email" class="form-control" id="email" placeholder="{{ trans('auth.email') }}" name='email'>
            </div>

            
<div class="form-group">
                <label for="password">{{ trans('auth.password') }}</label>
                <input type="password" class="form-control" id="password" placeholder="{{ trans('auth.password') }}" name="password">
            </div>

            <button type="submit" class="btn btn-default">{{ trans('auth.log_in') }}</button>
        </form>

    </div>

</body>
</html>

Проверяем, что получилось. Переходим по ссылке http://lesson.loc/ru/auth/login :
01Теперь перейдем по ссылке http://lesson.loc/en/auth/login :
02Отлично. Все работает.

В следующей статье мы обновим нашу регистрацию и сделаем регистрацию по инвайтам.
Так, что не пропускайте выхода новых статей. Следите в Facebook, в Вконтакте, в Twiter и
в Google+

Понравилась статья? Поделись с друзьями.
  • Add to favorites
  • Добавить ВКонтакте заметку об этой странице
  • Twitter
  • Facebook
  • Мой Мир
  • LiveJournal
  • Одноклассники
  • Блог Я.ру
  • MySpace
  • FriendFeed
  • В закладки Google
  • Google Buzz
  • Яндекс.Закладки
  • Reddit
  • StumbleUpon
  • Technorati
  • del.icio.us
  • БобрДобр
  • LinkedIn
  • Memori.ru
  • Сто закладок
  • Blogger

  • Илья - 13.11.2015 в 15:20

    Спасибо за статью!
    А как сделать так чтобы язык по умолчанию имел ссылку, например site.ua. А другие языки так: site.ua/en

  • Андрей - 03.09.2016 в 21:45

    Для версии Laravel 5.2 подойдёт? Как сделать чтобы локализация ru по умолчанию открывалась на основном домене https://site.com без этой приписки http://site.com/ru/ , но другие локали открывались как у вас?

  • Ромчик - 04.09.2016 в 07:53

    Да, для Laravel 5.2 подойдет, все настраивается в конфиге

    • Андрей - 11.09.2016 в 17:26

      Я так понимаю язык будет храниться в сессии? А возможно ли настроить период жизни сессии, не 120 минут по умолчанию, а навсегда?

  • Андрей - 11.09.2016 в 21:26

    Каким образом можно языковые версии сайта сделать на поддоменах типа:

    https://en.site.com
    https://de.site.com

    и т.д. ?

  • Андрей - 11.09.2016 в 22:04

    Каким образом можно сделать переключение языков, скажем через select? В версии Laravel 5.3 в файле маршрутов прописано так:

    Auth::routes();

  • Владимир - 24.11.2016 в 19:09

    После перезагрузки страницы (перехода на другую и тд), настройки языка сбиваются, посколько мы их не ложим ни в сессию не в кукки, а вот догнать как это сделать не могу. Поможете?

    • Ромчик - 24.11.2016 в 19:22

      Не должны сбиваться, у нас язык в адресе <название сайта>/<локализация>/…

  • Владимир - 24.11.2016 в 19:36

    Но тем не менее, сбиваются. У нас же по умолчанию «ru», и если допустим из example.com/en/ перейти по ссылке типа «Контакты«, то урл становится example.com/ru/contacts.
    Не знаю как это связано, но ни кука ни сессия у меня не ложится, что это может быть?

    • Ромчик - 24.11.2016 в 19:43

      Не, не, неправильно. Вы жестко прописываете ссылку, а надо либо через {{ route(‘<имя роута>‘) }}. Тут же можете посмотреть статью «Laravel: Именованные группы роутов». Или App::getLocale()/<ссылка на нужную страницу>

    • Владимир - 24.11.2016 в 19:59

      Огромное спасибо, привычка из Angular JS, что стэйты уже имеют свои имена))
      Тут же им явно нужно задавать, спасибо еще раз. Кручу дальше, а то с фронта надо расти куда-то)))

    • Ромчик - 24.11.2016 в 20:10

      Не за что. Удачи в освоении Laravel )

    • Владимир - 25.11.2016 в 10:38

      Спасибо!

  • Виктор - 15.11.2017 в 17:46

    Подскажите, может у кого получилось сделать такую задачку:
    Перевести элементы вызываемые из базы в форму селект
    {!! Form::select(‘posts’, $posts, 1,[‘class’ => ‘form-control’]) !!}

    • Ромчик - 15.11.2017 в 20:32

      Перевести элементы в контроллере и передать их уже переведенными.

    • Виктор - 16.11.2017 в 10:02

      Спасибо все работает через цикл внутри контроллера, я думал это не возможно, а на самом деле все норм

  • ©2012-2020 По всем вопросам обращайтесь через форму обратной связиПолитика конфиденциальности

    Яндекс.Метрика