Сообщение

Переводим названия пунктов меню Configuration

Об одном способе интернационализации меню Configuration


Для изменения языка отображения информации в Zen-Cart используется привычный способ подключения тех или иных наборов скриптов, содержащих переводы фраз в зависимости от выбранного языка.

Казалось бы, нет ничего проще. Знай-себе переводи фразы в соответствующих файлах и сайт "заговорит" нужным языком. Но, не все так хорошо, как кажется на первый взгляд. Так уж сложилось, что из этого правила выпадают несколько исключений. Одним из них является под-меню Configuration главного меню административной части. Названия пунктов этого меню хранятся в базе данных и не изменяются при переключении языка интерфейса. Даже, если перевести названия на нужный нам язык, то это будет только один-единственный язык и легко переключать переводы на разные языки все-равно не получится.

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

Раз у нас нет удобного способа повлиять на содержимое страницы во время ее генерации, давайте попробуем изменить его после того, как страница будет сгенерирована.

PHP позволяет буферизировать вывод перед отправкой его браузеру пользователя. Итак, наша первая задача - получить в буфере текст генерируемой страницы. Для этого мы должны получить управление до начала формирования страницы. Архитектура Zen-Cart позволяет сделать это очень удобным способом, не затрагивая при этом код ядра.

О том, как работает процедура инициализации, подробно описано в документации. Воспользуемся имеющимися у нас возможностями, чтобы получит управление на этапе инициализации системы. Для этого в каталог /admin/includes/auto_loaders/ поместим файл config.buffering.php следующего содержания:

<?php

  $autoLoadConfig[200][] = array('autoType' => 'init_script',
                                 'loadFile' => 'init_buffering.php');
  $autoLoadConfig[200][] = array('autoType' => 'class',
                                 'loadFile' => 'page_parser.php',
                                 'classPath' => DIR_WS_CLASSES);

В конфигурационный массив системы инициализации будут помещены указания:

  • выполнить скрипт /admin/includes/init_includes/init_buffering.php
  • выполнить скрипт /admin/includes/classes/page_parser.php

Код в init_buffering.php включает буферизацию вывода и определяет функцию, которая получит накопленный вывод по его завершении для последующей обработки.Вот его содержание:

<?php
ob_start('parsePage');

function parsePage($page) {
  global $configurationItem, $configurationTranslation;

  PageParser::translateConfigurationMenu($page, $configurationItem, $configurationTranslation);
  
  return $page;
}

По окончании формирования страницы накопленное в буфере содержимое будет передано функции parsePage. Эта функция вызывает статический метод translateConfigurationMenu класса PageParser, который и выполняет все необходимые преобразования. После преобразования содержимое буфера будет передано для дальнейшей обработки и возврата в браузер пользователя.

Пришло время поближе взглянуть на класс PageParser, который был объявлен при вызове кода в файле /admin/includes/classes/page_parser.php на этапе инициализации.

Код объявления класса PageParser:

<?php
class PageParser
{
  static function translateConfigurationMenu(&$page, $configurationItem = array(), $configurationTranslation = array())
  {
    $matches = array();
    preg_match_all('/<a(.*)gID=(\d*)">(.*)<\/a>/i', $page, $matches, PREG_OFFSET_CAPTURE);

    foreach ($matches[0] as $i => $item) {
      $gid = $matches[2][$i][0];

      if (isset($configurationTranslation[$gid])) {
        $item_name = $configurationTranslation[$gid];
        $pattern = '/<a(.*)gID=' . $gid .'">(.*)<\/a>/i';
        $replacement = '<a\\1gID=' . $gid . '">' . $item_name . '</a>';
        $page = preg_replace($pattern, $replacement, $page);
      }
    }
    
    if (isset($configurationItem['pattern']) && isset($configurationItem['replacement'])) {
      $page = preg_replace('/' . $configurationItem['pattern'] . '/', $configurationItem['replacement'], $page);
    }
  }
}

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

Метод имеет три входных параметра:

  • &$page - ссылка на переменную, хранящую текст страницы
  • $configurationItem - массив названий пунктов меню
  • $configurationTranslation - шаблон поиска и строка замены для перевода названия этого под-меню

$configurationItem и $configurationTranslation (в случае русского языка) определены в файле /admin/includes/languages/russian/extra_definitions/menu_configuration.php

Приводим содержимое этого файла

<?php

$configurationItem = array(
  'pattern' => '>Configuration<',
  'replacement' => '>Конфигурация<'
);

$configurationTranslation = array(
  1  => 'Мой магазин',
  2  => 'Минимальные значения',
  3  => 'Максимальные значения',
  4  => 'Изображения',
  5  => 'Сведения о покупателях',
  7  => 'Доставка/Упаковка',
  8  => 'Списки товаров',
  9  => 'Склад',
  10 => 'Журал',
  12 => 'Параметры e-mail',
  13 => 'Параметы атрибутов',
  14 => 'Сжатие GZip',
  15 => 'Сессии',
  11 => 'Регламент',
  16 => 'Подарочные купоны',
  17 => 'Кредитные карты',
  18 => 'Информация о товаре',
  19 => 'Настройки макета',
  20 => 'Техобслуживание',
  21 => 'Список новых',
  22 => 'Список рекомендуемых',
  23 => 'Список всех товаров',
  24 => 'Список на главной',
  25 => 'Параметры Define Page',
  30 => 'Параметры EZ-Pages'

);

В результате мы решили вопрос интернационализации названий пунктов меню "Конфигурация".

Заключительные замечания

Приведенный выше способ выглядит несколько искусственным. Но, такой подход позволяет менять некоторую функциональность системы, не изменяя ее кода. Это существенно облегчает процедуру обновления версий ядра и позволяет автоматизировать процедуру установки, обновления и удаления дополнений в Zen-Cart.

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


Joomla templates by a4joomla