gpt4 book ai didi

grails - Backbone 和 Handlebars 的服务器端国际化

转载 作者:行者123 更新时间:2023-12-02 02:21:53 26 4
gpt4 key购买 nike

我正在开发一个 Grails/Backbone/Handlebars 应用程序,它是一个更大的遗留 Java 系统的前端,其中(出于历史和可定制性的原因)国际化消息深入隐藏在几个 SOAP 服务后面的数据库中依次隐藏在各种内部 Java 库后面。从 Grails 层获取这些消息很容易并且工作得很好。

不过,我想知道如何将(例如)国际化标签添加到我的 Handlebars 模板中。

现在,我正在使用 GSP 片段生成模板,包括获取我感兴趣的消息的自定义标记,例如:

<li><myTags:message msgKey="title"/> {{title}}</li>

但是,出于性能和代码布局的原因,我想摆脱 GSP 模板并将它们直接转换为 HTML。我研究了一些客户端国际化选项,例如 i18n.js ,但它们似乎取决于我没有的消息文件的存在。 (我可以生成它,也许,但它会是巨大且昂贵的。)

到目前为止,我能想到的最好的办法是将标签也楔入 Backbone 模型中,所以我最终会得到类似的东西

<li>{{titleLabel}} {{title}}</li>

然而,这确实偏离了在干净的 RESTful JSON API 之上构建 Backbone 模型的理想——RESTful 服务返回的 JSON 中充满了表示数据(即本地化标签),或者我必须做额外的工作才能将标签注入(inject)到 Backbone 模型中,并且用演示数据弄乱 Backbone 模型似乎也是错误的。

我认为,就干净的数据和干净的 API 而言,我想做的是编写另一个 RESTful 服务,该服务采用消息键和类似列表,并返回包含所有本地化消息的 JSON 数据结构。然而,问题仍然存在:

  1. 指示(可能在模板中)给定 View 需要哪些消息键的最佳方式是什么?
  2. 数据的正确格式是什么?
  3. 如何将本地化消息放入 Backbone View 中?
  4. 是否有任何现有的 Javascript 库可以提供帮助,或者我应该开始编写一些东西?
  5. 是否有更好/更标准的替代方法?

最佳答案

我认为你可以通过结合 Handelbars 助手和一些正则表达式来创建一个相当优雅的解决方案。

这是我的建议:

  1. 创建一个服务,该服务接收消息键的 JSON 数组并返回 JSON 对象,其中键是消息键,值是本地化文本。
  2. 定义一个 Handlebars 助手,它接收消息键(与服务器上的消息键匹配)并输出翻译后的文本。类似于 {{localize "messageKey"}}。使用此帮助程序进行所有模板本地化。
  3. 编写一个模板预处理器,用于从模板中获取消息键并向您的服务发出请求。预处理器缓存它获得的所有消息键,并且只请求它还没有的消息键。
    • 您可以在需要渲染模板时按需调用此预处理器,也可以预先调用它并缓存消息键,以便它们在您需要时随时可用。
    • 要进一步优化,您可以将缓存保留到浏览器本地存储。

Here's a little proof of concept 。它还没有本地存储持久性或支持一次获取多个模板的文本以进行缓存,但它很容易组合在一起,我认为通过进一步的工作,它可以很好地工作。

客户端 API 可能如下所示:

var localizer = new HandlebarsLocalizer();

//compile a template
var html = $("#tmpl").html();
localizer.compile(html).done(function(template) {
//..template is now localized and ready to use
});

这是懒惰的读者的来源:

var HandlebarsLocalizer = function() {

var _templateCache = {};
var _localizationCache = {};

//fetches texts, adds them to cache, resolves deferred with template
var _fetch = function(keys, template, deferred) {
$.ajax({
type:'POST',
dataType:'json',
url: '/echo/json',
data: JSON.stringify({
keys: keys
}),
success: function(response) {
//handle response here, this is just dummy
_.each(keys, function(key) { _localizationCache[key] = "(" + key + ") localized by server"; });
console.log(_localizationCache);
deferred.resolve(template);
},
error: function() {
deferred.reject();
}
});
};

//precompiles html into a Handlebars template function and fetches all required
//localization keys. Returns a promise of template.
this.compile = function(html) {

var cacheObject = _templateCache[html],
deferred = new $.Deferred();

//cached -> return
if(cacheObject && cacheObject.ready) {
deferred.resolve(cacheObject.template);
return deferred.promise();
}
//grep all localization keys from template
var regex = /{{\s*?localize\s*['"](.*)['"]\s*?}}/g, required = [], match;
while((match = regex.exec(html))) {
var key = match[1];
//if we don't have this key yet, we need to fetch it
if(!_localizationCache[key]) {
required.push(key);
}
}

//not cached -> create
if(!cacheObject) {
cacheObject = {
template:Handlebars.compile(html),
ready: (required.length === 0)
};
_templateCache[html] = cacheObject;
}

//we have all the localization texts ->
if(cacheObject.ready) {
deferred.resolve(cacheObject.template);
}
//we need some more texts ->
else {
deferred.done(function() { cacheObject.ready = true; });
_fetch(required, cacheObject.template, deferred);
}

return deferred.promise();
};

//translates given key
this.localize = function(key) {
return _localizationCache[key] || "TRANSLATION MISSING:"+key;
};

//make localize function available to templates
Handlebars.registerHelper('localize', this.localize);
}

关于grails - Backbone 和 Handlebars 的服务器端国际化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14206586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com