shoorick: (Default)
shoorick ([personal profile] shoorick) wrote2010-12-10 11:33 pm

Йаду не хватило

Снова задумался о применении геттекста в Mojolicious — существующий метод, когда вместо написания отдельных геттекстовых po--файлов прямо в перловый код засовывается что-то такое:
our %Lexicon = ( 
    'Add'    => 'Добавить',
    'Remove' => 'Удалить'
);
никоим образом не может считаться достойным. Порывшись по CPAN, добрёл по ссылкам до Locale::Maketext::TPJ13, где авторы ругают геттекст, приводя корявые якобы геттекстовые примеры обслуживания множественных чисел, надеясь оправдать этим существование собственного других модулей, которые не лучше.

Написал на annocpan коммент, хотя сомневаюсь, что авторы получит его и пойдёт читать мануал по Locale::TextDomain. Похоже, процитированная в Locale::Maketext::TPJ13 статья вышла очень давно (first appeared in The Perl Journal #13 and is copyright 1999) и авторы о ней забыли.

[identity profile] knutov.livejournal.com 2010-12-10 09:17 pm (UTC)(link)
А собственно, как делать правильно? В отрыве от моджо.

#gettext в отрыве от #mojolicious

[identity profile] shoorick.livejournal.com 2010-12-11 03:27 pm (UTC)(link)
https://gist.github.com/737400

Не знаю, правильно ли, но оно работает. И переводит на нужный язык, и подбирает соответствующее число в зависимости от переданной цифры (в русском кое-где встречаются остатки двойственного числа). В геттекстовом мануале описаны правила подбора числа для 36 языков.

Как использовать пример:
  1. mkdir example locale po
  2. кладём скрипт в example (у меня он назывался 1.pl), остальное — в po
  3. cd po; make
  4. cd ../example
  5. запустить можно двумя способами:
    env LANGUAGE=ru ./1.pl
    или
    ./1.pl ru
    Вместо ru можно писать любой другой код. Если найдётся файл переводов — скрипт будет писать на выбранном языке, если на найдётся — на английской.
  6. при изменении текста в скрипте надо обновить исходные файлы переводов (*.po) — проще всего через cd po; make up (вместо up можно писать update), а затем, отредактировав в случае необходимости po-файлы, перекомпилять их — перейди на шаг 3.
Получается, что тут переводы отделены от исходного кода скриптов — можно поручить перевод людям, мало понимающим в программировании, но разбирающимся в иностранных языках.

Re: #gettext в отрыве от #mojolicious

[identity profile] shoorick.livejournal.com 2010-12-13 07:53 am (UTC)(link)
Подправил пример (оказывается, там можно хранить и структуру каталогов).
Получить свежий пример можно с git://gist.github.com/737400.git — там уже всё разложено куда надо и добавлен маленький README.

[identity profile] nuclon.livejournal.com 2010-12-11 12:14 pm (UTC)(link)
А вот, кстати, можете показать пример применения Locale::TextDomain в Mojo для мультиязычного сайта?
Я недавно делал проект и у меня получилось нечто рабочее, но жутко корявое, использующее gettext_pp (pure perl) имплементацию.

Пока нет

[identity profile] shoorick.livejournal.com 2010-12-11 02:32 pm (UTC)(link)
Пока не могу. Но, видимо, придётся всё-таки придумать, как это сделать. Как придумаю — обязательно напишу.

Re: Пока нет

[identity profile] nuclon.livejournal.com 2010-12-11 03:32 pm (UTC)(link)
судя по этому (http://search.cpan.org/~guido/libintl-perl-1.20/lib/Locale/libintlFAQ.pod#How_do_I_switch_languages_or_force_a_certain_language_independently_from_user_settings_read_from_the_environment?): "Remember that these environment variables are not guaranteed to work, if you use an XS version of gettext" - все равно придётся использовать pure perl имплементацию.

Re: Пока нет

[identity profile] nuclon.livejournal.com 2010-12-11 03:40 pm (UTC)(link)
...попробую-ка я интереса ради написать плагин. :)

Re: Пока нет

[identity profile] nuclon.livejournal.com 2010-12-12 08:20 pm (UTC)(link)
https://bitbucket.org/nuclon/mojolicious-plugin-textdomain/src

только ещё доку не начал писать, буду рад любым предложениям переделать :)

предполагается использовать в бридже на /, где делать что-то типа


$self->set_language( $self->session('lang')
                  || $self->detect_language(
                         scalar $self->req->headers->accept_language, ['en', 'ru'], 'en' ) 
    );


ну или брать язык не с сессии, а с урла.

Re: Пока нет

[identity profile] shoorick.livejournal.com 2010-12-13 09:04 am (UTC)(link)
Пробую запустить.

Пока удалось перевести обычный текст, а с множественным числом пока не очень получается.

Re: Пока нет

[identity profile] shoorick.livejournal.com 2010-12-13 09:23 am (UTC)(link)
Сделал так: https://gist.github.com/738816
Запускаю:
env LANGUAGE=ru ./2_td.pl daemon
или
env LANG=ru_RU.UTF-8 ./2_td.pl daemon

Выводит:

in layout: Работает?

in template: Работает?

Plural via __nx: 24 apples were found

Plural via __n: 24 apples were found

Форму множественного числа, вроде, подбирает (то есть, иногда пишет 1 apple), но не переводит на русский.

Re: Пока нет

[identity profile] shoorick.livejournal.com 2010-12-13 10:45 am (UTC)(link)
Посмотрел внимательнее: оказалось, я там в скрипте msgid поменял, а в переводе — забыл. Подправил — заработало: и в обоих шаблонах, и в контроллере. Спасибо.

Осталось придумать, как xgettext научить брать из скрипта подлежащий переводу текст. Потому что сейчас он справляется только с обычными перловыми скриптами, а в шаблонах на epl пока бессилен. Могляжу мануал, может, найду.

Re: Пока нет

[identity profile] nuclon.livejournal.com 2010-12-13 10:00 am (UTC)(link)
только что закоммитил немного изменений + добавил в тест работу с множественным числом. пришлось немного поправить формулу plural-forms для русского (добавил скобки)

вообще - попробуйте закомментировать строку в тестах с установкой pp - некоторые тесты сразу упадут.

pp

[identity profile] shoorick.livejournal.com 2010-12-13 09:46 am (UTC)(link)
У меня и без pp заработало:
я закомментировал Locale::Messages->select_package('gettext_pp'); — ничего не поменялось.

(Anonymous) 2010-12-11 05:15 pm (UTC)(link)
Да вы опять издеватесь над собой. our %Lexicon вполне не плох. В погоне за совершенным и правильным решением вы потеряете кучу времени и придется еще писать свой код, который потом надо будет в другие ваши проекты тащить. А так все или можовское решение или Locale::gettext вполне, вполне.

our %Lexicon плох

[identity profile] shoorick.livejournal.com 2010-12-11 08:09 pm (UTC)(link)
Меня Locale::TextDomain вполне устраивает. Да и в геттекстовом мануале именно он и рекомендован. С учётом того, что сам геттекст — популярное решение, используемое уже больше 10 лет, мне кажется, что следует пользоваться именно им.

То, что его пока нет в Mojolicious'е — не беда. Можно, в конце концов, потратить какое-то время и написать плагин (если к тому моменту ещё кто-нибудь не напишет) — это лучше, чем использовать %Lexicon.

Предлагаемые в Mojolicious методы (с %Lexicon) плохи хотя бы тем, что там нет поддержки множественного числа (или я не нашёл). Писать «2 файл(ов)» в своих программах, как мне кажется, не следует.

Или так

[identity profile] shoorick.livejournal.com 2010-12-11 08:36 pm (UTC)(link)
Если бы речь шла об изменении уже существующей системы переводов с Meketext на GNU gettext — я бы задумался, стóит ли ввязываться.
Но в случае, когда никакая система ещё не используется — лучше сразу поставить более правильную.

mojowka сейчас не переведена на другие языки (хотя надо бы перевести): я ещё несколько месяцев назад наткнулся на статью Вячеслава Тихановского Building a multilingual website with Mojolicious, но до сих пор не внёс предложенный там код в свою систему — мне не понравился %Lexicon.
(deleted comment)

Про эту проблему

[identity profile] shoorick.livejournal.com 2010-12-11 08:15 pm (UTC)(link)
Здóрово. А вы писали сразу на английском или в сети лежит и русский перевод?
(deleted comment)

Re: Про эту проблему

[identity profile] shoorick.livejournal.com 2010-12-12 06:47 am (UTC)(link)
Ну это-то понятно, почему оно их не волнует :-)

Не понял про "русский" русский.

[identity profile] meettya.livejournal.com 2010-12-22 11:28 pm (UTC)(link)
Поправьте, если ошибаюсь, но в русском языке словоформа множественного числа явно не одна.
1 файл_, 2-4 файлА, 5-20 файлОВ и далее по малому циклу (0-9) с числами больше 20.
Есть CPAN решение, нормально руссифицируещее сообщения?

Re: Не понял про "русский" русский.

[identity profile] shoorick.livejournal.com 2010-12-23 06:08 am (UTC)(link)
Мне попадалось мнение, что в русском языке действительно не два числа, а три — между единственным и множественным попадаются остатки когда-то существовавшего двойственного числа. Хотя если мы говорим «2 файла» и «33 зуба», значит, двойственное число есть и сейчас. Хоть о нём и не рассказывают в школе.

На CPAN было дофига вариантов. Как и в этом журнале: и на перле, и на пхп.

Но если планируете использовать в своей программе несколько языков, лучше всё-таки использовать геттекст. А если пока не планируете, всё равно не помешает заглянуть на http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html — там, помимо руководства на геттекст, перечислены правила вычисления множественных чисел почти для сорока языков. Есть и достаточно компактное выражение (на C) для русского.

Re: Не понял про "русский" русский.

[identity profile] meettya.livejournal.com 2010-12-29 12:51 am (UTC)(link)
О, спасибо за наводку на геттекстовый ман, ИМХО это самый прямой путь.

Что до множественного числа - у Зализняка А.А. есть очень верное определение данной словоформы как "ограниченное число" или там же "множественное число малого количества" - "от полутора до четырех". (книга «Русское именное словоизменение»)
(deleted comment)

ngettext

[identity profile] shoorick.livejournal.com 2010-12-11 08:10 pm (UTC)(link)
Не знал :-)