Хорошая практика интернационализации в RactiveJS (с использованием RequireJS)

Я создал веб-приложение на основе RactiveJS. Он использует RequireJS для обработки модулей и зависимостей. Шаблоны Ractive загружаются с помощью rv.

Теперь я хотел бы поддерживать несколько языков (изначально только немецкий и английский).

Итак, мой вопрос:

Что рекомендуется для интернационализации в RactiveJS?

Пока вижу два варианта:

<сильный>1. Удалите весь текст из шаблонов, поместите их в файл ресурсов и пропустите их через метод поиска.
Недостатки:
Либо текст разбивается на части, оставляя бессмысленные фрагменты, либо разрывается привязка данных в случаях, подобных <div>The Item {{name}} is used <b>{{count}}</b> times.</div>.

<сильный>2. Дублирующиеся шаблоны
Недостатки:
• дублированный код шаблона
• Не удалось понять, как создавать отдельные языковые пакеты для шаблонов с помощью Требуется оптимизатор JS

<сильный>3. ???
Есть еще идеи?

Кстати: можно перезагружать все приложение при смене языка. Я бы предпочел решение, при котором через RequireJS будет загружаться только ресурс для выбранного в данный момент языка.


person LeJared    schedule 09.11.2015    source источник
comment
Вы можете взглянуть на github.com/ceremcem/ractive-i18n.   -  person ceremcem    schedule 06.11.2018


Ответы (2)


Канонического способа сделать это нет. Однако вы можете избежать этого, используя декораторы. Оберните текст в <span> и добавьте декоратор в <span>. Что делает декоратор, так это извлекает содержимое <span>, получает перевод из подготовленного сопоставления и заменяет этот текст.

<div>
  <span decorator="i18n">Some random text to translate</span>
</div>

Чтобы сгенерировать файлы перевода, вы можете использовать инструмент grunt/gulp/любой инструмент, который проходит через все ваши файлы компонентов, анализирует его часть HTML и ищет элементы с расширением decorator="i18n". Затем вы создаете на его основе шаблон JSON и вручную заполняете переводы.

{
  "Some random text to translate": "Alcuni testo casuale da tradurre",
  ...
}

Затем у вас может быть какой-то глобальный индикатор, чтобы сигнализировать модулю декоратора, какие сопоставления перевода загружать. Поскольку перевод можно изменить в любое время, он не может быть загружен через RequireJS статически. Сопоставления необходимо будет отключить с помощью AJAX или выполнить с помощью динамического вызова require. В любом случае переводы не будут включены оптимизатором.

Кроме того, при рендеринге возникают некоторые накладные расходы, поскольку каждый компонент, визуализируемый с помощью этого декоратора, будет изменять текст на лету.

person Joseph    schedule 10.11.2015
comment
Хорошая идея, но это еще хуже, чем вариант 1, потому что он также нарушает привязку данных в тексте (см. пример), а таблица поиска прерывается сразу же, когда вы изменяете ссылочный текст. Кроме того, обработка нескольких декораторов на одном элементе немного сложна в текущей версии RactiveJS, поэтому вам нужно добавить дополнительную разметку, чтобы сохранить ее эксклюзивность. И для проблемы смены языка: как я уже говорил в вопросе, можно перезагрузить приложение при смене языка. - person LeJared; 10.11.2015

Чтобы решить проблему 1 + 2, а именно сохранить смысл ваших шаблонов, но не дублировать все шаблоны, рассмотрите возможность предоставления текста на вашем основном языке (скажем, на английском) в качестве по умолчанию для функции перевода.

Основано на обсуждении в этой проблемы с Ractive и продемонстрировано Курдиным в эту скрипту ваш шаблон может выглядеть так:

<p>{{{ t('Hello <strong>{{name}}</strong> and have a nice day!', 'hello', {name: user.name}) }}}</p>

Затем вы должны определить функцию перевода t, которая специально обрабатывает значение по умолчанию.

Translations = []   // load those however you want
Translations["ru"] = {
       localization: 'пример локализации',
       hello: "Привет <strong>{{name}}</strong> хорошего тебе дня!",
       language: 'Язык: {{lang}} ',
       lang: 'Русский'
}

I18n.translations = Translations;
I18n.defaultLocale = "en";

function t(defaultText, name, context) {
    return (I18n.locale === I18n.defaultLocale) ? defaultText : I18n.t(name, context);
}

Недостатки:

  1. Несоответствие. Язык по умолчанию жестко запрограммирован в шаблонах, т. е. у вас будет другое место для языка по умолчанию, чем для языковых пакетов.
  2. Накладные расходы: вы можете загрузить данные для двух языков, поскольку в шаблонах всегда будет загружаться язык по умолчанию.

Чтобы решить первую проблему, то есть согласованность, вы можете также предоставить языковой пакет для английского языка и пропустить пользовательскую функцию t.

person mknecht    schedule 11.11.2015
comment
Думаю, я пойду с вариантом этого. Я думаю, что я буду использовать I18next в качестве t()-функции и зарегистрировать ее глобально для всех моих экземпляров Ractive и использовать ключи чтобы получить доступ к тексту через него. В любом случае мне придется поддерживать заполнители и разметку стилей, например <strong>, в файлах ресурсов, по крайней мере, для языков, отличных от стандартных. - person LeJared; 11.11.2015