Oct 29 2008

Symfony: интернационализация (I18n) / часть 1 – введение

Category: Symfonyingvar @ 00:32

Начинаю цикл статей по организации мультиязычности в Symfony. Мультиязычность достигается с помощью интернационализации и локализации.

Часть 1.1: интернационализация (I18n) – введение

Немного теории (источник Википедия).

Интернационализа́ция (англ. internationalization) — процесс адаптации продукта, такого как программное или аппаратное обеспечение, к языковым и культурным особенностям региона (регионов), отличного от того, в котором разрабатывался продукт. В английском языке для слова «internationalization» принято сокращение «i18n». При этом число 18 означает количество пропущенных между «i» и «n» букв.

Локализа́ция (англ. localization) — перевод и адаптация элементов интерфейса, вспомогательных файлов и документации. В английском языке для слова «localization» иногда применяется сокращение «l10n». При этом число 10 означает количество пропущенных между «l» и «n» букв.

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

Хочу поделиться моим небольшим опытом и достигнутыми результатами упрощения организации работы с I18n в Symfony. Весь материал разбил на несколько частей.

Использовалась Symfony 1.1 и Propel 1.3.

Мои требования к интернационализации (I18n) для фреймворка:
1) Локализация интерфейса сайта
2) Интернационализации данных (новости, статьи, продукция,…)
3) Административная панель: редактирование локализации интерфейса
4) Административная панель: редактирование данных с учетом интернационализации
5) Простота использования, гибкость (возможность легко добавить новый язык), производительность
6) Работать с локализацией через БД (MySQL), в частности через PDO (Propel 1.3), используя открытый коннект к БД

Symfony практически «справляется» со всеми требованиями. Но для некоторых процессов пришлось кое-что изменить, доработать. Добился ли я выполнения поставленных задач? ДА!!!!!

По умолчанию доступен один язык, и его можно активировать через настройки: frontend/config/settings.yml

Листинг 1.1: настройка “культуры” по умолчанию

all:
  .settings:
    default_culture: ru_RU  # или uk_UA

Не забудьте сбросить кеш.

Формат записи (локали): uk_UA – язык и код страны.

Таким образом, мы говорим, какой профиль использовать для интернационализации.
Список всех профилей можно найти в ядре Symfony: /symfony-1.1/lib/i18n/data/

Теперь если использовать Helpers, которые работают с I18n (календарь, список стран, дата…) мы на выходе получим тексты не в английском языке по умолчанию, а в украинском.

Листинг 1.2: получение текущей “культуры”

$culture = $this->getUser()->getCulture();

 

Часть 1.2: организация итернационализации (I18n) контента в Symfony

Сначала расскажу, как организована интернационализация данных, а после вернемся к локализации интерфейса в других частях.

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

Листинг 1.3: схема таблицы “Статьи” (schema.yml)

propel:
  _attributes:          { package: lib.model.article }

  article:
    id:                 ~
    slug:               { type: varchar, size: 255, required: true }
    image_url:          { type: varchar, size: 255, required: true }
    title:              { type: varchar, size: 255, required: true }
    announce:           { type: text, required: true }
    full_text:          { type: text, required: true }
    created_at:         ~

Листинг 1.4: Маршрутизация (routing.yml):

article:
  url: /articles/:year/:month/:day/:slug
  param: { module: article, action: index }

Ссылка на статью имела бы следующий вид: http://tigor.com.ua/articles/2008/10/28/i18n_hello_world

Добавляем интернационализацию.

Листинг 1.4: Маршрутизация с поддержкой I18n (routing.yml)

article:
  url: /:sf_culture/articles/:year/:month/:day/:slug
  param: { module: article, action: index }
  requirements: { sf_culture: (?:ru|uk|en) }

Указываем к примеру 3-и языка: русский, украинский, английский. Если ввести что-то другое вместо языка, то страница будет не найдена, и получим код ошибки 404.

Теперь ссылка будет вот такая:
• http://tigor.com.ua/en/articles/2008/10/28/i18n_hello_world
• http://tigor.com.ua/ru/articles/2008/10/28/i18n_hello_world
• http://tigor.com.ua/uk/articles/2008/10/28/i18n_hello_world

Но контент все еще на одном языке. Делаем правки схемы.

Листинг 1.5: схема с поддержкой I18n (schema.yml)

propel:
  _attributes:          { package: lib.model.article }

  article:
    _attributes:        { phpName: Product, isI18N: true, i18nTable: article _i18n }
    id:                 ~
    slug:               { type: varchar, size: 255, required: true }
    image_url:          { type: varchar, size: 255, required: true }
    created_at:         ~

  article _i18n:
    id:                 { type: integer, required: true, primaryKey: true, foreignTable: article,
       foreignReference: id, onDelete: cascade, onUpdate: cascade }
    culture:            { isCulture: true, type: varchar, size: 7, required: true, primaryKey: true }
    title:              { type: varchar, size: 255, required: true }
    announce:           { type: text, required: true }
    full_text:          { type: text, required: true }

В Листинге 1.5 для таблицы article _i18n сознательно указаны id и culture, чтобы отобразить, что же Symfony вставляет при указании опции isI18N. Эти поля указывать не стоит, дабы не совершать ошибки. Но в исключительных это может понадобиться.

Листинг 1.6: Небольшие примеры работы с объектом Article

// Чтение данных
$article = ProductPeer::retrieveByPk(1);
$title = $article ->getTitle(); // По умолчанию испольщуется текущая культура, или переопределенная через машрутизацию
$title = $article ->getTitle(‘en’); // Явно указываем язык

// Изменение данных
$article = ProductPeer::retrieveByPk(1);
$article->setTitle(‘Мир во всем мире!’, ‘ru’);
$article->save();

Ссылки по теме:
Symfony: интернационализация (I18n) / часть 2 – редактирование данных в административной панели
Википедия: Интернационализация
Википедия: Локализация
Wikipedia: Internationalization_and_localization
The Definitive Guide to symfony: Chapter 13 – I18n And L10n

Tags: ,