Как стать автором
Обновить

Комментарии 25

Спасибо за статью. А в чём отличие от того же PolyglotJS?
А вы сможете ввести в Polyglot такую фразу: «Мы поймали #{a_count} ((окуня|окуней)):a_count и #{b_count} ((плотвиху|плотвихи|плотвих))»? Да и поддержка плюрализации там, похоже, не по UCDR.

В Locale::Babelfish, например, "#{count}, не меньше!" преобразуется в код sub { return params->{count}. ", не меньше"; }->(count => 5), без всяких регулярок.
А насколько востребованы такие сложные шаблоны формата? Я это к чему: в действительности у нас есть DOM. Обычно интерактивные элементы (типо счётчиков) находятся в собственных элементах и манипуляция с ними производится какой-то MV-либой, либо аналогичным ей самописным участком в кодобазе. То есть на практике может стать так, что нам нужно максимум зарегать функции из такой локализационной либы в качестве фильтров в MV.
Эти строки формата могут в полной мере раскрыться только в генерации на сервере, но в эпоху интерактивных/одностраничных/изоморфных (выбрать нужное) приложений, такой кейс становится всё более редким.
Вы затронули интересную тему.

Могу на своем опыте описать, что «строгие формы склонения» крайне популярны в английском/GB и русском/RU языках. Ну, пусть 0.5%. Это иногда крайне важно с точки зрения продаваемости.

А вообще, A/B-тестирование не зря придумано ;)
Интересная статья, спасибо. А как вы решили проблему наличия html кода во фразе? Например вам нужно локализировать
Привет, <a href='/user/'>#{username}</a>
эта фраза целиком пойдет в yaml файл в таком виде? Спасибо
мы предпочитаем Markdown-разметку.

Привет, (/user/)[#{username}]


Или как-то так. Никто не мешает вставлять и HTML, но не одобряется.

Посмотрите демку: regru.github.io/babelfish-demo/
Ну то есть как я понял, в локали все равно будет разметка там, где без нее не обойтись?
да. это удобнее в работе и при переводах (где акценты, где ссылки, — важно знать при переводе).
А инструменты переводчика есть готовые?
Спасибо. А что-нибудь не облачное и желательно open source? (возможно, потребуется делать доработки)
У нас пока только в планах (долго запрягаем).
Расскажите, как осуществляется подстановка одних кусков фраз в другие, когда обе содержат разметку? Как осуществляется экранирование спецсимволов, в том числе при подстановке пользовательских данных и одних кусков фраз в другие?

Например,
// locale:
{ "inner": "<span class="b-inner">**italic**</span>", "outer": "<span class="b-outer">#{inner}</span>"  }

// translation:
window.t("outer");


или,
// locale:
{ "outer": "<span class="b-outer">#{user_data}</span>" }

// translation:
window.t("outer", { "user_data": "<script>alert(document.cookie)</script>" });

Метод t имеет опциональный параметр с объектом-хэшем переменных (любой вложенности).

Тут вызываем t('outer', { inner: t('inner'));
Спасибо, это я понимаю. Вопрос был про экранирование разметки при таком вкладывании переводов друг в друга.
Не совсем понял вопроса. У нас в словарях обычно нет HTML-разметки, только markdown и подстановки переменных. Даже типографика и то отрабатывается автоматически.
Обычно — нет. А если всё-таки есть?

Приведу пример из жизни. Пользователю в веб-приложении отображается инструкция к части его интерфейса, структура инструкции задается в файле перевода (то есть код, выводящий строку с инструкцией, не знает, какая именно инструкция там написана). В этой инструкции присутствует изображение кнопки, которое должно в точности соответствовать внешнему виду кнопки в веб-приложении. Стиль кнопки задается CSS-темой оформления, которых множество, то есть скриншотить кнопку и вставлять картинку каждый раз, когда меняется или добавляется новая тема — не вариант. Соответственно, нужно вставить кусок разметки, представляющий собой кнопку, к которой автоматически применятся стили темы. Этот сценарий как-то предусмотрен?

Второй пример из жизни: вывод данных, введенных пользователем, в подстановке. Данные пользователя теоретически могут содержать разметку, которую нужно экранировать. На каком уровне вы это делаете? Экранируете ли от разметки всё, что попадает в подстановку? Тогда как избегаете двойного экранирования при вложенных подстановках?

Спасибо.
первый пример — чистка пользовательского ввода (sanitize) идет еще до попадания данных в базу. более того, современные интерфейсы внедряемые рассчитаны на ввод markdown вместо html.

второй пример — экранируется обычно весь результат уже после трансляции (возможно, перед процесссингом в Markdown), если так надо.
чистка пользовательского ввода (sanitize) идет еще до попадания данных в базу

А если данные из стороннего API и не известно, были ли они очищены?

экранируется обычно весь результат

Вместе с нужной разметкой, которая была в переводах? (см. пример с кнопкой)

Спасибо. Извините, что докучаю, но вопросы системного характера, хотелось бы понимать, есть ли системные решения, или каждый отдельный случай нужно огораживать костылем.
мы не доверяем данным сторонних провайдеров. всегда зачищаем.
Например, по нашим правилам некоторые ссылки должны иметь rel=«nofollow» class=«b-link» target="_blank". Это все описывается в конфиге БЭМ, и некий БЭМ-фильтр согласно конфигу накладывает эти атрибуты на срендеренный HTML. Опять-таки без необходимости вводить это все вручную.
Есть еще github.com/twitter/twitter-cldr-js (на его основе я написал враппер для своего приложения, в виде MyApp.tt(...) ) могу выложить gist, если интересно.
Спасибо, полезно. Хотя будущее за чистыми JS-реализациями, в любом случае.

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