пятница, 13 ноября 2009 г.

Поддержка языков в системе. Часть 1.

Система Управления Контентом, в любом случае должна поддерживать работу в режиме -- множество языковых версий сайта.
Описываемая мной система также должна поддерживать работу нескольких локализаций.
Не так давно, на форуме русского сообщества CodeIgniter обсуждалось, Как организовать поддержку нескольких языков на сайте? Там этот вопрос рассматривался в контексте одного веб-приложения нас же интересует Как организовать поддержку нескольких языков для Системы Управления Контентом? На мой взгляд, это несколько другой уровень вопроса, хотя и не на много более сложный, как окажется при детальном рассмотрении.



Если дело касается статических мест на сайте, например, названия полей формы регистрации, то здесь все довольно просто. Если рассматривать генерацию страницы в середине рабочего цикла движка, то вся задача решается языковыми файлами на разных языках и функцию...
Чаще всего для этого используют функцию с коротким именем. Например в CodeIgniter это функцияlang() -- принимающая первым параметром имя строки (чаще всего -- сокращение записанное на английском языке). В CMS Drupal для этого есть функция _t,которая принимает всю строку, какой её нужно показать если используется язык по умолчанию.

Я бы модифицировал такую функцию следующим образом -- вторым параметром передавать строку на родном языке, что бы в случае отсутствия (забыли определить строку) вывести строку по умолчанию.

Но это то что касается вывода строк для стандартных форм или заголовков на сайте. Когда язык уже определен, остается только загрузить требуемый язык (а следовательно и нужные файлы со строковыми наборами) и предоставить возможность их использовать.

Языковые файлы лучше хранить в различных папках, где каждая папка, это отдельный язык. При этом, каждая папка должна иметь строго совпадающий набор файлов (совпадающий по имени файла). Формат файла, остается на усмотрение разработчика. Это может быть как файл формата ini, где можно даже организовать группировку строк по некому признаку. Например так:

[registration]
name="Имя"
sname="Фамилия"
....
[search]
query="Что ищем?"


Это дает возможность иметь подмножества строк. Такой механизм, если я не ошибаюсь, предлагает Zend Framework.

Другой, возможно, менее удобный, но быстрее работающий - это php-файлы.


   $lang['reg_name'] = 'Имя';
   $lang['reg_sname'] = 'Фамилия';
//или деление на группы
   $lang['registration_form'] = array(
         'name' => 'Имя',
         'sname' => 'Фамилия'
    );


Такой код будет обработан быстрее чем ini-файл (хотя это нужно проверять тестами).

У ini-файлов есть еще одно преимущество - простота обработки, в том числе и программной. Т.е. не составит труда встроить в админку сайта механизм правки и расширения таких языковых файлов, хотя вполне возможно и написание механизма правки php-кода.

Так же, можно рассмотреть и множество других форматов хранения таких строк. Это может быть и XML, но в данном случае, я считаю, что это слишком "дорогой" формат для таких целей.
Если Вас по каким-то причинам не устраивают предложенные форматы, то стоит обратить внимание в сторону YAML -- красивый и читаемый формат.

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

Ядро


При разработке Системы Управления контентом, так же важно оставить поддержку работы системы при отключении многоязычности. Т.е. когда сайт делается исключительно для аудитории одного языка, нет нужды в функционале многоязычности. Из этого следует, что Система должна уметь работать в двух режимах:
  1. Поддержка языков включена.
    Сайт имеет контент на нескольких языках, стандартные формы сайта используют языковые функции для оформления универсальных форм, когда, например, имена полей зависят от выбранного пользователем языка. Ссылки сайта всегда имеют определения выбранного пользователем языка.
  2. Сайт имеет единственный язык.
    В шаблонах можно смело использовать текст на конкретном, единственном языке. Ссылки сайта лишены указания языка.
Тут следует подробно остановиться на каждом варианте, т.к. они не разрывно связаны.

Поддержка мультиязычности в ядре, это одно из двух исключений в стиле Ядро -- только запускает модули. Именно ядро определяет текущий "заказанный" пользователем язык.
То КАК это делает ядро CMS -- это уже интересный вопрос.

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

Хранить язык в cookies браузера
Очевидный плюс -- язык не мешается в урле, пользователь видит контент на нужном ему языке.
Потенциальные минусы -- Если сайт является информационным, то продвигать в поисковиках нужно контент на всех языках, но поисковики не используют cookies, следовательно, они увидят контент исключительно на языке по-умолчанию. Второй минус - пользователь нашел интересный контент, отправляет другу ссылку на него, но у друга нет cookie на нужный язык и он попадает на, возможно, 404ю ошибку, т.к. такого документа в языке по-умолчанию просто нет или же ему нужно переключить язык на нужный -- лишний переход, следовательно, это неудобно.

Определять User Agent у браузера с целью выяснить язык посетителя
Этот параметр слишком легко подменить -- это главный минус. Но при этом, эту идею нельзя сбрасывать со счетов. Таким образом можно предположить, какой язык показать пользователю на главной странице.

Размещать язык в строке адреса как один из параметров (сегментов адреса)
Для меня -- это лучший способ. Если размещать 2 буквы алиаса языка в строке адреса, то это решает проблему с отправкой ссылки другому человеку, поисковики будут индексировать параллельно несколько версий сайта.
Именно этот способ я и буду использовать в дальнейшем.

Место для параметра языка в строке адреса страницы сайта
Вероятно, имеется всего 2 варианта, если не используются GET параметры (т.е. используется сегментный (или путевой) формат строки адреса) -- в начале и в конце.
Размещать сегмент языка в середине строки адреса лишено смысла (исключение -- админ-понель, но о ней позже) т.к. будет трудно выделять его в общем списке сегментов.
Я рекомендовал бы размещать его в начале строки. Но это дело вкуса, да и возможно сделать этот момент настраиваемым.

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

Комментариев нет: