9

我有一些静态 html 文件,并希望通过 mustache.js 进行客户端修改来更改其中的静态文本。

似乎这可能是 Twitter 在 github 上的小胡子扩展:https ://github.com/bcherry/mustache.js

但最近特定的 I18n 扩展已被删除或更改。

我想象一个基于 lang 参数http:/server/static.html?lang=en加载和语言 JSON 文件的解决方案。mustache.jsdata_en.json

然后 mustache 用{{tags}}发送的数据替换 。

有人可以给我一个例子如何做到这一点?

4

5 回答 5

6

您可以将 lambdas 与 i18next 之类的库或其他库一起使用。

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

并且数据通过了:

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

这为我解决了问题

于 2014-03-14T18:01:26.777 回答
2

我认为 Silent 的回答并不能真正解决/解释问题。

真正的问题是你需要运行 Mustache 两次(或者使用其他东西然后 Mustache)。

这是大多数 i18n 的工作方式,如下所示:

  1. 使用给定的变量渲染 i18n 文本。
  2. 使用 post 渲染的 i18n 文本渲染 HTML。

选项 1:使用 Mustache 部分

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

给这个胡子模板的数据可能是:

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

然后,您会将所有 i18n 模板/消息存储为服务器上的 mustache 模板的大量 JSON 对象:

以下是“en”的翻译:

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

现在这种方法存在一个相当大的问题,因为 Mustache 没有逻辑,因此处理诸如复数之类的事情会变得混乱。另一个问题是执行这么多部分负载(也许不是),性能可能会很差。

选项 2:让服务器的 i18n 完成工作。

另一种选择是让服务器进行第一次扩展(步骤 1)。Java 确实有很多用于 i18n 扩展的选项,我认为其他语言也可以。

这个解决方案比较烦人的是你必须加载你的模型两次。一次使用常规模型,第二次使用扩展 i18n 模板。这相当烦人,因为您必须确切知道要扩展哪些 i18n 扩展/模板并将其放入模型中(否则您将不得不扩展所有 i18n 模板)。换句话说,你会得到一些很好的 DRY 违规行为。

解决前一个问题的一种方法是预处理小胡子模板。

于 2012-04-04T02:14:07.357 回答
2

我的回答是基于开发者的。他的回答非常好,我将在消息键码中添加使用小胡子标签的可能性。如果您希望能够根据当前的胡须状态或循环获取消息,则确实需要

它基于简单的双重渲染

 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.
}
于 2014-06-16T08:30:52.420 回答
0

这很简单,也很直接。

首先,您需要添加代码来确定查询字符串lang。为此,我使用从此处的答案中获取的片段。

function getParameterByName(name) {

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

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

}

然后,我使用 jQuery 来处理ajaxonReady状态处理:

$(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 答案。

于 2012-03-07T07:33:54.263 回答
0

请务必记住,其他语言与 EN 有很大不同。

在 FR 和 ES 中,形容词在名词之后。“green beans”在 FR 中变成了“haricots verts”(beans green),所以如果你插入变量,你翻译的模板必须以相反的顺序包含变量。因此,例如, printf 将不起作用,因为参数不能更改顺序。这就是为什么您使用上面选项 1 中的命名变量,并在整个句子和段落中使用翻译模板,而不是连接短语。

您的数据也需要翻译,因此来自数据的“便便”一词 - 必须以某种方式进行翻译。不同的语言有不同的复数形式,英语也是如此,如牙齿/牙齿、脚/脚等。EN 也有眼镜和裤子总是复数。其他语言也有类似的例外和奇怪的惯用语。在英国,IBM 参加了贸易展,而在美国,IBM 参加了贸易展。俄语有几种不同的复数规则,具体取决于它们是人、动物、狭长物体等。在其他国家/地区,千位分隔符是空格、点或撇号,在某些情况下不能使用 3 位数字:4 in日本,印度不一致。

满足于平庸的语言支持;工作量太大了。

不要将不断变化的语言与不断变化的国家混为一谈——瑞士、比利时和加拿大也有讲法语的人,更不用说大溪地、海地和乍得了。奥地利说DE,阿鲁巴说NL,澳门说PT。

于 2013-02-01T20:26:23.317 回答