Как сделать локализацию в Google Closure

В настоящее время я использую простой текст в своем приложении Closure. Я хочу добавить локализацию к этому тексту. Я только что нашел несколько статей о функции goog.getMsg, которая используется для такой локализации. Насколько я понял, это делается во время компиляции. Как мы можем изменить язык во время выполнения, когда пользователь нажимает кнопку? Как проще всего это сделать с помощью Closure?


comment
i8nl — это время компиляции в конце.   -  person lennel    schedule 09.11.2013


Ответы (2)


Я действительно достиг времени выполнения i18n. Я использую шаблоны .soy с тегами {msg}. Когда вы компилируете .soy в .js, эти вызовы компилируются в вызовы goog.getMsg. Что я должен был сделать, так это:

  1. Найдите все .js файлы, в которых есть goog.getMsg(.
  2. Добавить goog.require("myApp.i18n");\n
  3. Заменить все вызовы goog.getMsg( на myApp.i18n.translate(
  4. Замените все имена свойств MSG_* на myprefix_MSG_*

Зачем все это: нельзя напрямую переопределить goog.getMsg, потому что он считается примитивом компилятора и не допускает никаких манипуляций. То же самое относится к свойствам MSG_*.

myApp.i18n.translate — это функция, которая принимает строку, пытается найти ее в карте локали (которая передается во время выполнения) и возвращает результат goog.getMsg, используя локализованную строку (goog.getMsg делает несколько удобных замен заполнителей).

Хотя это не очень красивое решение, оно работает и позволяет мне менять язык во время выполнения, используя только один скомпилированный файл для всех языков.

Фактический код включает в себя несколько хаков, которые позволяют мне использовать сгенерированное описание и использовать файлы JSON вместо странного формата файла закрытия, но суть та же.

Однако!

На самом деле вам следует скомпилировать несколько файлов из вашего приложения и загрузить разные файлы .js для каждого языка.

Мне пришлось использовать это решение, потому что мне нужно поддерживать сотни различных конфигураций и несколько языков: было бы безумием компилировать тысячи файлов .js, когда одна компиляция занимает 30+ секунд.

person Corkscreewe    schedule 16.11.2013
comment
автоматизированная сборка лет! что касается вашего решения, оно интересно, я бы рекомендовал написать его как плагин компилятора. Если вам нужна помощь в этом, я с радостью помогу. - person lennel; 09.01.2014

Хотя это не решение для переключения языка одним щелчком мыши, я нахожу его очень удобным, поскольку оно позволяет использовать один и тот же источник локализованных текстов как для шаблонов Soy, так и goog.getMsg() в коде JS. Это своего рода недокументированный способ использования собственного XML-формата переводов Google, называемого XTB.

В итоге вы получите разные скомпилированные файлы .js для каждого языка, поэтому для переключения локали вам нужно перезагрузить другой файл JS.

Помимо стандартных инструментов Closure, существует сторонний инструмент под названием XtbGenerator, который можно найти здесь: https://github.com/kuzmisin/xtbgenerator.


Теперь рабочий процесс:

  1. Скомпилируйте свои шаблоны, используя SoyToJsSrcCompiler.jar с --shouldGenerateGoogMsgDefs --bidiGlobalDir 1 параметрами. Еще нет локали.

  2. Создайте файл зависимостей, используя calcdeps.py

  3. Запустите closurebuilder.py с --compiler_jar, установленным в файл XtbGenerator.jar, и с параметром --compiler_flags="--xtb_output_file=origin.xtb".

    Это создаст файл с именем origin.xtb, который вы сможете использовать в качестве основы для своих переводов. Он будет содержать все тексты как из шаблонов Soy (в {msg} блоках), так и ваших JS-файлов (где используется var MSG_TEST = goog.getMsg('Text');).

  4. Скопируйте origin.xtb например в translated.cs_CZ.xtb, измените атрибут lang в файле и переведите туда все тексты.

  5. Скомпилируйте приложение для данной локали стандартным способом, используя closurebuilder.py и compiler.jar. Использовать параметры:

    --compiler_flags="--translations_file=translated.cs_CZ.xtb"

    --compiler_flags="--define=goog.LOCALE='cs_CZ'"

    Это создаст скомпилированную версию для одной локали.

Хорошие примеры всех этих шагов здесь: http://www.closurecheatsheet.com/skeleton.

Жаль, что официальной документации по этому поводу почти нет.


Формат XTB:

Формат следующий:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
    <translation id="4127240967364168948" key="MSG_6LRZ706911HM" source="..\test.soy.js" desc="description">test</translation>
</translationbundle>

id и для соевых шаблонов также атрибут key автоматически генерируется компилятором/экстрактором

Скорее всего, это какой-то внутренний формат Google с инструментами для этого, исходный код которых еще не открыт.


Примечание о XtbGenerator:

Он внутренне использует код Closure Compiler для просмотра ваших JS-кодов и извлечения сообщений. Загружаемая версия, однако, построена с использованием более старой версии Closure Compiler, поэтому у меня возникали некоторые ошибки.

Я сделал быстрый и грязный взлом, скопировав каталоги goog из текущей версии compiler.jar в XtbGenerator.jar.

person oujesky    schedule 26.03.2014