В настоящее время я использую простой текст в своем приложении Closure. Я хочу добавить локализацию к этому тексту. Я только что нашел несколько статей о функции goog.getMsg, которая используется для такой локализации. Насколько я понял, это делается во время компиляции. Как мы можем изменить язык во время выполнения, когда пользователь нажимает кнопку? Как проще всего это сделать с помощью Closure?
Как сделать локализацию в Google Closure
Ответы (2)
Я действительно достиг времени выполнения i18n. Я использую шаблоны .soy с тегами {msg}
. Когда вы компилируете .soy в .js, эти вызовы компилируются в вызовы goog.getMsg. Что я должен был сделать, так это:
- Найдите все
.js
файлы, в которых естьgoog.getMsg(
. - Добавить
goog.require("myApp.i18n");\n
- Заменить все вызовы
goog.getMsg(
наmyApp.i18n.translate(
- Замените все имена свойств
MSG_*
наmyprefix_MSG_*
Зачем все это: нельзя напрямую переопределить goog.getMsg, потому что он считается примитивом компилятора и не допускает никаких манипуляций. То же самое относится к свойствам MSG_*
.
myApp.i18n.translate
— это функция, которая принимает строку, пытается найти ее в карте локали (которая передается во время выполнения) и возвращает результат goog.getMsg
, используя локализованную строку (goog.getMsg
делает несколько удобных замен заполнителей).
Хотя это не очень красивое решение, оно работает и позволяет мне менять язык во время выполнения, используя только один скомпилированный файл для всех языков.
Фактический код включает в себя несколько хаков, которые позволяют мне использовать сгенерированное описание и использовать файлы JSON вместо странного формата файла закрытия, но суть та же.
Однако!
На самом деле вам следует скомпилировать несколько файлов из вашего приложения и загрузить разные файлы .js для каждого языка.
Мне пришлось использовать это решение, потому что мне нужно поддерживать сотни различных конфигураций и несколько языков: было бы безумием компилировать тысячи файлов .js, когда одна компиляция занимает 30+ секунд.
Хотя это не решение для переключения языка одним щелчком мыши, я нахожу его очень удобным, поскольку оно позволяет использовать один и тот же источник локализованных текстов как для шаблонов Soy, так и goog.getMsg()
в коде JS. Это своего рода недокументированный способ использования собственного XML-формата переводов Google, называемого XTB.
В итоге вы получите разные скомпилированные файлы .js для каждого языка, поэтому для переключения локали вам нужно перезагрузить другой файл JS.
Помимо стандартных инструментов Closure, существует сторонний инструмент под названием XtbGenerator, который можно найти здесь: https://github.com/kuzmisin/xtbgenerator.
Теперь рабочий процесс:
Скомпилируйте свои шаблоны, используя
SoyToJsSrcCompiler.jar
с--shouldGenerateGoogMsgDefs --bidiGlobalDir 1
параметрами. Еще нет локали.Создайте файл зависимостей, используя
calcdeps.py
Запустите
closurebuilder.py
с--compiler_jar
, установленным в файлXtbGenerator.jar
, и с параметром--compiler_flags="--xtb_output_file=origin.xtb"
.Это создаст файл с именем
origin.xtb
, который вы сможете использовать в качестве основы для своих переводов. Он будет содержать все тексты как из шаблонов Soy (в{msg}
блоках), так и ваших JS-файлов (где используетсяvar MSG_TEST = goog.getMsg('Text');
).Скопируйте
origin.xtb
например вtranslated.cs_CZ.xtb
, измените атрибутlang
в файле и переведите туда все тексты.Скомпилируйте приложение для данной локали стандартным способом, используя
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
.