2008-02-07

Многоязычность в TWiki

Я использую ForUserLanguagesPlugin, который позволяет на одной странице держать и оригинальный текст, и переводы. Именно из-за этого я его и взял на вооружение, на мой вкус одна страница удобнее 10-ти, когда вносишь изменения оригинал и перевод перед глазами одновременно. Да, еще не надо дублировать всякие элементы, если они перевода не требуют (например, фото какого-нибудь hardware-оборудования).

Плугин довольно примитивен, и там есть пара недочетов. Первый - не работает инсталляционный скрипт. С этим все просто - руками рассовываем файлы по каталогам, ставим пермишены. Вторая проблема посложнее: при выборе языка плугин опирается на переменную LANGUAGE, которая сохраняется в сессии. В отсутствие таковой будет установлен дефолтовый английский (lib/TWiki/Plugins/ForUserLanguagesPlugin.pm, sub initPlugin):

$ul = TWiki::Func::getSessionValue( 'LANGUAGE' ) || 'en';


Но ведь хочется-то, чтобы было сразу на том языке, который нам понятен! Представьте себе ситуацию: заходите вы на wiki, там все по-анлгицки. Но справа вверху язык уже выбран - русский! Для того, чтобы получить русский вывод от этого плагина, надо переключиться на любой другой язык и обратно. Толко тогда getSessionValue( 'LANGUAGE' ) вернет 'ru'.

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

my $lang_det = TWiki::Func::getSessionValue( 'LANGUAGE' );

unless ($lang_det) {
my $accept_language = $ENV{HTTP_ACCEPT_LANGUAGE};

if ( $accept_language =~ /^\w+$/ ) {
$lang_det = $accept_language;
}
if ( $accept_language =~ /^\*$/ ) {
$lang_det = 'en';
}
if ( $accept_language =~ /,/ ) {
($lang_det) = $accept_language =~ /^(\w+?)/;
}
unless ($lang_det) {
$lang_det = 'en';
}
}

$ul = $lang_det;


Конечно, это далеко от совершенства, но работает для MSIE7, Netscape Navigator 9, Firefox 2, Mozilla 1.7.x. Ну и если будете совершенствовать, загляните в RFC2616 :)

Комментариев нет: