Николай Ланец
31 мар. 2013 г., 16:08

Мультиязычность на сайте MODX-клуба

Specialy for Mark Hamstra на сайте я ввел сегодня мультиязычность, добавив для начала английский язык, но в дальнейшем можно будет добавить и другие языки.
Напомню, Марк — один из команды MODX, человеку, которому мы обязаны появлением во всех отношениях «классных» процессоров. Марк — очень позитивный человек и охотно идет на контакт, плюс к этому обладает отличными техническими знаниями. Думаю, будет правильно, чтобы хотя бы переводом основных пунктов меню и кнопок, мы облегчили ему процесс общения на нашем сайте. Ждем сегодня Марка на сайте :-) И будем надеяться, вслед за ним придут и другие мировые MODX-специалисты. По технической реализации (наверняка многим будет интересно, ведь мультиязычность — далеко не закрытый вопрос для MODX-еров).
На этом сайте используется modLivestreet (то есть связка MODX+Livestreet), потому практически для всего есть русский и английский словари. Остается только передать в конфиг текущий cultureKey. Для этого в stable-конфиг Livestreet пишем следующее:
switch($modx->getOption('cultureKey')){ case 'en': $config['lang']['current'] = 'english'; break; default:; }
Но теперь надо обеспечить постоянно актуальный и индивидуальный cultureKey, так как как наверняка многие заметили, у нас нет здесь уникальных УРЛ-ов типа en/ и т.п., есть только адрес смены языка ?cultureKey=ru/en. На днях я как-то ковырял механизм MODX-а по словарям, и нашел такой интересный кусочек кода в классе MODx:
protected function _initCulture($options = null) { $cultureKey = $this->getOption('cultureKey', $options, 'en'); if (!empty($_SESSION['cultureKey'])) $cultureKey = $_SESSION['cultureKey']; if (!empty($_REQUEST['cultureKey'])) $cultureKey = $_REQUEST['cultureKey']; $this->cultureKey = $cultureKey; if ($this->getOption('setlocale', $options, true)) { $locale = setlocale(LC_ALL, null); setlocale(LC_ALL, $this->getOption('locale', null, $locale)); } $this->getService('lexicon', $this->getOption('lexicon_class', $options, 'modLexicon'), '', is_array($options) ? $options : array()); $this->invokeEvent('OnInitCulture'); }
Что здесь примечательного? Как видим, MODX устанавливает значение переменной $this->cultureKey = $cultureKey, которое берет из массива $_SESSION или $_REQUEST. То есть эту переменную всегда можно перегрузить, просто отправив тот же GET-запрос cultureKEy=lang. Но что еще более интересно, то что эта переменная не используется больше нигде))) (только в одном системном процессоре). А $modx->config->cultureKey по прежнему берется из системных настроек. Но это все равно не мешает нам ее использовать в тех же плагинах. Я создал плагин на событие OnHandleRequest и написал:
<?php if($modx->context->key == "mgr"){return;} if(!empty($_REQUEST['cultureKey']) AND in_array($_REQUEST['cultureKey'], array('ru', 'en'))){ $_SESSION['cultureKey'] = $_REQUEST['cultureKey']; } $modx->setOption('cultureKey', $modx->cultureKey); $modx->setOption('cache_prefix', "cache_{$modx->cultureKey}");
То есть этот плагин каждый раз устанавливает актуальный cultureKey исходя из значения $modx->cultureKey. Плюс к этому смотрит, если передан языковой идентификатор, то пишет его в сессию.
UPD: Обновил код плагина, так как надо было учесть кеширование документов, поэтому в плагин добавил смену кеш-префикса.
спасибо. перерыл много чего, но ответ нашел только здесь.

Добавить комментарий