Modx Revo multilanguage babel

tsumbaluk.in.ua28 Февраль 2017

Настройка многоязычности сайта на Modx с помощью babel

Приветствую тебя читатель, в данном руководстве речь пойдет о реализации многоязычности, что по моему скромному мнению не есть тривиальной задачей не в одной из известных мне CMS(таких, как Wordpress, Drupal) или PHP фреймворках вроде Symphony. А если предположить что ваше основное поле деятельности front-end разработка, так и подавно. Но благо каждая платформа предлагает свои модули для решения такой задачи ну и естественно MODX не исключение, он предоставляет в наше пользование пакет под названием Babel, к помощи коего мы и прибегнем во время выполнения этой задачи.

Шаг 1. Настройка .htaccess

Должно быть что-то вроде этого где IfModule mod_rewrite.c отвечает за редиректы и многоязычность а ifModule mod_expires.c за кеширование данных на сервере. Небольшое примечание данные настроки я использую и на своем сайте портфолио front-end разработчика, при этом скорость загрузки главной страницы на page spped в момент публикации донной статьи составляла 90%. Что я считаю очень не плохо!

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  RewriteCond %{HTTP_HOST} ^www\.tsumbaluk.jaya-test\.com$ [NC]
  RewriteRule ^(.*)$ http://tsumbaluk.jaya-test.com/$1 [R=301,L]


  RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
  RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,NC]

  # redirect all requests to /ua/favicon.ico and /en/favicon.ico and /ru/favicon.ico to /favicon.ico
  #RewriteCond %{HTTP:Accept-Language} !^ru/ [NC]
  #RewriteRule ^$ ru/ [R=301,L]
  #RewriteRule ^$ en/ [R=301,L]
  #RewriteRule ^$ ua/ [R=301,L]
  RewriteRule ^(ru|en|ua)/favicon.ico$ favicon.ico [L,QSA]

  # redirect all requests to /en/assets* and /ru/assets* and /ua/assets*
  # to /assets*
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(ru|en|ua)/assets(.*)$ assets$2 [L,QSA]
  RewriteRule ^(ru|en|ua)/design(.*)$ design$2 [L,QSA]

  # redirect all other requests to /en/* and /ru/* and /ua/*  to index.php and set the cultureKey parameter
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(ru|en|ua)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]
</IfModule>

<ifModule mod_expires.c>
	# Add correct content-type for fonts
	AddType application/vnd.ms-fontobject .eot
	AddType application/x-font-ttf .ttf
	AddType application/x-font-opentype .otf
	AddType application/x-font-woff .woff
	AddType image/svg+xml .svg

	# Compress compressible fonts
	AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-opentype image/svg+xml

	ExpiresActive On
	ExpiresDefault "access plus 5 seconds"

	# Cache Images
	ExpiresByType image/x-icon "access plus 2592000 seconds"
	ExpiresByType image/jpeg "access plus 2592000 seconds"
	ExpiresByType image/png "access plus 2592000 seconds"
	ExpiresByType image/gif "access plus 2592000 seconds"
	ExpiresByType image/svg+xml "access plus 2592000 seconds"

	# Cache Fonts
	ExpiresByType application/vnd.ms-fontobject "access plus 2592000 seconds"
	ExpiresByType application/x-font-ttf "access plus 2592000 seconds"
	ExpiresByType application/x-font-opentype "access plus 2592000 seconds"
	ExpiresByType application/x-font-woff "access plus 2592000 seconds"
	ExpiresByType image/svg+xml "access plus 2592000 seconds"

	# Cache other content types (Flash, CSS, JS, HTML, XML)
	ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
	ExpiresByType text/css "access plus 604800 seconds"
	ExpiresByType text/javascript "access plus 2592000 seconds"
	ExpiresByType application/javascript "access plus 2592000 seconds"
	ExpiresByType application/x-javascript "access plus 2592000 seconds"
	ExpiresByType text/html "access plus 600 seconds"
	ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>

Шаг 2. Создание контекстов

В сети можно найти статьи в которых этот пункт сводиться к занудным однотипным действиям. Я в свою очередь предлагаю использовать скрип для создания необходимых языковых контекстов. Которым со мной поделился мой бывший коллега и по совместительству front-end developer (вот его сайт со множеством готовых примеров). Для выполнения PHP скрипта нам понадобиться модуль Console так что если он у вас еще не установлен тогда: Приложения - установщик - загрузить дополнения ищем и устанавливаем Console. После установки данный модуль доступен для использования Приложения - Console. Вставляем скрипт и прописываем настройки в зависимости от нужного языкового контекста. Чаще всего ето контекст 'English' (ключ: en), контекст 'Ukrainian' (ключ: ua), контекст 'Russian' (Ключ: web)

<?php
	//Настройки Ukrainian
	$context_main = array(
	  'key' => 'ua',
	  'name' => 'Ukrainian',
	  'description' => 'This is Ukrainian context'
	);
	$context_params = array(
	  'cultureKey' => 'uk',
	  'site_start' => 1,
	  'base_url' => '/ua/', 
	  'site_url' => 'http://tsumbaluk.jaya-test.com/ua/',
	  'error_page' => 2
	);

	//Далее ничего не меняем!
	//Создаем контекст
	$context = $modx->getObject('modContext', array('key' => $context_main['key']));
	if(!$context){
	  $context = $modx->newObject('modContext');
	}
	$context->set('key',$context_main['key']);
	$context->set('name',$context_main['name']);
	$context->set('description',$context_main['description']);
	$context->save();

	//создаем настройки контекста
	foreach ($context_params as $key => $value) {
	  $context_setting = $modx->getObject('modContextSetting', array('key' => $value));
	  if(!$context_setting){
	    $context_setting = $modx->newObject('modContextSetting');
	  }
	  $context_setting->set('context_key',$context_params['cultureKey']);
	  $context_setting->set('key',$key);
	  $context_setting->set('value',$value);
	  $context_setting->set('xtype','textfield');
	  $context_setting->set('namespace','core');
	  if($value !== 'error_page'){
	    $context_setting->set('area','language');
	  }
	  $context_setting->set('editedon',0);
	  $context_setting->save();
}?>

Шаг 3. Связка языка и контекста

Создаем плагин для с названием gateway (название может быть любым на ваше усмотрение). Код плагина ниже, также перед сохранением не забываем поставить галочку Системные события : OnHandleRequest.

<?php
$lngkey = substr($_SERVER['REQUEST_URI'], 1, 2);
if ($modx->context->get('key') != "mgr"){
  switch ($lngkey){
  case 'en':
    setlocale(LC_ALL, "en_US.UTF-8");
    $modx->switchContext('en');
    $modx->setOption('cultureKey', 'en');
    break;

  case 'ua':
    setlocale(LC_ALL, "uk_UA.UTF-8");
    $modx->switchContext('ua');
    $modx->setOption('cultureKey', 'uk');
    break;

  default:
    setlocale(LC_ALL, "ru_RU.UTF-8");
    $modx->switchContext('web');
    $modx->setOption('cultureKey', 'ru');
    break;
  }
}
?>

Шаг 4. Установка дополнения Babel

Тут все просто Приложения - установщик - загрузить дополнения ищем и устанавливаем. Вот тут информация и документация по данному модулю.

Шаг 5. Вывод переключателей языков

Отобразить во front-end языковый список позволяет снипет утановленого пакета babel.

<div class="lang-switcher">
  <span>[ [++cultureKey:is=`uk`:then=`ua`:else=`[ [++cultureKey]]`]]</span>
  <ul>
    [ [BabelLinks? &tpl=`tpl.BabelLink`]]
  </ul>
</div>

Ну и чанк tpl.BabelLink

<li>
    <a href="[ [+url]]" class="[ [+cultureKey]][ [+active:notempty=`[ [+active]]`]]">
        [ [+cultureKey:is=`uk`:then=`ua`:else=`[ [+cultureKey]]`]]
    </a>
</li>

Шаг 6. Переводы статических строк

идем (core/components/babel/lexicon/ru/translate.inc.php - для контекста ru), и в таком формате создаем переводы для русского языка, (core/components/babel/lexicon/uk/translate.inc.php - для контекста uk) для украинского и так далее.

$_lang['button-call']          = 'Перезвоните мне';
$_lang['button-more']          = 'Подробнее';
$_lang['button-reead-more']    = 'Читать подробнее';

Вывод во front-end - указать перевод можна следующим образом.

[ [%button-call? &topic=`translate` &namespace=`babel`]]
[ [%button-more? &topic=`translate` &namespace=`babel`]]
[ [%button-reead-more? &topic=`translate` &namespace=`babel`]]

Шаг 7. Возможная ошибка

При создании переводов страниц возможно возникновение следующей ошибки Ресурс уже использует URI Пожалуйста, введите уникальный псевдоним или используйте «Заморозить URI», чтобы вручную заменить его. Для устранения необходимо зайти в системный настройки далее ищем настройку "Проверять на дублирование URI во всех контекстах" (global_duplicate_uri_check) и переключаем его на Нет

Новое в блоге

Бесплатный хостинг!
tsumbaluk.in.ua || 29.06.2017

Бесплатный хостинг!

e2e тестирование приложений. Используя Protractor
tsumbaluk.in.ua || 30.04.2017

e2e тестирование приложений. Используя Protractor

Node package manager publish package
tsumbaluk.in.ua || 11.02.2017

Node package manager publish package

Modx перенос на сервер или туда и обратно
tsumbaluk.in.ua || 01.11.2016

Modx перенос на сервер или туда и обратно

Gulp инструмент для удобной и быстрой front-end разработки!
tsumbaluk.in.ua || 05.10.2016

Gulp инструмент для удобной и быстрой front-end разработки!

Как определить страну и город по IP адресу, javascript?
tsumbaluk.in.ua || 05.10.2016

Как определить страну и город по IP адресу, javascript?