Zend Framework и мультиязычность Степан Танасийчук ceo@stfalcon.com презентация

Содержание

Чем я занимаюсь? Web разработкой занялся в 2003 году С Zend Framework начал работать в 2008 году Руковожу собственной веб-студией с 2009 года Активный участник сообщества zendframework.ru Люблю прикольные смайлы

Слайд 1
Zend Framework и мультиязычность

Степан Танасийчук
ceo@stfalcon.com
27 марта 2010 г.
Санкт-Петербург


Слайд 2Чем я занимаюсь?
Web разработкой занялся в 2003 году
С Zend Framework начал

работать в 2008 году
Руковожу собственной веб-студией с 2009 года
Активный участник сообщества zendframework.ru
Люблю прикольные смайлы :]

Слайд 3Содержание доклада
Простейшее подключение Zend_Translate
Работа с view хелпером translate
Plural forms или формы

множественного числа
Почему я отдаю предпочтение gettext?
Работаем с poedit
Хаки для работы с gettext
Перевод сообщений валидаторов
Сравнение различных схем передачи языка в URL
Zend_Translate и кеширование

Слайд 4Самый простой вариант подключения Zend_Translate
Добавляем в application.ini следующие настройки:
resources.translate.data = APPLICATION_PATH

"/languages"
resources.translate.adapter = "array"
resources.translate.locale = "auto"
resources.translate.options.scan = "directory"
resources.translate.options.disableNotices = true

Редактриуем IndexAction() в дефолтном контроллере:
./application/controllers/IndexController.php
public function indexAction()
{
echo $this->view->translate('Hello');
}

Слайд 5Создаем файл переводов для русского языка
Структура каталога languages:
./application/languages/
`-- ru
`--

application.php

Файл переводов:
./application/languages/ru/application.php
return array(
'Hello' => 'Привет',
);

Результат:
Привет

Слайд 6Почему ”Привет”, а не ”Hello”?
Потому что в моих настройках браузера русский

язык по приоритету выше английского:

Слайд 7Отдельные можно выводить сообщения на указанном языке
Для этого нужно указать язык

или локаль в последнем аргументе view хелпера translate():
./application/controllers/IndexController.php
public function indexAction() {
echo $this->view->translate('Hello', 'en_GB');
// или
echo $this->view->translate('Hello', 'en');
}

Результат:
Hello

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

Слайд 8Plural forms или формы множественного числа
Поддержка plural forms есть в адаптерах:
Array
Csv
Gettext

Разберем

на примере:
./application/controllers/IndexController.php
public function indexAction()
{
echo $this->view->translate('Hello') . '! ';
$count = 5;
echo sprintf($this->view->translate(array('%s day', '%s days', $count)), $count) . ' ' . $this->view->translate('left before the conference');
}

Слайд 9Plural Forms (продолжение)
Обновим файл переводов для русского языка:
./application/languages/ru/application.php

=> 'Привет',
'left before the conference' => 'осталось до начала конференции',
'%s day' => array(
'%s день',
'%s дня',
'%s дней'
)
);

Результат:
Привет! 5 дней осталось до начала конференции

Слайд 10Почему я отдаю предпочтение gettext?
В коде отображаются оригиналы сообщений. Пример сообщения

в view шаблоне:

translate('Create new brand'); ?>:



Не нужно искать где и какие строки были добавлены или удалены в исходном коде — gettext сам найдет все изменения.

Есть готовые программы для работы с файлами переводов (особенно актуально для НЕпрограммистов). Достаточно предоставить заказчику или перводчику .po файл и программу для его редактирования (например кроссплатформенная Poedit).

Слайд 11Работаем с poedit. Настройки каталога
Создаем новый каталог Файл→Создать каталог.
Указываем необходимые настройки:


Слайд 12Работаем с poedit. Настройка каталога (продолжение)
Обязательно указывайте формы множественного числа для

каждого перевода!
Полный список форм можно найти на странице http://translate.sourceforge.net/wiki/l10n/pluralforms
Например
для русского:
nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 or n%100>=20) ? 1 : 2)
для немецкого:
nplurals=2; plural=(n != 1)

Слайд 13Работаем с poedit. Пути
На вкладке «Пути» указываем путь к каталогу проекта

или пути к каталогам которые нужно сканировать:

Слайд 14Работаем poedit. Ключевые слова
Также добавляем названия функций, строковые аргументы которых должны

добавлятся в языковый файл (вкладка «Ключевые слова»):

Слайд 15Для чего я добавил plural:1,2?
Я не знаю как заставить парсер xgettext

доставать строки из такой конструкции:
$this->view->translate(array('%s day', '%s days', $count)

Но он успешно достает их из конструкции вида:
$this->view->translate()->getTranslator()->plural('%s day', '%s days', $count)

Слайд 16Работаем с Poedit. Обновляем каталог из исходных файлов
Сохраняем каталог ./application/languages/ru/application.po
И обовляем

его Каталог→Обновить из исходного кода
Получаем следующую картину:

Слайд 17Работаем с Poedit. Добавляем переводы и сохраняем каталог
Сохраняем результат. В параметрах

должна быть отмечена опция ”При сохранении автоматически компилировать файл .mo”.
В application.ini меняем адаптер на:
resources.translate.adapter = "gettext"
Запускаем:
Привет! 5 дней осталось до начала конференции

Слайд 18Ньюансы и хаки для работы с gettext
Лейблы формы нужно оборачивать в

_(). Пример:
$username = $form->createElement('text', 'username');
$username->setLabel(_('Имя пользователя'));
Только что подумал о том, что setLabel тоже можно добавить в ключевые слова :).

Та же ситуация с названиями пунктов меню для Zend_Navigation:
array(
'controller' => 'users',
'action' => 'list',
'resource' => 'mvc:users',
'privilege' => 'list',
'label' => _('Users'),
'route' => 'default',
)

Слайд 19Перевод сообщений валидаторов для адаптеров != array
Раньше мы делали отдельный файлик,

который содержал все сообщения валидаторов обернутые в _():
_("A record matching \"%value%\" was found");
_("Password and confirmed password do not match.");
xgettext этот файл парсил, а мы переводили и компилировали .mo файл, который уже подключали ко всем проектам.

Теперь в ZF появилась папочка resources, в которой лежат переводы сообщений валидаторов. Но как ихподключить если для основного сайта используется адаптер отличный от array я пока не разобрался. Думаю, что вскоре разберусь и решение будет опубликовано на сайте или форуме http://zendframework.ru

Слайд 20Перевод сообщений валидаторов для адаптера array
Для array все намного проще. Добавляем

в Bootstrap.php такой метод:

/**
* Init translator to Zend_Validate
* @return Zend_Translate
*/
public function _initZendValidateTranslator()
{
$this->bootstrap('translate');
$translate = $this->getResource('translate');
$translate->addTranslation(APPLICATION_PATH . '/../resources/languages');
return $translate;
}

Слайд 21Варианты передачи языка в URL
Язык на поддомене (Zend_Controller_Router_Route_Hostname):
en.wikipedia.org
ru.wikipedia.org
Язык в поддиректории:
1й вариант

(CyEngine_Controller_Router_Route_Multilingual):
mota.ru – русский
mota.ru/en/ – английский
2й вариант (переопределяем Zend_Controller_Router_Route):
preorder.it – ”auto” или по базе GeoIP
preorder.it/ru/ – русский
preorder.it/en/ – английский

Слайд 22Язык на поддомене +/-
+
Ускоренная индексация.
Для доменов первого уровня, которые не

имеют географической привязки можно настроить разные географические цели для каждой языковой версии сайта (в Google Webmaster Tools).
Вес с основного домена передается на поддомены.
Сайты можно разнести на разные сервера и делать независимые изменения в коде.
-
Бюджет на продвижение и эффект от него будет дробиться на все сайты.

Слайд 23Язык в поддиректории +/-
+
Достаточно просто реализовать в ZF.
Хорошо подходит для

сайтов-услуг.
Идет продвижения одного домена, т.е. тот же бюджет что и в первом варианте даст больший эффект.
-
Более медленная индексация.
Нельзя сделать разные географические цели для разных языковых версий сайта.
С технической стороны будет проблематично разнести разные языковые версии сайта на разные сервера.

Слайд 24Несколько строчек кода, которые делают приложение быстрее :)
Если есть возможность

что-то закешировать, значит нужно её использовать:

$cache = Zend_Cache::factory(
'Core',
'File',
array(
'caching' => true,
'automatic_serialization' => true,
'lifetime' => 3600,
),
array(
'cache_dir' => realpath(APPLICATION_PATH . '/../tmp'),
)
);

Zend_Translate::setCache($cache);

Слайд 25The end ☺



Благодарю за внимание!
Задавайте ваши вопросы ;)


Степан Танасийчук
ceo@stfalcon.com


Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

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


Для правообладателей

Яндекс.Метрика