PostgreSQL coub express.js freeware git jquery laravel links linux macos mysql node.js php powershell python ubuntu vim virtualbox анекдот блог игры интересно стихи цитаты

Laravel 4: Localization (пример решения задачи многоязыковой поддержки)
July 18, 2014
Само решение принадлежит Barry vd. Heuvel и приведено им на форуме forumsarchive.laravel.io, я только немного дорихтовал детали, довольно неуклюже пока как мне кажется, но работает.

Для понимания кода примера нужно ознакомиться с документацией по Localization (надо прочитать всё, там не много) и Routing (prefixing).
Приведенный ниже код работает так
  • Проверяет первый сегмент uri запроса (http://hostname/ru/one/two/?p=1)на соответствие какому-либо из установленных языков
  • Если первый сегмент uri соответствует какому-либо установленному языку, то устанавливается кука с этим языком на месяц, чтобы в дальнейшем пользователь мог зайти на страницу набрав только имя хоста и тут же перейти на свою языковую версию
  • В случае если первый сегмент не соответствует ниодному из установленных языков ту же проверку пробуем провести с кукой, содержащей выбранный язык
  • Далее добавляем к запрошенной ссылке текущую локаль и насильно редиректим на "правильную" ссылку. Причем локаль берется из текущего состояния приложения, то есть если ничего ни в uri ни в cookie небыло найдено, то локаль будет установлена та, что указана в конфиге приложения app/config/app.php
// set language prefix
$locale = Request::segment(1);
$langs = ['ru', 'en'];
if (in_array($locale, $langs) !== false) {

  \App::setLocale($locale);
  Cookie::queue('language', $locale, 60 * 24 * 30);
} else {

  // if no url param - try to get lang from cookie
  $locale = Cookie::get('language');
  if (in_array($locale, $langs) !== false) {
    \App::setLocale($locale);
  }

  if (!\App::runningInConsole()) {
    // save all uri & force redirect to "correct" link
    $qp = Input::query();
    $qp = (!empty($qp)) ? '?' . http_build_query($qp, null, '&') : '';
    Redirect::to('/' . Lang::getLocale() . '/' . Request::path() . $qp, 301)->send();
    exit();
  }
}

// front part routing
Route::group(['prefix' => $locale], function () {
  Route::get('/', ['as'   => 'main-page', 'uses' => function () {
    return View::make('main');
  }]);

  Route::get('/yey', ['as' => 's-yey', 'uses' => 'HomeController@sayYey']);
  Route::get('/wow', ['as' => 's-wow', 'uses' => 'HomeController@sayWow']);

}); // front part with language prefix
Я уверен что это не самое лучшее решение но оно работает. Далее, интересный вопрос с кнопкой переключения языков, то есть с той самой переключалкой из ссылок вида Ru | En которая собственно переключает текущий язык. Думаю логично хотеть чтобы при таком переключении в текущем урле ничего кроме языкового сегмента не менялось. Предлагаю свой велосипед, основанный на мане по Localization
Создадим языковые файлы для этой цели, под английский и русский языки из примера
// app/lang/en/lang_toggle.php

$segsEn = $segsRu = Request::segments();
$segsRu[0] = 'ru';
$qp = Input::query();
$qp = (!empty($qp)) ? '?' . http_build_query($qp, null, '&') : '';

return [
  'en' => [
    'text' => 'En',
    'href' => '/' . implode('/', $segsEn) . $qp,
  ],
  'ru' => [
    'text' => 'Ru',
    'href' => '/' . implode('/', $segsRu) . $qp
  ],
];
И ещё один
// app/lang/ru/lang_toggle.php

$segsEn = $segsRu = Request::segments();
$segsEn[0] = 'en';
$qp = Input::query();
$qp = (!empty($qp)) ? '?' . http_build_query($qp, null, '&') : '';

return [
  'en' => [
    'text' => 'En',
    'href' => '/' . implode('/', $segsEn) . $qp,
  ],
  'ru' => [
    'text' => 'Ru',
    'href' => '/' . implode('/', $segsRu) . $qp
  ],
];
Практически это копипаста которую я пока не придумал как залечить. Теперь у нас есть роутинг с языковым сегментом и языковые варианты контрола переключения с сохранением всех параметров uri. Осталось сделать шаблон для отображения этого контролла, вот он
{{-- app/views/lang-toggle.blade.php --}}
<div style="float:right; padding:5px;">
  <a href="@lang('lang_toggle.en.href')">@lang('lang_toggle.en.text')</a>
  |
  <a href="@lang('lang_toggle.ru.href')">@lang('lang_toggle.ru.text')</a>
</div>
Теперь осталось только подключить этот контрол где-то в лэйауте
{{-- app/views/layout-main.blade.php --}}
...
@include('lang-toggle')
...
На этом все. Повторюсь что решение наверняка не идеальное, но в масштабах вселенной не должно создавать невероятную нагрузку. В качестве упражнения, можно попробовать отпилить языковой префикс для языка по умолчанию (настройка в app/config/app.php). То есть чтобы для русского по умолчанию роутинг нормально отрабатывал без языкового сегмента в ссылке, редирект по куке при этом должен остаться рабочим.
Если кто-то раздобудет решение красивее - буду благодарен за ссылку. Особо интересует момент генерации ссылок для контрола переключения языков.

Comments

No comments here yet.
You have to login to post a new comment.
aghr