10 лучших пакетов Laravel для переводов и мультиязычности

В Laravel локализация очень проста — разместите переводы в папке resources/lang, но их неудобно редактировать, поэтому существует множество пакетов, которые помогают сделать это более эффективно. Давайте рассмотрим самые популярные из них.

Разделим на три группы:

  • Визуальные менеджеры resources/lang
  • Пакеты для мультиязычных моделей
  • Другие невизуальные пакеты для перевода

Первое — как работают переводы в Laravel

Начнем с основ — как вы можете использовать переводы без пакетов. Четыре важных вещи:

1. Языковые папки

Вы создаете свои языковые папки в resources/lang — например, resources/lang/en и resources/lang/de.

2. Языковые файлы

В каждой из этих папок вы создаете файл или файлы, в которых храните массивы переводов как ключ-значение. Один и тот же файл в разных языковых папках должен иметь одинаковое название.

Пример — resources/lang/en/words.php:

return [
    'page_title' => 'QuickAdmin page',
    'page_description' => 'Best page in the world'
];

Пример — resources/lang/de/words.php:

return [
    'page_title' => 'QuickAdmin Seite',
    'footer'     => 'Beste Seite der Welt'
];

3. Вы определяете текущий активный язык, иначе называемый «locale»

Задается одно из имен ваших папок — в данном случае «en» или «de». В config/app.php есть дефолтная настройка:

'locale' => 'en',

Но вы можете переопределить её в любом месте своего кода:

App::setLocale($locale);

Кроме того, вы можете задать locale в соответствии с маршрутами, например так:

Route::get('welcome/{locale}', function ($locale) {
    App::setLocale($locale);
});

4. Использование переводов в контроллерах или шаблонах

Чтобы получить реальное слово из файла перевода или назначить его какой-либо переменной, вы должны вызвать функцию trans():

trans('words.page_title');

В зависимости от установленной локали система вернет «QuickAdmin page» или «QuickAdmin Seite». Параметр функции trans() — строка, состоящая из двух частей — имени файла, затем символа точки (.) и ключа массива, который вы хотите использовать. В нашем случае   — words и page_title.

Вы также можете сохранить переводы в другом формате — в JSON файлах c доступом через функцию с подчеркиванием __('Login'). Подробнее об локализации смотрите в официальной документации Laravel.

Как мы можем сделать всё это более удобным? Давайте перейдем к пакетам.

Все описанные пакеты активно поддерживаются и обновлялись по крайней мере один раз за последние несколько месяцев. Для каждого из пакетов я укажу адрес, автора и дату первого релиза. Я думаю это будет полезно, посмотреть на популярность пакета и качество его поддержки.

Группа 1. Визуальные менеджеры resources/lang

1. barryvdh/laravel-translation-manager

Адрес: https://github.com/barryvdh/laravel-translation-manager
Автор: Barry vd. Heuvel
Первый релиз: Июнь 2014

Это один из старейших менеджеров с графическим интерфейсом для перевода. По сути, вы получаете с этим пакетом панель администратора, где вы можете визуально редактировать свои переводы (временно сохраненные в базе данных), а затем синхронизировать их с файлами Laravel.

Типичный рабочий процесс:

  • Импортировать переводы: прочитать все файлы переводов и сохранить их в базе данных.
  • Найти все переводы в исходниках php/twig
  • По желанию: посмотреть отсутствующий перевод через специальный Переводчик
  • Перевести все ключи через веб-интерфейс
  • Экспорт: записывать все переводы обратно в файлы переводов.

Вот как это выглядит визуально:

Как использовать переводы в Ларавел

Вы можете перейти к переводу через адрес /translations, который по умолчанию не защищен паролем. Впрочем вы можете это легко сделать сами. Или, воспользоваться artisan командами:

php artisan translations:import

Команда import выполнит поиск по lang-файлам и загрузит все строки в базу данных, где вы сможете легко ими управлять.

php artisan translations:export [group]

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

Этот подход довольно удобен, и он решает довольно большую проблему — предоставление клиентам удобного способа редактировать переводы без какой-либо помощи разработчика , за исключением экспорта его обратно в приложение.

Тем не менее, я был бы осторожен с автоматическим импортом/экспортом и делал бы резервную копию файлов перед любой перезаписью, как и советует сам автор.

2. joedixon/laravel-translation

Адрес: https://github.com/joedixon/laravel-translation
Автор: Joe Dixon
Первый релиз: Сентябрь 2018

Это относительно новый пакет. Он предоставляет интерфейс для добавления новых языков и обновления переводов. Также есть artisan команды для управления вашими переводами и сканирования вашего приложения на наличие пропущенных переводов.

После установки вам просто нужно перейти по адресу /languages (который настраивается и защищен мидлваром), и вы увидите потрясающую админ-панель для перевода, работающую на Laravel + Vue.js:

Как использовать переводы в Ларавел

Пакет может хранить переводы в файлах или в базе данных.

Группа 2. Пакеты для мультиязычных моделей

3. spatie/laravel-translatable

Адрес: https://github.com/spatie/laravel-translatable
Автор: Spatie
Первый релиз: Апрель 2016

Один из самых популярных пакетов. Его автор Freek написал о нём статью «Making Eloquent models translatable».

Этот пакет содержит трейт для того, чтобы делать модели Eloquent переводимыми. Переводы хранятся как json. Дополнительная таблицы, для их хранения, не нужна.

После установки, всё, что вам нужно сделать в вашей модели:

use Spatie\Translatable\HasTranslations;

class NewsItem extends Model
{
    use HasTranslations;
    
    public $translatable = ['name'];
}

А вот как работать с переводами:

$newsItem = new NewsItem; // Это модель Eloquent
$newsItem
   ->setTranslation('name', 'en', 'Name in English')
   ->setTranslation('name', 'nl', 'Naam in het Nederlands')
   ->save();
   
$newsItem->name; // Вернет "Name in English", учитывая, что текущая локаль приложения - 'en'
$newsItem->getTranslation('name', 'nl'); // вернет 'Naam in het Nederlands'

app()->setLocale('nl');

$newsItem->name; // вернет 'Naam in het Nederlands'

4. Astrotomic/laravel-translatable (бывший dimsav/laravel-translatable)

Адрес: https://github.com/Astrotomic/laravel-translatable
Авторы: Tom Witkowski | Dimitrios Savvopoulos
Первый релиз: Февраль 2014

Если нам нужны переводимые модели, например мультиязычный каталог продуктов или блог, то обратите внимание на этот пакет. Важно, что он сменил владельца летом 2019 года. И впечатляет цифра — более 1 миллиона загрузок.

По сути, этот пакет работает так:

  • Для каждой модели вы создаете дополнительную таблицу в базе данных с именем [model]_translations и модель [Model]Translation
  • Ваша основная модель должна использовать trait пакета и иметь свойство $translationAttributes.
  • Тогда вы можете получить перевод таким образом:
$greece = Country::where('code', 'gr')->first();
echo $greece->translate('en')->name; // Greece

Также вы заполнить переводы так:

$greece->translate('en')->name = 'abc';
$greece->save();

Теперь, если вы хотите сделать что-то особенное, например, поиск конкретной строки на определенном языке или упорядочить по переводу, то вам нужно написать Eloquent запрос, например, такой:

Country::join('country_translations as t', 't.country_id', '=', 'countries.id')
    ->where('locale', 'en')
    ->groupBy('countries.id')
    ->orderBy('t.name', 'desc')
    ->with('translations')
    ->get();

Доступны и другие методы, такие translateOrDefault(), hasTranslation(), скоуп (scope) translateIn() и т.д. Если честно, этот пакет заслуживает отдельного обзора, поэтому мы оставим вам возможность прочесть его readme файл.

В общем, я не удивлен, что этот пакет настолько популярен. О нём даже урок в официальном блоге Laravel и два дополнительных пакета, созданных сообществом:

Группа 3. Другие невизуальные пакеты для перевода

5. mcamara/laravel-localization

Адрес: https://github.com/mcamara/laravel-localization
Автор: Marc Camara
Первый релиз: Январь 2014

Один из самых популярных пакетов списка. По сути, он заботится о многоязычной маршрутизации, адресах и мидлварах.

Вот как должен выглядеть ваш файл routes/web.php:

Route::group(['prefix' => LaravelLocalization::setLocale()], function()
{
    /**  ДОБАВЬТЕ ВСЕ ЛОКАЛИЗОВАННЫЕ МАРШРУТЫ ВНУТРЬ ЭТОЙ ГРУППЫ **/
    Route::get('/', function()
    {
        return View::make('hello');
    });

    Route::get('test',function(){
        return View::make('test');
    });
});

/**  ДРУГИЕ СТРАНИЦЫ, КОТОРЫЕ НЕ НУЖНО ЛОКАЛИЗОВЫВАТЬ **/

Как только эта группа маршрутов будет добавлена в файл маршрутов, пользователь сможет получить доступ ко всем локалям, заданным в SupportLocales в конфигурации.

Также вы можете использовать Мидлвар для перенаправления всех «нелокализованных» маршрутов на соответствующие «локализованные»:

    Route::group(
    [
        'prefix' => LaravelLocalization::setLocale(),
        'middleware' => [ 'localeSessionRedirect', 'localizationRedirect' ]
    ],
// ...

Самая классная фишка пакета, на мой взгляд, это Translated Routes — например, вы хотите иметь адрес /en/article/5 для английского языка и /de/artikel/5 для немецкого. Я имею в виду, здесь же разные семантические адреса. Но с этим пакетом это возможно!

Route::get(LaravelLocalization::transRoute('routes.view'),function($id){
      return View::make('view',['id'=>$id]);
});

Наконец, здесь имееется большой набор хелперов и функций, таких как getLocalizedURL(), getURLFromRouteNameTranslated() и других. Вы можете вызывать их прямо из шаблонов для формирования правильных ссылок или перенаправления на нужную страницу.

Это действительно хороший пакет, не удивительно, что он так популярен.

6. spatie/laravel-translation-loader

Адрес: https://github.com/spatie/laravel-translation-loader/
Автор: Spatie
Первый релиз: Октябрь 2016

Для этого пакета есть небольшой урок, написанный его автором в своём популярном блоге, но я кратко перескажу вам его.

По сути, всё, что делает пакет, — храненит переводы в базе данных и использует модель LanguageLine для управления ими.

Поэтому, если вы хотите сохранить все содержимое ваших папок resources/lang в базе данных, то вы должны сделать это построчно, например:

use Spatie\TranslationLoader\LanguageLine;

LanguageLine::create([
   'group' => 'validation',
   'key' => 'required',
   'text' => ['en' => 'This is a required field', 'nl' => 'Dit is een verplicht veld'],
]);

И, каждый раз, когда вы вызываете trans('validation.required'); — пакет проверяет, есть ли такое значение в базе данных, если нет — то, как обычно, загружает перевод из файла resources/lang/[locale]/validation.php.

Также пакет позволяет создавать собственные методы хранения и расширять функциональность.

7. Waavi/translation

Адрес: https://github.com/Waavi/translation
Автор: Waavi web development studio
Первый релиз: Ноябрь 2013

Этот пакет делает довольно много — у него целый набор функций. Если честно, то прочесть документацию и понять все сразу это сложно. Но давайте попытаемся разобраться.

Источник переводов

Пакет позволяет загружать перевод из обычных файлов локализации Laravel (/resources/lang), из базы данных, из кэша или смеси всего упомянутого. Вы можете настроить желаемый режим в файле конфигурации translationator.php и/или в переменной среды TRANSLATION_SOURCE.

Если вы выберете режим базы данных, то вам придется запустить миграцию и выполнить команду php artisan translationator:load для загрузки переводов в базу данных.

Кроме того, он позволяет хранить переводы в кеше и загружать их оттуда — для этого вы должны использовать такие константы, как TRANSLATION_CACHE_ENABLED, TRANSLATION_CACHE_TIMEOUT и TRANSLATION_CACHE_SUFFIX.

Репозиторий переводов

Пакет имеет собственный репозиторий \Waavi\Translation\Repositories\LanguageRepository для управления переводами.

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

Модельный атрибут перевода

Этот пакет также подходит для перевода моделей — вам просто нужно добавить свойство массива $transurableAttributes в вашу модель, а в миграции добавить поля с суффиксом _translation.  Хотя, если честно, я не понимаю, как пакет хранит значения разных языков в одной таблице базы данных, но, думаю, если вы покопаетесь, то узнаете.

Локализация адресов

Также вы можете использовать Waavi\Translation\Middleware\TranslationMiddleware, чтобы убедиться, что все ваши URL-адреса правильно локализованы. TranslationMiddleware будет перенаправлять только те GET-запросы, в которых нет локали.

Довольно много функционала в одном пакете, согласитесь?

8. nikaia/translation-sheet

Адрес: https://github.com/nikaia/translation-sheet
Автор: Nassif Bourguig
Первый релиз: Сентябрь 2016

Пакет с отличной идеей — новым подходом к управлению переводами. Пакет использует… Google Sheets! По сути, разработчики экспортируют все константы в Google Sheets, затем переводчики/клиенты делают свою работу, потом разработчики импортируют слова обратно в систему. Удобно!

Рабочий процесс выглядит так:

  • Вы создаете приложение Google при помощи консоли разработчика, создаете Google Sheet и указываете эти учетные данные и идентификатор в конфигурации.
  • Запускаете artisan-команды: translation_sheet:setup + translation_sheet:prepare + translation_sheet:push. Это опубликует переводы в Google Sheet
  • Команда translation_sheet:lock блокирует Sheet от дальнейших изменений
  • Команда translation_sheet:pull импортирует переводы обратно в Laravel

Есть еще несколько вспомогательных artisan-команд, но в целом все довольно просто.

9. zerospam/laravel-gettext (ex. xinax/laravel-gettext)

Адрес: https://github.com/zerospam/laravel-gettext
Автор: ZEROSPAM Security Inc. | Nicols Daniel Palumbo
Первый релиз: Октябрь 2014

Этот пакет предназначен для работы с GNU gettext и Poedit.

Первое, что вы делаете после установки этого пакета — настраиваете поддерживаемые локали в файле конфигурации и запускаете команду php artisan gettext:create, которая генерирует каталоги и файлы перевода в resources/lang/i18n.

Теперь вы можете использовать переводы вот так:

echo __('Translated string'); // Напоминает WordPress, не так ли?

Пример из Blade шаблона:

{{ __('Translated string') }}

Кроме того, есть дополнительные функции Gettext — например множественное число:

{{ _n('Переведенная строка', 'Переведенная строка во множественном числе', $n) }}

Вы можете редактировать свои переводы с помощью Poedit — просто используйте эти файлы: resources/lang/i18n/[locale]/LC_MESSAGES/[domain].po

Пакет предоставляет методы для получения/установки активных локалей, изменения настроек в файлах конфигурации и обработки маршрутов — вы можете прочитать все это в официальном файле Readme.

В общем, я бы порекомендовал этот пакет, если вы знакомы с Gettext и Poedit — тогда вам не придется слишком сильно менять рабочий процесс.

10. caouecs/Laravel-lang

Адрес: https://github.com/caouecs/Laravel-lang
Автор: Fred Delrieu
Первый релиз: Март 2015

Последний пакет — это просто список из 73 языков для Laravel. В этом репозитории вы можете найти файлы lang.

Как использовать переводы в Ларавел

Все, что вам нужно сделать, это установить этот пакет, а затем скопировать нужные вам языки/файлы в вашу папку resources/lang.

Бонус: пакеты JavaScript

Пока искал для вас эти пакеты, то наткнулся на пакеты для JavaScript. Я не буду их здесь рассматривать, но они выполняют почти одно и то же — загружают ваши переводы в код JavaScript. Вот ссылки:

Выводы: Какой пакет лучше?

Пакеты разделены на категории, поэтому давайте начнем с Менеджеров перевода. Здесь нет победителя — каждый пакет в списке имеет свой подход к переводам или сценариям использования, вы просто выбираете тот, который подходит для вас: хотите ли вы переводить вещи через Интернет, Artisan, Google Sheets или Poedit.

Многоязычные модели — безусловными лидерами здесь являются два пакета с одноименным названием Laravel Translatable. Выберите тот, который вам больше нравится — либо Spatie, либо Astrotomic/Dimsav.

Наконец, лучшим (на сегодняшний день) пакетом для обработки маршрутов и мидлваров в мультиязычном проекте является Laravel Localization.

Автор: Povilas Korop
Перевод: Demiurge Ash