Как сделать клиентскую часть I18n с помощью mustache.js - PullRequest
9 голосов
/ 22 марта 2011

У меня есть несколько статических html-файлов, и я хочу изменить статический текст внутри с помощью модификации на стороне клиента через mustache.js.

похоже, что это было возможно расширение усов Twitter на github: https://github.com/bcherry/mustache.js

Но в последнее время конкретное расширение I18n было удалено или изменено.

Я представляю решение, в котором http:/server/static.html?lang=en загружает mustache.js и языковой файл JSON на основе параметра lang data_en.json.

Затем усы заменяют {{tags}} отправленными данными.

Может кто-нибудь дать мне пример, как это сделать?

Ответы [ 5 ]

6 голосов
/ 14 марта 2014

Вы можете использовать лямбды вместе с некоторой библиотекой, такой как i18next или чем-то еще.

{{#i18n}}greeting{{/i18n}} {{name}}

И переданные данные:

{
    name: 'Mike',
    i18n: function() {
        return function(text, render) {
            return render(i18n.t(text));
        };
    }
}

Это решило проблему для меня

3 голосов
/ 04 апреля 2012

Я не думаю, что ответ Silent действительно решает / объясняет проблему.

Реальная проблема в том, что вам нужно дважды запустить Усы (или использовать что-то еще, а затем Усы).

ЭтоВ большинстве случаев i18n работает как двухэтапный процесс, подобный следующему:

  1. Визуализация текста i18n с заданными переменными.
  2. Визуализация HTML с отображаемым в тексте текстом i18n.

Вариант 1: Использовать частичные усы

<p>{{> i18n.title}}</p>
{{#somelist}}{{> i18n.item}}{{/somelist}}

Данные для этого шаблона усов могут быть следующими:

{ 
  "amount" : 10, 
  "somelist" : [ "description" : "poop" ]
}

Тогда вы сохраните все свои шаблоны / сообщения i18n какмассивный JSON-объект шаблонов усов на сервере:

Ниже приведены переводы "en":

{ 
   "title" : "You have {{amount}} fart(s) left", 
   "item" : "Smells like {{description}}"
}

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

Вариант 2: пусть i18n сервера выполнит свою работу.

Другой вариант - позволить серверу выполнитьпервый проход расширения (шаг 1).У Java есть много вариантов расширения i18n. Я полагаю, что и другие языки тоже.

Что довольно раздражает в этом решении, так это то, что вам придется загружать модель дважды.Один раз с обычной моделью и второй раз с расширенными шаблонами i18n.Это довольно раздражает, так как вам нужно точно знать, какие расширения / шаблоны i18n следует развернуть и вставить в модель (в противном случае вам придется развернуть все шаблоны i18n).Другими словами, вы получите несколько хороших нарушений DRY.

Одним из способов решения предыдущей проблемы является предварительная обработка шаблонов усов.

2 голосов
/ 16 июня 2014

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

Это основано на простом двойном рендеринге

 info.i18n = function(){
        return function(text, render){
            var code = render(text); //Render first to get all variable name codes set
            var value = i18n.t(code)
            return render(value); //then render the messages
        }
    }

Таким образом, спектакли не пострадали из-за усов, работающих на очень маленькой струне.

Вот небольшой пример:

Данные Json:

 array : 
    [
        { name : "banana"},
        { name : "cucomber" }
    ]

Шаблон усов:

{{#array}}
    {{#i18n}}description_{{name}}{{/i18n}}
{{/array}}

Сообщения

description_banana = "{{name}} is yellow"
description_cucomber = "{{name}} is green"

Результат:

banana is yellow
cucomber is green

Множественное

[Редактировать]: Как указано в комментарии, приведен пример с псевдокодом обработки множественного числа для английского и французского языков. Это очень простой и не проверенный пример, но он дает вам подсказку.

description_banana = "{{#plurable}}a {{name}} is{{/plurable}} green" (Adjectives not getting "s" in plurals)

description_banana = "{{#plurable}}Une {{name}} est verte{{/plurable}}" (Adjectives getting an "s" in plural, so englobing the adjective as well)

info.plurable = function() 
{
  //Check if needs plural
  //Parse each word with a space separation
  //Add an s at the end of each word except ones from a map of common exceptions such as "a"=>"/*nothing*/", "is"=>"are" and for french "est"=>"sont", "une" => "des"
  //This map/function is specific to each language and should be expanded at need.
}
0 голосов
/ 02 февраля 2013

Обязательно помните, что другие языки значительно отличаются от EN.

В FR и ES прилагательные следуют после существительного."зеленые бобы" становятся "фасолью вершин" (зеленые бобы) в FR, поэтому, если вы подключаете переменные, ваши переведенные шаблоны должны иметь переменные в обратном порядке.Так, например, printf не будет работать, потому что аргументы не могут изменить порядок.Вот почему вы используете именованные переменные, как в варианте 1 выше, и переводите шаблоны в целые предложения и абзацы, а не в объединение фраз.

Ваши данные также должны быть переведены, поэтому слово «корма», которое пришло из данных, - каким-то образом должно быть переведено.Разные языки делают множественное число по-разному, как и английский, как в зубах / зубах, ступнях / ступнях и т. Д. У EN также есть очки и штаны, которые всегда множественного числа.Другие языки также имеют исключения и странные символы.В Великобритании IBM «присутствует» на выставке, в то время как в США IBM «присутствует» на выставке.В русском языке есть несколько различных правил для множественного числа, в зависимости от того, являются ли они людьми, животными, длинными узкими объектами и т. Д. В других странах разделителями тысяч являются пробелы, точки или апострофы, и в некоторых случаях они не работают на 3 цифры: 4 вЯпония непоследовательно в Индии.

Будьте довольны посредственной поддержкой языков;это просто слишком много работы.

И не путайте смену языка со сменой страны - в Швейцарии, Бельгии и Канаде также есть говорящие на французском языке, не говоря уже о Таити, Гаити и Чаде.Австрия говорит на DE, Аруба говорит на NL, а Макао говорит на PT.

0 голосов
/ 07 марта 2012

Это довольно просто и довольно просто.

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

function getParameterByName(name) {

    var match = RegExp('[?&]' + name + '=([^&]*)')
                    .exec(window.location.search);

    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));

}

И затем я использую jQuery для обработки обработки состояний ajax и onReady:

$(document).ready(function(){
    var possibleLang = ['en', 'id'];
    var currentLang = getParameterByName("lang");
    console.log("parameter lang: " + currentLang);
    console.log("possible lang: " + (jQuery.inArray(currentLang, possibleLang)));
    if(jQuery.inArray(currentLang, possibleLang) > -1){
        console.log("fetching AJAX");
        var request = jQuery.ajax({
            processData: false,
            cache: false,
            url: "data_" + currentLang + ".json"
        });
        console.log("done AJAX");

        request.done(function(data){
            console.log("got data: " + data);
            var output = Mustache.render("<h1>{{title}}</h1><div id='content'>{{content}}</div>", data);
            console.log("output: " + output);
            $("#output").append(output);
        });

        request.fail(function(xhr, textStatus){
            console.log("error: " + textStatus);
        });
    }
});

В этом ответе я пытаюсь использовать простые данные JSON:

{"title": "this is title", "content": "this is english content"}

Получите этот GIST для полного ответа HTML.

...