'

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

Понравилась презентация – покажи это...





Слайд 0

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


Слайд 1

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


Слайд 2

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


Слайд 3

Самый простой вариант подключения 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'); }


Слайд 4

Создаем файл переводов для русского языка Структура каталога languages: ./application/languages/ `-- ru `-- application.php Файл переводов: ./application/languages/ru/application.php <?php return array( 'Hello' => 'Привет', ); Результат: Привет


Слайд 5

Почему ”Привет”, а не ”Hello”? Потому что в моих настройках браузера русский язык по приоритету выше английского:


Слайд 6

Отдельные можно выводить сообщения на указанном языке Для этого нужно указать язык или локаль в последнем аргументе view хелпера translate(): ./application/controllers/IndexController.php public function indexAction() { echo $this->view->translate('Hello', 'en_GB'); // или echo $this->view->translate('Hello', 'en'); } Результат: Hello Эту возможность удобно использовать при формировании текстов для многоязычной рассылки.


Слайд 7

Plural 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'); }


Слайд 8

Plural Forms (продолжение) Обновим файл переводов для русского языка: ./application/languages/ru/application.php <?php return array( 'Hello' => 'Привет', 'left before the conference' => 'осталось до начала конференции', '%s day' => array( '%s день', '%s дня', '%s дней' ) ); Результат: Привет! 5 дней осталось до начала конференции


Слайд 9

Почему я отдаю предпочтение gettext? В коде отображаются оригиналы сообщений. Пример сообщения в view шаблоне: <h2><?php echo $this->translate('Create new brand'); ?>:</h2> Не нужно искать где и какие строки были добавлены или удалены в исходном коде — gettext сам найдет все изменения. Есть готовые программы для работы с файлами переводов (особенно актуально для НЕпрограммистов). Достаточно предоставить заказчику или перводчику .po файл и программу для его редактирования (например кроссплатформенная Poedit).


Слайд 10

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


Слайд 11

Работаем с 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)


Слайд 12

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


Слайд 13

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


Слайд 14

Для чего я добавил plural:1,2? Я не знаю как заставить парсер xgettext доставать строки из такой конструкции: $this->view->translate(array('%s day', '%s days', $count) Но он успешно достает их из конструкции вида: $this->view->translate()->getTranslator()->plural('%s day', '%s days', $count)


Слайд 15

Работаем с Poedit. Обновляем каталог из исходных файлов Сохраняем каталог ./application/languages/ru/application.po И обовляем его Каталог>Обновить из исходного кода Получаем следующую картину:


Слайд 16

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


Слайд 17

Ньюансы и хаки для работы с 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', )


Слайд 18

Перевод сообщений валидаторов для адаптеров != array Раньше мы делали отдельный файлик, который содержал все сообщения валидаторов обернутые в _(): _("A record matching \"%value%\" was found"); _("Password and confirmed password do not match."); xgettext этот файл парсил, а мы переводили и компилировали .mo файл, который уже подключали ко всем проектам. Теперь в ZF появилась папочка resources, в которой лежат переводы сообщений валидаторов. Но как ихподключить если для основного сайта используется адаптер отличный от array я пока не разобрался. Думаю, что вскоре разберусь и решение будет опубликовано на сайте или форуме http://zendframework.ru


Слайд 19

Перевод сообщений валидаторов для адаптера 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; }


Слайд 20

Варианты передачи языка в 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/ – английский


Слайд 21

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


Слайд 22

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


Слайд 23

Несколько строчек кода, которые делают приложение быстрее :) Если есть возможность что-то закешировать, значит нужно её использовать: $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);


Слайд 24

The end ? Благодарю за внимание! Задавайте ваши вопросы ;) Степан Танасийчук ceo@stfalcon.com


×

HTML:





Ссылка: