PHP Profi

Использование Laravel'овских строк перевода(локализации) во Vue.js Перевод

Одина из проблем, с которой вам придется столкнуться при создании мультиязычного сайта — это то, как держать в порядке ваши строки переводов для серверной стороны и для JavaScript компонентов. Я собираюсь продемонстрировать основные приёмы реализации этого, используя в моих примерах Laravel и Vue.js.

Что это?

Сразу хочу уточнить, что приёмы показанные в этом посте полностью независимы от фреймворка и даже языка. Идея, лежащая в основе, будет работать также и в приложении на .Net с Ember.js на фронте.

Я опишу это с двух сторон, так что вы можете прочитать только про то, что вам нужно. Если вы просто ищите решение для вашего приложения на Laravel и Vue, пролистайте и посмотрите на примеры с кодом. Если вы прочитали выше абзац про .Net и находитесь в недоумении, то не переживайте мы погрузимся чуть глубже, рассказав что мы действительно делаем — в дополнение к работе с кодом самих библиотек.

Обзор процесса

Сначала давайте посмотрим на то, что мы пишем и почему. Целью является иметь единый источник строк перевода, которые могут быть использованы в шаблонах нашего backend-языка (Laravel blade), а также в наших frontend-компонентах (Vue). Несмотря на то, что может показаться проще просто иметь php-файлы для одного и json-файл для другого, поддерживая переводы в актуальном состоянии, всё же будет ещё намного проще, если у нас будет единый источник. Однако, эти два языка не могут свободно "общаться" друг с другом напрямую, поэтому мы должны написать своего рода мост между ними.

Это значит, нам понадобятся следующие компоненты:

  1. Наши .php файлы, которые хранят наш перевод в виде пар ключ-значение (ака, массивы).
  2. Сервис, который будет конвертировать эти файлы во что-то, что может читать Vue.
  3. Сервис, который будет читать этот преобразованный вывод и делать возможным импорт оного в компонент Vue.
  4. Некоторый дополнительный стандартный код на Vue для простоты использования.

Серверные файлы переводов

Первый пункт этого списка поставляется с нашим фреймворком Laravel —  компонент Localization или “lang”-файлы. Подробнее: https://laravel.ru/docs/v5/localization (на русском) или https://laravel.com/docs/5.5/localization (оригинальная документация). Я не буду тратить очень много времени на него, так как он довольно прост и хорошо документирован — по ссылке выше или в многочисленных руководствах/статьях. Я бы порекомендовал создавать директорию components внутри каждой языковой директории (т.е. /resources/en/components) по причинам, которые вы увидите далее.

Php-файлы удобны для интеграции с нашей системы, и, возможно, для использования стороннего API для поддержки самих переводов, но они всё же php-файлы и должны быть преобразованы во что-то, что сможет прочесть javascript для наших Vue-компонентов. Есть разные варианты: если у вас небольшой сайт, вы покажется проще создать Vue-prop и передать набор значений на соответствующих страницах — так же, как вы передаёте другие данные инициализации. Однако, это будет немного беспорядочно и не очень быстро.

Создание единого файла перевода

Приём, который мы собираемся использовать, состоит в том, чтобы преобразовать их все в один файл javascript, который мы позже сможем импортировать во Vue. Есть много хороших библиотек для этого. Если вы работаете с Laravel, вам может понравится Laravel-JS-Localization, которая работает со всеми версиями Laravel. Это только конвертер php-файлов в js-файл, так что для нас по-прежнему не имеет значения что мы используем на клиентской стороне Vue, или Angular, или что-нибудь ещё. Кроме того, если вы не используете Laravel, вы можете найти (или создать) эквивалентную библиотеку для этого преобразования (например, «CakePHP-JS-Localization», которая будет понимать систему файлов перевода CakePHP).

Настройка этой библиотеки очень простая, но я просто отмечу пару вещей, которые я нашел, когда я её устанавливал. Файл config/localization-js.php имеет две настройки. В messages перечисляются файлы, которые вы хотите включить в этот файл перевода, т.е. просто список php-lang-файлов для ваших Vue-компонентов. В настройке path указывается путь, где этот файл будет создан, т.е. скорее всего вы захотите расположить его в ваших assets, если вы используете для сборок фронтэнда gulp или что-то похожее. Я бы назвал его как-то более понятно, чем “translations” или “messages”, чтобы не путать его с другим кодом. Я назвал так:

/*
 * The default path to use for the generated javascript.
 */
'path' => resource_path('assets/js/vue-translations.js'),

Для выполнения конвертации мы будем использовать команду artisan lang:js  --quiet  --no-lib.

Каждый раз, когда вы добавляете или изменяете переводы в поддиректории components вам потребуется переконвертировать их, т.к. Vue на самом деле использует файл vue-translations.js, так что все изменения должны быть воссозданы в нём. В зависимости от того, как часто вы это делаете, вы можете захотеть добавить эту команду в свою сборку фронта (gulp, mix, что угодно). Переконвертация происходит очень быстро и не добавит много времени на сборку.

Подгрузка его во Vue.js

Если вы посмотрите внутрь файл vue-translations.js, то вы увидите, что это большая json-свалка всех en/components/*.php файлов. Так что следующее, что нам нужно — это какой-то парсер, который сможет прочитать этот json и выбрать одину конкретную строку перевода, которая нам нужна. Для этого мы будем использовать https://github.com/rmariuzzo/lang.js.

Итак, еще раз — чтобы было ясно, что мы делаем. Файл vue-translations.js — это стандартный формат, который понимает Lang.js. Неважно как мы получили наши переводы в этом формате, главное, что мы сделали так, чтобы Lang.js смог использовать свой функционал, чтобы прочитать его. Вот почему я сказал, что не важно, какой фреймворк или даже язык программирования используется. (Вы даже могли бы написать его вручную, если вы достаточно мазохистичны).

Сейчас мы на шаге 3 — импорт библиотеки Lang.js в наш фронтэнд (в данном случае, Vue). Библиотека имеет простой API и использует функции в стиле lang.get('greetings.hello'), но мы хотим импортировать её во Vue чтобы можно было легко её использовать в наших компонентах.

Посмотрим на наш файл main.js (или как вы называете ваш “глобальный” файл для всех компонентов). Мы можем создать пользовательский фильтр, как показано ниже:

// Если файл разрастается, вы можете вынести это в filters.js
var Vue = require('vue');
var Lang = require('lang.js');

// получение данных
import translations from './vue-translations.js';

// вот почему мы использовали --no-lib в командной строке
var lang = new Lang();
lang.setLocale('en');  // @TODO вызвать когда мы создаём переключатель языков

// по умолчанию 'en', но но если вам нужен другой язык,
// в Lang.js есть такой функционал, который вы можете использовать:
// if (lang.getLocale() === 'undefined'){
//     lang.setLocale('en');
// }

// передача данных в Lang.js
lang.setMessages(translations);

// Это наш обычный фильтр Vue.
// '...args' позволяет нам использовать любое количество параметров в наших строках
Vue.filter('trans', (...args) => {
    return lang.get(...args);
});

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

Ну и в конце давайте заюзаем это на нашей странице!

Добавление в компоненты Vue.js

Наш основной фильтр во Vue будет работать так:

// вызов без параметров:
{{{ 'components/Faqs.question' | trans }}}

// передача дополнительных параметров:
// для Vue 1.*
{{{ 'components/Faqs.question' | trans {'value' : 'Pass this value'} }}}
// для Vue 2.*
{{{ 'components/Faqs.question' | trans({'value' : 'Pass this value'}) }}}

Обратите внимание на синтаксис. Для этого примера в Laravel это будет файл с именем Faqs.php в подкаталоге с названием components внутри en (или любой другой языковой группы). question - это ключ в оригинальном массиве. Строка ‘components/Faqs.question’ передается в trans-фильтр без параметров в этом случае, а trans() говорит Lang.js найти этот ключ во vue-translations.js.

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

  1. Создали обычные lang-файлы в Laravel (например /en/components/Faq.php).
  2. Преобразовали в один json-файл (vue-translations.js).
  3. Подключили Lang.js для чтения этого json и вытаскивания нужного ключ:значение.
  4. Создали фильтр Vue.js для простоты использования Lang.js функций в наших компонентах.

Итак! В итоге у нас остался один источник переводов, который мы можем импортировать в любой сторонний сервис для переводов.

Надеюсь, это поможет!

2018-01-18 оригинал

Последние посты

Комментарии

авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий