Итак, какие вообще могут быть варианты организации мультиязычности на сайте? Самый простой и очевидный вариант, это создание для каждого языка папки «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/
Добавить комментарий