Мультиязычность в MODX Revo (Контексты + Babel)


Содержание:


Подключить мультиязычность на MODX Revolution не сложно, но нужен четкий план действий. Для лучшего понимания рассмотрим процедуру подключения на примере.

Допустим мы хотим подключить два дополнительных языка для сайте, то есть мы хотим получить следующий результат:

  • Русская версия сайта — http://site.ru/
  • Английская версия — http://site.ru/en/

Языков можно подключить неограниченно, для примера остановимся на 1-ом дополнительном языке.

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

Для реализации данной задачи нам понадобится:

  • MODX Revolution (2.0 и старше), само собой
  • Доступ до .htaccess (или ht.access)
  • Плагин Babel (2.2 и старше)

Настройка .htaccess

В корне сайта должен быть файл .htaccess (иногда файлы скрыты от просмотра, см. в настройках вашего FTP-клиента) или ht.access (его переименовываем в .htaccess).

Настройка .htaccess

В файле .htaccess проверяем правильность 'RewriteBase' и включен ли modRewrite ('RewriteEngine On').

ВАЖНО! .htaccess — файл дополнительной конфигурации веб-сервера Apache, если у вас другой сервер и без Apache конфигураций, то директивы в .htaccess у вас работать не будут, но практически все современные сервера используют связку Apach + nginx, т. е. работать .htaccess в большинстве случаев на вашем сервере будет. Работает ли modRewrite можно проверить путем добавления обычных редиректов в .htaccess или путем настройки SEF-ссылок (если они работают, то .htaccess активен).

Если сайт установлен в корневой каталог используемого домена, то в .htaccess пишем:

RewriteEngine On
RewriteBase /

Если сайт установлен не в корневой каталог, то пишем:

RewriteEngine On
RewriteBase /каталог/

Далее добавляем в наш .htaccess после наших редиректов, в самом конце, следующее (см. изображение ниже):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(ru|en)/favicon.ico$ favicon.ico [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(ru|en)/assets(.*)$ assets$2 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(ru|en)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]

Где (ru|en) должны совпадать с: ru для корневой директории http://site.ru/ , а en — с http://site.ru/en/ (прописываются в настройках контекста ниже).

ВАЖНО! Директивы '# The Friendly URLs part' УДАЛЯЕМ или комментируем через # (по умолчанию включены), получится так (см. изображение ниже):

# The Friendly URLs part
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Настройка .htaccess

Настройка контекстов

В админке MODX нам нужно создать контекст для нового языка. Для этого перейдите по: «Система» -> «Контексты» и кликаем по «Создать новый».

Настройка контекстовНастройка контекстов

Далее в качестве «Ключа контекста» вводим, например, для английского — «eng».

ВАЖНО! Эти ключи в дальнейшем будут использованные в плагине переключения контекстов.

При добавлении контекста важно поле «Ключа контекста», а поля «Имя» и «Описание» не играют особой роли.

Далее правый клик мыши по новому контексту и выбираем «Редактировать». Переходим по табу «Настройки контекста» и кликаем по «Создать новый».

Настройка контекстов

Для каждого языка нам нужно добавить следующие настройки.

Существующий контекст (ключ «web»)
Многие настройки для контекста web не обязательны, т. к. они уже настроены в «Системных настройках» админ-панели (кроме cultureKey (Babel не выводит переключатель без него) остальные можно не заполнять, но лучше заполнить :) ):

Редактируем новый контекст (ключ «eng»):

Base URL

  • Ключ: base_url
  • Имя: Base URL
  • Запись словаря для раздела: language
  • Значение: /

Culture key ([[++cultureKey]]). Не путать с «Ключом контекста» ([[*context_key]])

  • Ключ: cultureKey
  • Имя: Culture key
  • Запись словаря для раздела: language
  • Значение: ru

Site start

  • Ключ: site_start
  • Имя: Site start
  • Запись словаря для раздела: language
  • Значение: 1

Site name

  • Ключ: site_name
  • Имя: Site name
  • Запись словаря для раздела: language
  • Значение: Название сайта

Site URL

  • Ключ: site_url
  • Имя: Site URL
  • Запись словаря для раздела: language
  • Значение: / (или http://site.ru/)

Error page

  • Ключ: error_page
  • Имя: 404 page
  • Запись словаря для раздела: language
  • Значение: id страницы для 404 ошибки

Опционально:

Locale, используется для форматирования даты в текстовом виде

  • Ключ: locale
  • Имя: Setting locale
  • Запись словаря для раздела: language
  • Значение: ru_RU.UTF8

Base URL

  • Ключ: base_url
  • Имя: Base URL
  • Запись словаря для раздела: language
  • Значение: /en/

Culture key

  • Ключ: cultureKey
  • Имя: Culture key
  • Запись словаря для раздела: language
  • Значение: en

Site start

  • Ключ: site_start
  • Имя: Site start
  • Запись словаря для раздела: language
  • Значение: id страницы для Главной в английской версии (Все id создаем переводом через Babel, об этом ниже)

Site name

  • Ключ: site_name
  • Имя: Site name
  • Запись словаря для раздела: language
  • Значение: Название сайта на английском языке

Site URL

  • Ключ: site_url
  • Имя: Site URL
  • Запись словаря для раздела: language
  • Значение: /en/ (или http://site.ru/en/)

Error page

  • Ключ: error_page
  • Имя: 404 page
  • Запись словаря для раздела: language
  • Значение: id страницы для 404 ошибки в английской версии (Все id создаем переводом через Babel, об этом ниже)

Опционально:

Locale

  • Ключ: locale
  • Имя: Setting locale
  • Запись словаря для раздела: language
  • Значение: en_US.UTF8

Практически все системные настройки можно прописать уникальными для каждого контекста.

Создание плагина «switchContext»

Для того чтобы наша мультиязычность работала нам нужно разработать плагин для связки языка с контекстом.

В панели управления переходим по табу «Элементы» и кликаем по иконке «Новый плагин».

В поле имя пишем switchContext, в код помещаем следующий код:

<?php
if($modx->context->get('key') != "mgr") {
/* Определяем текущий язык в cultureKey */
switch ($_REQUEST['cultureKey']) {
/* Переключаем контекст */
case 'en':
$modx->switchContext('eng');
break;
/* Добавляем дополнительные языки в плагин, если нужно
case 'de':
$modx->switchContext('dtsch');
break;
*/
/* Устанавливаем контекст по умолчанию */
default:
$modx->switchContext('web');
break;
}
/* Очищаем GET-параметр чтобы не допустить появлении ссылки вида cultureKey=xy при генерации URL других компонентов */
unset($_GET['cultureKey']);
}

Далее переходим по табу Системные события и включаем OnHandleRequest, и сохраняем.

Создание плагина switchContext

Установка Babel

Устанавливаем пакет Babel, в админ-панели переходим по «Система» -> «Управление пакетами» и кликаем «Загрузить дополнения» и находим там Babel, загружаем и устанавливаем пакет.

Проходим все необходимые условия установки пока не увидите «Настройки установки». Здесь уже должны быть контексты которые мы создали (по примеру это: web, eng; если поле пустое, то можно вписать ключи контекстов руками), другие настройки оставляем без изменений.

Создание мультиязычного контента

Как добавлять страницы сайта на других языках?

В админ-панели сайта, в табе «Ресурсы», мы видим наши контексты (выводятся имена контекстов, которые вы заполнили при создании/редактировании контекста). Ресурсы каждого из контекстов отвечают за ресурсы языковых версий сайта.

Как добавлять страницы сайта на других языках?

Но как нам знать какой ресурс за какую страницу отвечает, т. е. как же связать страницы разных языков между собой?

Здесь нам поможет Babel. При создании или редактировании ресурса в правом верхнем углу появятся кнопки, отвечающие за языковые версии («Создать перевод», «Связать перевод…»). Через эти кнопки создаются копии ресурсов только в другом контексте (языковой версии).
Полученные id ресурсов и используем в настройках контекстов (см. выше).

Как добавлять страницы сайта на других языках?

Наконец нам нужны кнопки (ссылки) переключения языков на сайте. С помощью Babel это очень просто реализовать.

Для этого в месте где вы хотите вывести переключатель (шаблон, чанк) пишем следующее:

<ul>
[[BabelLinks?
&showCurrent=`1`
]]
</ul>

Все параметры BabelLinks можно посмотреть тут — https://docs.modx.com/extras/revo/babel/babel.babellinks.

Однако Babel переведен не на все языки (кнопки, ссылки переключатели), поэтому можно для нужных языков добавить свои переводы, скопировав и поправив, например, папку «ru» в /public_html/core/components/babel/lexicon/ (причем имя папки должно совпадать с cultureKey в настройках добавленного контекста).

Вывод статического содержимого в зависимости от контекста

Существует нескоолько методов вывода разного статического содержания (заголовки, адреса и копирайт в футере, кнопки и пр.) в зависимости от контекста:

1. Создать для каждого чанка копии с нужным языком, например, [[$footer_ru]], [[$footer_en]], а в шаблонах вызывать в виде [[$footer_[[++cultureKey]]]] (при генерации страницы MODX подставит нужное значение [[++cultureKey]] и выведет содержание чанка для активного языка).

2. Можно проверять контекст и выводить нужное содержимое через фильтры ввода-вывода.

Условие вывода лучше прописывать именно через [[*context_key]], а, к примеру, не через [[++cultureKey]] т. к. Ключ контекста заполняется один раз и изменить его нельзя (дополнительная зашита от дурака), а настройки же контекста можно менять неограниченно.

Например, условие будет таким:

[[*context_key:is=`web`:then=`г. Москва, ул. Льва Толстого, д. 1`:else=`Moscow, Leo Tolstoy st. 1`]]

С другой стороны, с использованием [[++cultureKey]], условие будет грамотнее читаться:

[[++cultureKey:is=`ru`:then=`г. Москва, ул. Льва Толстого, д. 1`:else=`Moscow, Leo Tolstoy st. 1`]]

В общем, выбор, как всегда, за вами :)

Автоматически определяем id переведенных страниц

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

В этом нам поможет сниппет BabelTranslation. Подробнее можно посмотреть тут — BabelTranslation. BabelTranslation выводит связанный id переведенной страницы нужного контекста:

[[BabelTranslation? &resourceId=`6` &contextKey=`eng`]]

Выведет в шаблоне связанный id в контексте eng для страницы с id=6 активного контекста (в нашем случае web).

В совокупности с условиями ввода-вывода, конструкцию можно сделать грамотнее:

[[*context_key:is=`web`:then=`6`:else=`[[BabelTranslation:default=`6`? &resourceId=`6` &contextKey=`eng`]]`]]

Тут мы выводим id=6, если контекст web и выводим связанный id для контекста eng через BabelTranslation, если же связанного id нет, то выведет id=6 (исходя из :default). Подробнее об условиях ввода-вывода смотри тут.

Конструкцию можно сделать еще грамотнее и проще, для этого всю конструкцию сохраняем в чанк [[$eng_id]] и задаем параметр [[+ru_id]] в чанке (чанк и параметр можно назвать как угодно).

Код чанка:

[[*context_key:is=`web`:then=`[[+ru_id]]`:else=`[[BabelTranslation:default=`[[+ru_id]]`? &resourceId=`[[+ru_id]]` &contextKey=`eng`]]`]]

А так, например, выводим id для ссылки через наш чанк с параметром (если не найдет переведенную страницу, откроется исходная страница):

<a href="[[~[[$eng_id?ru_id=`6`]]]]"></a>

Бывает так, что нужно сделать не разные языковые версии сайта, а разные сайты для городов, однако у таких сайтов много дублирующих страниц будет, чтобы этого не возникало, можно пользоваться «символическими ссылками», они позволяют использовать контент указанной страницы, но при этом можно задать свои заголовки, шаблон, url и поля. Т. е. править текст можно будет в одном месте.

По умолчанию между контекстами нельзя ставить символические ссылки, чтобы это включить — переходим в админке сайта «Системные настройки» выбираем в фильтре «Система и сервер» и ставим у «Разрешить перенаправление через контексты» — «Да»

Символические ссылки для контекстов

Источники файлов в TV для нескольких контекстов

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

Вот и все, да здравствует мультиязычность в MODX Revolution :)


Свяжитесь с нами

Нажимая на кнопку «Отправить», я даю свое согласие на обработку персональных данных в соответствии с законом №152-ФЗ «О персональных данных» от 27.07.2006 и принимаю условия Пользовательского соглашения