Существует довольно много способов локализации XSLT-шаблонов, некоторые способы описаны студией Лебедева, но сегодня я расскажу о локализации с помощью сущностей.
C начала о том, что же такое «сущности», не углубляясь в DTD. Сущности — это своеобразные константы в XML-документе, описываемые с помощью DTD, и используемые в качестве сокращений. Примером такой замены могут служить буквенные обозначения символов, не присутствующих на стандартной раскладке клавиатуры (©, ®, ₤ и т.д.). Сущности описываются следующим образом:
Или более полное описание для XSLT:
В XML-таблице сущности подставляются так: &имя-cущности;
В качестве примера приведу описание всем известной сущности nbsp (неразрывный пробел):
Посмотреть на многие «стандартные» сущности можно в DTD HTML: www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
Если для (X)HTML все сущности спец-символов описаны по умолчанию, то для XST определены только три сущности: amp (&), lt (<) и gt (>). Если же Вы захотите использовать nbsp, то придется либо воспользоваться готовой таблицей, с описанием спец-символов, либо описывать сущность самому.
Теперь давайте попробуем сделать простейшую локализацию для XSLT-шаблона, используя сущности:
Результат, думаю, очевиден. Но в этом примере есть один большой недостаток: при смене языка нам надо заменять все сущности во всех шаблонах, а значит толку от такой локализации мало. Теперь предположим, что сайт у нас небольшой, и все языковые константы можно собрать в одном месте. Пускай этим местом будет файл lang.dtd, где описаны только «языковые» сущности. Вот пример такого DTD-файла:
Теперь дело за малым — подключить этот файл в XSLT-шаблон:
Последний вариант уже довольно рабочий; чтобы сменить язык, достаточно заменить всего-лишь один файл. Но в некоторых случаях этого все-равно недостаточно.
Допустим, что у нас есть CMS, где все языковые файлы представленны в виде массивов или вообще находятся в БД. Самым простым способом связать системную локализацию и XSLT-шаблоны — автоматически генерировать DTD-файлы с «языковыми» сущностями. Вариант, конечно, не самый плохой, но есть немного другой — генерировать DTD «на лету». Это дает два преимущества: во-первых, больше нет необходимости обновления языковых DTD-файлов, при внесении изменений в локализацию; во-вторых, мы можем легко менять локализацию, отдавая языковые сущности того языка, который установлен CMS.
Допустим, что мы написали скрипт, который отдает контент, как в файле lang.dtd, подключим его в XSLT-шаблоне:
Здесь возникает проблема, которую, казалось бы, решить никак — привязка к домену. Но если наша CMS написана на PHP (за другие языки не отвечаю), то отчаиваться рано :)
В PHP, начиная с версии 4.3, можно реализовывать свои протоколы. Например можно реализовать поддержку протокола file (file://) или любого другого. За реализацию пользовательских протоколов отвечает разработчик. Подробно останавливаться на этом не буду, т.к. это уже другая тема. Прочитать про реализацию своих протоколов можно в документации к PHP здесь, а посмотреть готовый пример можно в SVN моего проекта здесь.
Теперь применим это в XSLT. Реализуем протокол, например, lang и исправим шаблон:
ENTITY
C начала о том, что же такое «сущности», не углубляясь в DTD. Сущности — это своеобразные константы в XML-документе, описываемые с помощью DTD, и используемые в качестве сокращений. Примером такой замены могут служить буквенные обозначения символов, не присутствующих на стандартной раскладке клавиатуры (©, ®, ₤ и т.д.). Сущности описываются следующим образом:
<!ENTITY имя-сущности "значение-сущности">
Или более полное описание для XSLT:
<!DOCTYPE xsl:stylesheet [
<!ENTITY имя-сущности "значение-сущности">
]>
* This source code was highlighted with Source Code Highlighter.
В XML-таблице сущности подставляются так: &имя-cущности;
В качестве примера приведу описание всем известной сущности nbsp (неразрывный пробел):
<!ENTITY nbsp "&#160;">
Посмотреть на многие «стандартные» сущности можно в DTD HTML: www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
Если для (X)HTML все сущности спец-символов описаны по умолчанию, то для XST определены только три сущности: amp (&amp;), lt (&lt;) и gt (&gt;). Если же Вы захотите использовать nbsp, то придется либо воспользоваться готовой таблицей, с описанием спец-символов, либо описывать сущность самому.
Локализация (начало)
Теперь давайте попробуем сделать простейшую локализацию для XSLT-шаблона, используя сущности:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY labelHello "Привет, мир!">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="xml" />
<xsl:template match="/">
<xsl:text>&labelHello;</xsl:text>
</xsl:template>
</xsl:stylesheet>
* This source code was highlighted with Source Code Highlighter.
Результат, думаю, очевиден. Но в этом примере есть один большой недостаток: при смене языка нам надо заменять все сущности во всех шаблонах, а значит толку от такой локализации мало. Теперь предположим, что сайт у нас небольшой, и все языковые константы можно собрать в одном месте. Пускай этим местом будет файл lang.dtd, где описаны только «языковые» сущности. Вот пример такого DTD-файла:
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY labelHello "Привет, мир!">
<!ENTITY labelLogin "Авторизоваться">
<!ENTITY labelRegister "зарегистрироваться">
* This source code was highlighted with Source Code Highlighter.
Теперь дело за малым — подключить этот файл в XSLT-шаблон:
<!DOCTYPE xsl:stylesheet SYSTEM "lang.dtd">
* This source code was highlighted with Source Code Highlighter.
Последний вариант уже довольно рабочий; чтобы сменить язык, достаточно заменить всего-лишь один файл. Но в некоторых случаях этого все-равно недостаточно.
Локализация на уровне CMS
Допустим, что у нас есть CMS, где все языковые файлы представленны в виде массивов или вообще находятся в БД. Самым простым способом связать системную локализацию и XSLT-шаблоны — автоматически генерировать DTD-файлы с «языковыми» сущностями. Вариант, конечно, не самый плохой, но есть немного другой — генерировать DTD «на лету». Это дает два преимущества: во-первых, больше нет необходимости обновления языковых DTD-файлов, при внесении изменений в локализацию; во-вторых, мы можем легко менять локализацию, отдавая языковые сущности того языка, который установлен CMS.
Допустим, что мы написали скрипт, который отдает контент, как в файле lang.dtd, подключим его в XSLT-шаблоне:
<!DOCTYPE xsl:stylesheet SYSTEM "http://localhost/lang.php">
* This source code was highlighted with Source Code Highlighter.
Здесь возникает проблема, которую, казалось бы, решить никак — привязка к домену. Но если наша CMS написана на PHP (за другие языки не отвечаю), то отчаиваться рано :)
В PHP, начиная с версии 4.3, можно реализовывать свои протоколы. Например можно реализовать поддержку протокола file (file://) или любого другого. За реализацию пользовательских протоколов отвечает разработчик. Подробно останавливаться на этом не буду, т.к. это уже другая тема. Прочитать про реализацию своих протоколов можно в документации к PHP здесь, а посмотреть готовый пример можно в SVN моего проекта здесь.
Теперь применим это в XSLT. Реализуем протокол, например, lang и исправим шаблон:
<!DOCTYPE xsl:stylesheet SYSTEM "lang://modulename">
* This source code was highlighted with Source Code Highlighter.