Второй способ создания многоязычного сайта

В предыдущей статье описывалось создание многоязычного сайта с использованием отдельного шаблона для каждого языка. В некоторых случаях, например, при частых внесениях изменений в шаблоны, такой подход не слишком удобен, и в данной статье рассмотрен другой подход к разработке многоязычного сайта. Основные принципы остаются теми же, и мы не будем на них останавливаться, рассмотрев только отличия, возникающие при использовании одного шаблона для всех языков.

Основная идея заключается в том, чтобы добавить в шаблон специальные плэйсхолдеры, которые будут заменяться чанками в зависимости от используемого языка. Например, если в шаблоне встретится плэйсхолдер [+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;
?>

После создания необходимых плагина, шаблона, сниппета и множества чанков можно приступать к созданию документов для каждого языка.

 

Реклама

Поиск на сайте

Введите ваш запрос для начала поиска.