---
title: Многоязычность Smarty
date: 2007-03-31T15:22
tags: [go, php, tech]
---

Многоязычность сайта - важный фактор для корпоративных сайтов. Какие существуют подходы?

1. Разные языки - разные сайты. Такое решение очень простое и используется для международных фирм. Каждый регион владеет своим доменом, хостинг как правило делается на одном защищённом сервере, где все данные доступны для всех доменов, либо же раздельно, что в принципе не играет большой роли, главное то - что платформа под каждый язык своя.
2. Разные языки - разные темплейты. Решение так же простое - для каждого языка свой темплейт. Контроллер всё же один и сам выбирает какие данные из БД выбирать. Большой минус в том, что при изменении дизайна, надо менять темплейты во всех языках, поэтому может случится что языки с разными дизайнами.
3. Разные языки - разные данные. Неудобен тем, что для каждой мелкой системной надписи надо лезть и добавлять строчки переводов. Кроме того возникают вопросы при составлении структур типа дерева - зависит ли структура от языка или нет. Например при составлении каталога продуктов, в случае если необходимо добавить новый язык, надо отдельно составлять всю структуру, или достаточно перевести уже созданную?

<!-- truncate -->

Кодировка Web2.0 - UTF-8 потому, что база данных умеет сортировать правильно и не возникает проблем когда на одной и той же странице пишут и по-русски и скажем по-японски. Кроме разделения по языкам, корпоративные сайты часто устанавливают зависимость каталога продуктов от стран. Напомню, что язык и страна - разные понятия и если каталог достаточно нужный, то для одной и той же страны он может быть на нескольких (государственных) языках. Типичный пример - Швейцария.

### Темплейты

Рассмотрим последний вариант подробней. Каждое слово в такой системе нуждается в переводе. Как связать данные с кодом? Можно через ID - пишем в коде номер, но такой код трудно читать. Через key более приятно, но возникает заминка с уникальностью ключей. Можно сделать обязательным один из языков и сразу писать скажем по-английски в коде. Но тогда возникает трудность с изменением слово на английском.

К делу! Создаём в БД таблицу

|   |   |   |   |   |
|---|---|---|---|---|
|ID|template|key|English|Russian|
|1|index|word|Word|Слово|

### Smarty блок функция

После инициализации smarty объекта создаём новую функцию

`$objSmarty->register_block('t', 'fnTranslate');      //для примера - беру языки из готового массива   $arrTranslations['rus']=array('red'=>'красное', 'black'=>'чёрное');   $arrTranslations['est']=array('red'=>'punane', 'black'=>'must');      function fnTranslate($params,$content, &$objSmarty,&$repeat){   global $arrTranslations;   return $arrTranslations['rus'][$content]; //надо прописать выбранный язык в сессию   }`

В темплейте использовать соответсвенно надо:

`{t}red{/t}`

В функцию fnTranslate передаются автоматически четыре параметра - `$parameters`, `$content`, `&$objSmarty`, `&$repeat`. Переводы можно либо связать с конкретным темплейт-файлов, воспользовавшись

`$objSmarty->_tpl_vars['strContentTemplate']`

Другой вариант - связывать с некоим системным модулем, но это уже зависит от архитектуры. Но помните, что завязка с модулем означает не только удобство по экспорту/импорту переводов в xml/csv/gz но и ограничивает использование переводов одних и тех же фраз из разных модулей.

Независимо от модульности существует и проблема слежения за использованием переводов - у программиста нет времени стирать ненужные переводы, а web-мастер желающий добавить автоматически язык понятия не имеет под каким модулем/ключевым словом находится нужный перевод. Часто изобретают велосипед и называют переводы типа GalleryHeaderNavigationFind, т.е. указывают нахождение в интерфейсе.

### Smarty prefilter

Кроме блоков, вызывающихся каждый раз из компилированного файла, можно также использовать [prefilter](http://www.smarty.net/manual/en/api.register.prefilter.php), который запускается один раз при компиляции и заменяет обозначенные области. Проблема этого подхода в том, что при переключении языков фактически переводы меняться не будут. С другой стороны такие фильтры позволяют использовать переменные в таких статических "переводах". Как решение проблемы, можно компилировать несколько файлов в зависимости от языка (с разными префиксами или в разных папках). Конечно при большом количестве языков (>20) рост числа файлов будет геометрический.

#### Стандарты

При создании таблиц языков, стран и зависимостей других объектов (статей, продуктов и тп) надо использовать индексы. Я советую использовать в качестве primary-ключей не нумерацию, а ISO-коды как для [языков](http://www.loc.gov/standards/iso639-2/php/code_list.php), так и для [стран](http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm) - это упростит понимание данных в будующем.

## Related

- [Crontab](/ru/blog/tech/server/vagrant/)
- [Google AI challenge - стратегии ботов](/ru/blog/tech/google-ai-challenge-strategii-botov/)
- [Phonegap приложение](/ru/blog/tech/phonegap-prilozhenie-s-angularjs/)
