Kohana 3.2: организация мультиязычности

от автора

На моём сайте в определенный момент очень остро встал вопрос организации мультиязычности, причём речь шла не о 2-3 языках, а о том, чтобы перевод сайта на другой, абсолютно любой язык мог быть осуществлен за считанные минуты. Информации в сети на эту тему не так много(может я плохо искал?) и мне пришлось думать самому. Хотя моё решение довольно простое и многим может показаться очевидным, я всё равно приведу его, надеюсь кому-нибудь оно будет полезно. Сразу предупреждаю, что необходимо мало-мальское представление о фреймворке kohana 3.

Итак, какие вообще могут быть варианты организации мультиязычности на сайте? Самый простой и очевидный вариант, это создание для каждого языка папки «ru», «en» и т.п. Но это значило бы копирование всех файлов, а если поменяли что-то, меняем во всех 30 папках… О ужас, развивать эту тему может только мазохист, поэтому, естественно, я стал искать другой путь, который бы позволил менять только языковые файлы с переводом.

Очевидно, что необходимо было ввести в роутинг параметр lang, который бы шёл в начале каждого правила:

Route::set('auth', '<lang>/<action>(/<param>)', array('action' => 'login|logout|registration|forgot|start')) 	->defaults(array(                 'directory'  => 'index', 		'controller' => 'auth', 	)); 	 Route::set('static', '<lang>/<action>(/<uri>)', array('action' => 'page|blog|news|forms|polls')) 	->defaults(array(                 'directory'  => 'index',                 'controller' => 'static',                 'action' => 'page', 	));   	 Route::set('default', '(<lang>(/<controller>(/<action>(/<param>))))', array('param' => '.+')) 	->defaults(array( 	        'directory' => 'index', 		'controller' => 'static', 		'action'     => 'index',                 'lang'        => 'ru' 	)); 

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

В основном контроллере в методе before (может это же лучше делать в bootstrap?) я определил константу LANG:

if ( !defined('LANG') ) {        define('LANG', $this->lang()); }  // какой язык в адресе? $lang_uri = $this->request->param('lang');  // если не совпадает перенаправляем if ( $lang_uri != LANG ) {      $this->request->redirect(LANG); }  // подключаем файл перевода  i18n::lang(LANG . '-' . $this->request->controller()); 

В методе lang я определяю язык пользователя по кукам или ip пользователя. Файл перевода лежит в папке application/i18n/LANG/controller_name.php. Я дробил перевод по контроллерам, можно это сделать по экшенам или вообще всё засунуть в один файл, это уж как вашей душе и потребностям проекта угодно.

Остается только переопределить метод helper’а HTML anchor. Для этого я создал в папке classes файл html с содержимым:

<?php defined('SYSPATH') or die('No direct script access.');  class HTML extends Kohana_HTML {  	public static function anchor($uri, $title = NULL, array $attributes = NULL, $protocol = NULL, $index = TRUE) 	{                 $uri = LANG . '/'. $uri;                                    return parent::anchor($uri, $title, array $attributes, $protocol, $index);         } } 

Я ВСЕГДА подаю в этот метод адрес без домена и начальной косой черты, если вы не всегда так делаете, то необходимо обработать входящий $uri правильным способом!

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/181832/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *