Fi1osof 31 марта 2013 0 2
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: Обновил код плагина, так как надо было учесть кеширование документов, поэтому в плагин добавил смену кеш-префикса.
2 комментария
den991
den99 03 июля 2013г в 15:52 #
спасибо. перерыл много чего, но ответ нашел только здесь.
Fi1osof1
Fi1osof 03 июля 2013г в 23:27 #
Пожалуйста.
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.