Второй способ создания многоязычного сайта
В предыдущей статье описывалось создание многоязычного сайта с использованием отдельного шаблона для каждого языка. В некоторых случаях, например, при частых внесениях изменений в шаблоны, такой подход не слишком удобен, и в данной статье рассмотрен другой подход к разработке многоязычного сайта. Основные принципы остаются теми же, и мы не будем на них останавливаться, рассмотрев только отличия, возникающие при использовании одного шаблона для всех языков.
Основная идея заключается в том, чтобы добавить в шаблон специальные плэйсхолдеры, которые будут заменяться чанками в зависимости от используемого языка. Например, если в шаблоне встретится плэйсхолдер [+lang.menu+], то на русских страницах будет добавлено содержимое чанка ru-menu, а на английских – en-menu. В каждом чанке можно разместить код вызова меню для соответствующего языка. При этом названия плэйсхолдеров жестко не закреплены, но они должны начинаться с префикса lang и точки, которые заменяются на две буквы языка и дефис в названии соответствующих чанков.
Плагин для обработки плэйсхолдеров
Для реализации замены нужных плэйсхолдеров требуется создать новый плагин, поместить в него приведенный ниже код, после чего связать данный плагин с событием OnParseDocument. При генерации каждого документа системой MODx будет выполняться поиск нужных плэйсхолдеров и их замена. Для работы на конкретном сайте нужно настроить плагин, введя номера главных страниц для каждого языка и соответствующие префиксы чанков (в примере 2 и ru– для русского, 3 и en– для английского языка, а также 0 и пустой префикс для многоязычных страниц,).
$e = &$modx->Event; if ($e->name == 'OnParseDocument') { $langPrefix = array(0=>"", 2=>"ru-", 3=>"en-"); if ($modx->documentObject['parent']=='0') { $lang=0; } else { $lang=$modx->documentIdentifier; do { foreach ($modx->documentMap as $mapEntry) { $parentId=array_search($lang, $mapEntry); if ($parentId) break; } if ($parentId) $lang=$parentId; } while ($parentId); } if ( preg_match_all("~\[\+lang\.(.*)\+\]~U", $modx->documentOutput, $matches)) { foreach ($matches[1] as $placeholder) { $modx->setPlaceholder('lang.'.$placeholder, $modx->getChunk( $langPrefix[$lang].$placeholder)); } } }
Вначале в плагине определяется родитель верхнего уровня, то есть то, к какому языку относится страница, после чего находятся все плэйсхолдеры с нужными названиями и выполняется замена их содержимым соответствующих чанков. Никаких ограничений на названия и количество плэйсхолдеров и чанков не накладывается.
Изменения в используемых сниппетах
Так как теперь отсутствуют уникальные шаблоны для каждого языка, в сниппет переключения языков, описанный в прошлой статье, необходимо внести изменения. Для определения того, к какому языку относится текущая страница, нужно выполнить немного более сложные действия.
<?php $mainurl["ru"] = $modx->makeURL(4); $mainurl["en"] = $modx->makeURL(7); $baseurl=$modx->config["base_url"]; $langId["ru"] = 2; $langId["en"] = 3; if ($modx->documentObject['parent']=='0') { $lang=0; } else { $lang=$modx->documentIdentifier; do { foreach ($modx->documentMap as $mapEntry) { $parentId= array_search($lang, $mapEntry); if ($parentId) break; } if ($parentId) $lang=$parentId; } while ($parentId); } function BaseReplace ($baseurl, $url) { global $modx; $url = str_replace( $modx->config['friendly_url_suffix'], "", $url); if ($baseurl == "/") return substr ($url, 1); else return str_replace ($baseurl, "", $url); } switch ($lang) { case $langId["ru"]: $output='<a href="'; $url = str_replace ("/ru/", "/en/", $modx->makeURL($modx->documentIdentifier)); if (array_key_exists(BaseReplace ($baseurl,$url), $modx->documentListing)) $output.=$url; else $output.=$mainurl["en"]; $output.='" title="English" >in English</a>'; break; case $langId["en"]: $output='<a href="'; $url = str_replace ("/en/", "/ru/", $modx->makeURL($modx->documentIdentifier)); if (array_key_exists(BaseReplace ($baseurl,$url), $modx->documentListing)) $output.=$url; else $output.=$mainurl["ru"]; $output.='" title="по-русски" >по-русски</a>'; break; } return $output; ?>
После создания необходимых плагина, шаблона, сниппета и множества чанков можно приступать к созданию документов для каждого языка.