Дорогие друзья! Сегодня мы с вами будем настраивать мультиязычность с помощью компонента Babel на примере одного из наших проектов. Забегая вперед скажу, что данный способ подходит и для организации мультисайтовости в MODx Revo.
Для начала устанавливаем компонент Babel из официального репозитория. При установке он у нас спросит про некоторые параметры, мы оставляем все по умолчанию и устанавливаем.
Настройки контекстов
Реализовывать мультиязычность мы с вами будем на примере украинского языка. И для начала создадим контекст с ключом UA, а имя ему дадим “Украинский”. Так как контекст WEB у нас с вами будет по умолчанию русским, его тоже можно отредактировать, дав ему имя – “Русский”.
Теперь нам с вами необходимо настроить наши контексты. Для этого кликаем по контексту в дереве ресурсов правой кнопкой мыши и нажимаем “редактировать”. На вкладке “Настройки контекста” нам с вами необходимо переопределить некоторые глобальные настройки системы.
Для вашего удобства я приведу все заполненные мной настройки контекстов в одной таблице.
Настройка | web | ua |
base_url | / | /ua/ |
cultureKey | ru | ua |
site_start | 1 | 205 |
site_url |
Теперь предлагаю разобраться с параметрами:
- base_url – базовый URL сайта относительно корня
- cultureKey – ключ языка
- site_start – идентификатор главной страницы сайта
- site_url – URL сайта (если вы используете домены или поддомены, то вместо моих значений у вас должны стоять разные домены, поддомены)
Не забывайте нажать кнопку “сохранить” после выставления всех настроек.
Настройка htaccess.
После того, как мы внесем все параметры в наши контексты нам необходимо настроить так называемы роутинг для инициализации наших контекстов. И первый файл, который мы с вами поправим – это .htaccess. В нем нам необходимо закомментировать стандартный роутинг MODX и сделать такую конфигурацию:
# The Friendly URLs part #RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_FILENAME} !-d #RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(ru|ua)/favicon.ico$ favicon.ico [L,QSA] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(ru|ua)/assets(.*)$ assets$2 [L,QSA] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(ru|ua)/images(.*)$ images$2 [L,QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(ru|ua)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]
Обратите внимание, что я оставил закоменченный роутинг MODX, для того, чтобы вам было удобнее ориентироваться.
Если же вы используете домены или поддомены, то вам не нужно использовать настройку .htaccess. Можете сразу переходить к написанию плагина.
Смысл здесь довольно простой: сначала мы настраиваем редиректы с /ua/favicon.ico, /ua/assets/, /ua/images/ на аналогичные папки без виртуального префикса /ua/. Следующий шаг, нам необходимо отследить, какой из контекстов мы будем грузить. Также делаем это на основе виртуального префикса /ua/, передав его в MODX как GET-параметр cultureKey.
Пишем плагин-обработчик
MODX у нас не знает, что появился новый параметр. Поэтому нам необходимо написать плагин gateway на событие onHandleRequest:
<?php if ($modx->context->key == 'mgr' || !$modx->getOption('friendly_urls') || $modx->event->name != 'OnHandleRequest') { return; } switch($_REQUEST["cultureKey"]){ // Украинский case 'ua': $modx->switchContext('ua'); break; // Русский default: $modx->switchContext('web'); break; } unset($_GET["cultureKey"]);
Таким образом, мы с вами научили MODX работать с новым параметром. Если же вы используете домены или поддомены, то в вашем случае плагин будет выглядеть примерно так:
<?php /* don't execute if in the Manager */ if ($modx->context->key == 'mgr' || !$modx->getOption('friendly_urls') || $modx->event->name != 'OnHandleRequest') { return; } switch ($_SERVER['HTTP_HOST']) { // проверка домена 1 case 'mastercentr.tmweb.ru': // if the http_host is of a specific domain, switch the context $modx->switchContext('web'); break; // проверка домена 2 case 'mso.mastercentr.tmweb.ru': // if the http_host is of a specific domain, switch the context $modx->switchContext('moika'); break; default: // by default, don't do anything $modx->switchContext('web'); break; }
Отлично! Теперь мы настроили с вами основную часть нашей задачи. Теперь осталось дело за малым – перевести все тексты. Для статичных элементов в нашей верстке нам необходимо создать файлы лексикона MODX.
Переводы в файлах лексиконов.
Надеюсь, вы уже заметили, что у каждого компонента в папке /core/components/ есть папка /lexicon/, в которой хранятся файлы лексиконов. Мы с вами будем работать в папке компонента babel. Так как у нас там не будет находится папки /ua/ ее необходимо будет создать. Также советую туда продублировать файл default.inc.php из папки /ru/.
Для переводов непосредственно на сайте я создаю в обоих папках файл translate.inc.php, где переведем фразу “Заказать звонок” и наименования наших языков. Файл translate.inc.php из папки “ru”:
<?php $_lang["ledsystems.buttons.callback"] = "Заказать звонок"; /* ----------- Языки -------------- */ $_lang["ledsystems.lang.ru"] = "RU"; $_lang["ledsystems.lang.ua"] = "UA";
Файл translate.inc.php из папки “ua”:
<?php $_lang["ledsystems.buttons.callback"] = "(укр.) Заказать звонок"; /* ----------- Языки -------------- */ $_lang["ledsystems.lang.ru"] = "(укр.) RU"; $_lang["ledsystems.lang.ua"] = "(укр.) UA";
На языках лучше создавать ключи, у которых значение задано с префиксом, в моем случае “(укр.)”. После полного заполнения файла он передается заказчику, и он уже все переведет с учетом контекста изложения.
Использование лексиконов.
Далее мы можем использовать наши лексиконы в шаблонах, чанках и сниппетах. В шаблонах и чанках мы будем использовать их следующим образом в синтаксисе fenom:
{$_modx->lexicon("ledsystems.buttons.callback")} {"ledsystems.buttons.callback" | lexicon}
Единственное, нужно заранее загрузить файлы лексикона выше строкой (обычно я это делаю в самом верху шаблона):
{$_modx->lexicon->load('babel:translate')}
В случае, если вы используете стандартный синтаксис, то вызов лексикона будет следующим образом:
[[%ledsystems.buttons.callback? &namespace=`babel` &topic=`translate`]]
В сниппете же вызов будет такой:
<?php // подгрузка лексиконов $modx->lexicon->load('babel:translate'); // использование $data = $modx->lexicon(‘ledsystems.buttons.callback’);
Настройка идентификаторов контейнеров, ресурсов.
Для того, чтобы передавать корректные значения parents и аналогичные, я советую использовать их через настройки контекста. Таким образом, мы сделаем работу с контекстами гибкой и удобной. Использовать настройки контекста мы сможем также, как и настройки системы. В синтаксисе fenom:
{$_modx->runSnippet("pdoMenu",[ "parents" => $_modx->config.ledsystems_base_catalog, "level" => 1 ])}
Стандартный синтаксис:
[[pdoMenu? &parents=`[[++ ledsystems_base_catalog]]` &level=`1` ]]
Вывод ссылок на языковые версии.
Вывести ссылки на языки мы можем с помощью сниппета babelLinks, таким образом:
{$_modx->runSnippet("!babelLinks", [ "showCurrent" => 1, "includeUnlinked" => 1, "tpl" => "babelLinksTpl" ])}
Параметры showCurrent (показывать ссылку на текущую языковую версию) и includeUnlinked (показывать ссылки на не прикрепленные ресурсы) можете использовать по желанию.
Таким вот образом можно настраивать мультисайтовость и мультиязычность с помощью компонента babel. При настройке мультисайтовости, использование babel не обязательно.
Из miniShop2 галерея не будет переноситься, так как это два совсем разных ресурса. Советую вам разобраться в принципе работы компонентов MODX и их структуре (хотя бы поверхностно) — тогда многие вопросы отпадут сами собой.
Сам понимаю что не хватает базовых знаний, поэтому буду разбираться далее, меня чем и подкупил МОДекс, так это своей простотой и гибкостью. Надеялся что и здесь можно воспользоваться каким нибудь «хитрым кодом».
Кстати, не разбираясь ни в html, ни в css, за небольшой промежуток времени, только благодаря вашим урокам удалось реализовать полноценный, работающий интернет-магазин, и теперь уже сделать его мультиязычным. Агонь!
Поменял названия чанков на свои.
Спасибо огромнейшее!
Существует ли возможность выводить у переведённого ресурса цепочку отзывов или тикетов, которые принадлежат родительскому ресурсу? Или у каждого ресурса исключительно своя цепочка отзывов и никак это не обойти?