Любая локализация сводится к формированию файлов-переводов. Эти файлы могут иметь различную структуру, но задача у них одна - хранение локализованных сообщений в виде словаря (ключ-значение). При попытке локализации той или иной части системы, требуется выполнить поиск локализованного значения по данному ключу, и если таковое будет найдено, использовать его в качестве замены.
Для начала рассмотрим простой пример GUI с использованием локализации:
В этом листинге представлена HTML разметка блока статьи (Article), использующая PHP переменные $title
и $content
для вставки конкретных значений заголовка и содержания. Далее будем называть такого рода данные Данными бизнес-модели. Они характеризуются тем, что отличаются для каждого объекта (для каждой статьи).
Блок article__date
использует текст Date create:
(дата создания) для описания своего содержимого. Назовем эти данные Метаданными бизнес-модели, так как они хоть и относятся к объекту (статье), но не разнятся от экземпляра к экземпляру. Другими словами можно сказать, что это данные класса (свойство класса dateCreate
), а не объекта бизнес-модели.
Блок так же дополнен ссылкой на комментарии читателей статьи Read comments
. Текст ссылки не относится к конкретному объекту или классу, а является Статикой интерфейса.
И так мы выделили три основные группы данных, нуждающихся в локализации, теперь рассмотрим подход к переводу и представлению каждой из них.
Локализация статики интерфейса
Статичная часть интерфейса поддается локализации проще всего. Достаточно сформировать файл перевода примерно следующего содержания:
Далее следует обернуть статику интерфейса в функцию-переводчик:
Остается только реализовать саму функцию tl
:
Логика функции довольно проста, она загружает словарь из файла перевода и ищет в нем перевод для данного сообщения. Если файл перевода не найден, или отсутствует перевод сообщения, функция возвращает исходный текст.
Локализация метаданных бизнес-модели
Для локализации метаданных классов, таких как их имена и имена их свойств, применяется контекстный перевод. Реализация его очень схожа с локализацией статики интерфейса с той лишь разницей, что поиск перевода осуществляется в заданном контексте. Для нашего примера контекстом будет являться класс Article
.
Рассмотрим пример:
Здесь Date create:
является локализованным на английский язык именем свойства Article::$dateCreate
. Скорее всего вы уже заметили, что наша функция tl
приняла второй необязательный параметр, содержащий имя класса. Этот параметр и задает контекст поиска локализации, в данном случае класс Article
.
Такая реализация позволяет не изменять логику перевода статики интерфейса и в то же время дополнить переводчик контекстным поиском. Достигается это за счет того, что аргумент $context
функции является не обязательным, и в случае передачи ему пустой строки или null
, поиск перевода сообщения будет производиться в глобальном контексте, где размещаются переводы статики интерфейса.
Остается добавить перевод в файл:
Локализация данных бизнес-модели
С локализацией данных дела обстоят сложнее. Дело в том, что объектов бизнес-модели множество, и все значения их свойств следует переводить и хранить в отдельных файлах. Одним из решений этой задачи является использование дополнительного, файлового (не обязательно) хранилища переводов. Оно имеет следующую структуру:
Как видно в хранилище для каждого объекта создается отдельный файл перевода, имя которого совпадает с идентификатором этого объекта. Это упрощает поиск файлов, что ускоряет работу самого переводчика.
Для систем с небольшим количеством объектов, таких как блоги и новостные ленты, созданием файлов локализации может заниматься сам автор, но более крупные системы, с сотнями или даже тысячами объектов, должны включать механизм автоматического создания этих файлов. Делается это за счет предоставления контент-менеджеру (через GUI) возможности переключения полей ввода контента на различные языки. При добавлении перевода, система должна автоматически создавать файл локализации объекта и сохранять в него этот перевод.
После реализации такой логики остается немного изменить нашу HTML разметку:
Обратите внимание на то, что в качестве контекста функции tl
передается не имя класса, а объект статьи. В этом случае переводчик должен использовать данный объект в качестве контекста и производить поиск перевода в соответствующем файле локализации объекта:
Функция tl
заметно усложнилась. Это вызвано тем, что ей необходимо подстраиваться под различные хранилища локализации (объектное и обычное). В том случае, если локализовать данные бизнес-модели переводчику не удается, он возвращает хранящиеся в целевом свойстве объекта данные.