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

в 19:12, , рубрики: Kohana, kohana 3.2, php, мультиязычность, метки: , ,

На моём сайте в определенный момент очень остро встал вопрос организации мультиязычности, причём речь шла не о 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 правильным способом!

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

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

Автор: olegmar

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js