Мультиязычный сайт на Modx Revo с помощью Localizator
Здравствуйте, друзья. Эта большая статья посвящана созданию мультиязычного сайта на Modx Revolution с помощью бесплатного дополнения Localizator. Как всегда пошагово и подробно расскажу как сделать английскую версию сайта. Поехали.
Если вам лень читать можете посмотреть видеоурок по созданию мультиязычного сайта на Modx Revo
1. Устанавливаем Localizator
Заходим в Пакет/Установщик. Далее выбираем поставщика "modstore.pro" жмём на "Загрузить пакеты" и вбиваем в поиск Localizator
Загружаем. Устанавливаем.
2. Добавляем локализацию Ru и En
Заходим в Пакеты/Localizator
Нажимаем "Добавить Локализацию". Добавляем сначала локализацию Ru
Ключ локализации: ru
Название: Русский язык
HTTP HOST: домен.зона/
Ключ языка: ru
3. Добавляем английскую версию
В этом шаге есть два варианта создания английской версии. Типа site.com/en/ и en.site.com. Чтобы сделать версию сайта типа site.com/en/ создаём такую Локализацию
Ключ локализации: en
Название: Английский язык
HTTP HOST: домен.зона/en/
Ключ языка: en
Если же нам нужно, чтобы вторая версия была на поддомене типа en.site.com, то в HTTP HOST пишем
en.домен.зона/
В этом случае нам нужно:
- На хостинге добавить алиас (псевдоним, синоним) en.домен.зона к основному домену (не нужно создавать поддомен)
- Включить (поставить) галочку "Автоподдомены" (если такая есть на хостинге/сервере)
- Убрать "главное зеркало", чтобы система не переадресовывала все поддомены на главный домен
- Создать и прикрепить SSL сертификат Let's Encrypt wildcard, который распространяется на все поддомены.
3. Редактируем htaccess
В случае с site.com/en/
Добавляем правильные пути
RewriteRule ^(ru|en)/assets(.*)$ assets$2 [L,QSA]
Прописываем пути в самом начале файла для корректных путей для изображений в английской версии (если у вас изображения в папке images в корне сайта)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(ru|en|de|fr|lt|nl)/images(.*)$ images$2 [L,QSA]
В случае с en.site.com
перенаправляем все поддомены и сам домен с www на без www
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
3. Добавляем переключатель языков
Если вы работаете на Fenom (его нужно влючить в настройках pdotools), то создаёте сниппет getLanguages
<?php $output = ""; $pdo = $modx->getService('pdoTools'); $uri = $_SERVER['REQUEST_URI']; if(substr($uri, 0, 1)) { $uri = mb_substr($uri, 1); $tmp = explode('/', $uri); if($path = $tmp[0]) { $tmp = $modx->getObject('localizatorLanguage', array('http_host:LIKE' => "%/{$path}/")); if($tmp) { $uri = str_replace("{$path}/", "", $uri); } } } $protocol = 'https://'; $languages = $modx->getIterator('localizatorLanguage', ['active' => 1]); foreach($languages as $language) { if(mb_substr($language->http_host, -1) == '/') { $placeholders = array( 'cultureKey'=>$language->key, 'active'=>$language->key == $modx->localizator_key ? 'active' : '', 'url'=>$protocol . $language->http_host . $uri, ); } else { $placeholders = array( 'cultureKey'=>$language->key, 'active'=>$language->key == $modx->localizator_key ? 'active' : '', 'url'=>$protocol . $language->http_host . '/' . $uri, ); } $output .= $pdo->getChunk($tpl, $placeholders); } return $output;
Выводите в шаблоне, как правло в шапке сайта
<div class="langs"> {$_modx->runSnippet('!getLanguages', ['tpl' => 'section-langs-1',])} <div class="dropdown-menu"> {$_modx->runSnippet('!getLanguages', ['tpl' => 'section-langs-2',])} </div> </div>
Также нужно создать два чанка
Чанк section-langs-1
<a href="#" data-toggle="dropdown" role="button" aria-expanded="false"></a><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}">
Чанк section-langs-2
<div class="dropdown-item"> {if $active != 'active'} <a class="{$active}" href="{$url}"><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}"></a> {else} <div class="{$active}"><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}"></div> {/if} </div>
Будет всё работать из коробки если вы используете разметку Twitter Bootstrap.
Если вы не используете Fenom можно обойтись и без сниппета примерно такой конструкцией
[[++cultureKey:is=`ru`:then=`
<a class="topbar-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
<img class="me-1 mb-1" src="assets/img/flags/ru.png" width="20" alt="Russian">Rus
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item pb-1" href="https://en.site.ru/[[*uri]]"><img class="me-2" src="assets/img/flags/en.png" width="20" alt="English">English</a></li>
</ul>`]]
[[++cultureKey:is=`en`:then=`
<a class="topbar-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
<img class="me-1 mb-1" src="assets/img/flags/en.png" width="20" alt="English">Eng
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item pb-1" href="https://site.ru/[[*uri]]"><img class="me-2" src="assets/img/flags/ru.png" width="20" alt="Russian">Russian</a></li>
</ul>`]]
Можно и с помощью сниппета, но если вы вы ограничетесь всего одной локализацией, то можно и без сниппета. Но имейте ввиду, если вы добавите еще одну локализацию, то в этот переключатель нужно будет добавить еще один такой блок. Если вы планируете много языковых версий, то конечно, сниппет будет удобнее.
5. Создаём перевод любой страницы
Заходим на любую страницу и видим, что у нас появилась вкладка Локализация
Переходим в неё и, по хорошему, создаём две локализации. Русскую версию и Английскую версию. Я создавал только одну Локализацию (Английскую), так как у меня был уже рабочий проект. Если вы делаете сайт с нуля, то лучше сразу делать две локализации. Так будет проще настроить автоматический перевод. В Локализации вы сможете перевести абсолютно всё: Заголовок, Расширенный заголовок, описание, содержимое и все tv-параметры.
Это всё можно будет вывести на английской версии сайта.
6. Вывод перевода Локализации
На самой странице все поля, типа pagetitle, description и так далее будут отображать перевод, кроме content. По официальной документации содержимое выводим так
{$_modx->resource.localizator_content}
Но опять же нужно включить Fenom. Если по какой-то причине вы не можете включить Fenom или он не работает, придётся строить вот такую конструкцию
[[++cultureKey:is=`ru`:then=`[[*content]]
`:else=`
[[Localizator?
&parents=`[[*parent]]`
&depth=`0`
&tpl=`@INLINE [[+content]]`
&includeContent=`1`
&resources=`[[*id]]`
&limit=`1`
]]
`]]
я не претендую на идеальность такого метода, но другого способа без Fenom вывести контент я не нашёл. Если вы знаете, напишите, пожалуйста, в комментариях.
7. Перевод элементов сайта
Перевод таких элементов, как текст в кнопке, копирайт, поисковая строка и другое можно сделать с помощью словаря. Разберём на примере с кнопкой "Подробнее", которая встречается в ленте статей и много еще где. Для начала заменим в кнопке текст подробнее на конструкцию more, типа
<a href="#" class="btn">[[%more]]</a>
Далее идём в Система/Управление словарями
Выбираем понравившееся Пространство имён.
Можно выбрать localizator (я всё делал в core). Но это не важно. Нажимаем создать запись
Название: more
Язык: en
Значение: More
Теперь создадим запись для русской версии
Название: more
Язык: ru
Значение: Подробнее
Готово. Теперь через more в русской версии будет отображаться Подробнее, а в английской More. Тоже самое нужно проделать со всеми статичными текстами на сайте.
7. Перевод в pdoMenu, pdoResources, PdoCrumb
Так как у меня всего одна локализация (английская, русскую я не делал), мой вызов pdoResources такой:
[[![[++cultureKey:is=`ru`:then=`pdoResources`:else=`Localizator`]]?
&parents=`0`
]]
То есть, когда русская версия - у меня работает pdoResources, когда английская Localizator. Опять же не претендую на идеальность решения, но у меня работает.
По хорошему вам нужно в настройках pdotools поменять значение в pdoFetch.class на pdotools.pdofetchlocalizator и тогда pdoResources будет работать с локализациями.
В pdoPage я использую такую конструкцию:
[[!pdoPage?
&element=`[[++cultureKey:is=`ru`:then=`pdoResources`:else=`Localizator`]]`
]]
Меню pdoMenu я делаю так
[[!pdoMenu?
&startId=`0`
&leftJoin = `{
"localizator" : {
"class" : "localizatorContent",
"alias" : "localizator",
"on" : "localizator.resource_id = modResource.id"
}
}`
[[++cultureKey:ne=`ru`:then=`
&select = `{ "localizator" : "modResource.*, localizator.*, modResource.id" }`
&where = `{ "localizator.key" : "[[++cultureKey]]"}`
`]]
]]
Вот, в принципе, основа для создания Мультиязычного сайта на Modx Revolution. Таким же образом можно сделать локализации представительст в других городах, типа spb.site.com. Официальную документацию по Localizator можно посмотреть здесь. Там же вы найдете информацию об автоматическом переводе. На этом у меня всё, спасибо за внимание, до свидания.
{if $_modx->resource.localizator_content}
{$_modx->resource.localizator_content}
{else}
{$_modx->resource.content}
{/if}