为 i18n 国际化解析 spring:messages in javascript
我正在尝试将我们的一些代码国际化.我在 JSPX 中有一个页面,它使用 <spring:message>
标记来解析 message.properties
文件中的字符串.这适用于 JSPX 页面中的 HTML 和 CSS,但是有一个 javascript 文件,并且用 <spring:message>
标记代替那里的字符串意味着它得到逐字打印出来.
I'm attempting to internationalize some of our code. I have a page in JSPX which is using the <spring:message>
tag to resolve strings from a message.properties
file. This works fine for the HTML and CSS that is in the JSPX page, however there a javascript file is sourced, and substituting the <spring:message>
tag for the string in there just means that it gets printed out verbatim.
我的 JSPX 像这样获取 javascript:
My JSPX sources the javascript like so:
<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${js}" />
我正在寻找替换字符串的JS如下:
The JS where I'm looking the replace the string is below:
buildList('settings', [{
name: '<spring:message code="proj.settings.toggle" javaScriptEscape="true" />',
id:"setting1",
description: '<spring:message code="proj.settings.toggle.description" javaScriptEscape="true" />',
installed: true
}]);
最后 message.properties 类似于:
And finally the message.properties is something like:
proj.settings.toggle=Click here to toggle
proj.settings.toggle.description=This toggles between on and off
所以我想知道的是,这应该有效吗?从我在各种论坛上收集的信息来看,在我看来应该是这样,但我无法弄清楚我哪里出错了.有没有更好的方法来解决这个问题?
So what I'm wondering is, should this work? It seems to me like it should, from what I've gathered on various forums, but I can't figure out where I'm going wrong. Is there a better way to go about this?
我还应该注意这些文件在 WEB-INF 文件夹之外,但是通过将 ReloadableResourceBundleMessageSource 放在根 applicationContext.xml 中,弹簧标签被拾取.
I should also note that these files are outside the WEB-INF folder, but by placing the ReloadableResourceBundleMessageSource in the root applicationContext.xml the spring tags are picked up.
感谢您的帮助!
推荐答案
在我看来,您要做的是将 JS 文件视为 JSP 文件并通过 spring:message 标签解析其内容.
我不会那样做.
It seems to me that what you want to do is to treat JS file like JSP file and resolve its contents via spring:message tag.
I would not do that.
通常 JS i18n 以两种方式之一完成:
Typically JS i18n is done in one of two ways:
- 通过从 JSP 页面写出翻译字符串数组
- 通过创建翻译过滤器并将预翻译的 JS 文件提供给请求的客户端
如果您为客户端可翻译字符串创建一个中心位置,这两种方法的效果最好.
在您的上下文中,我会推荐第一种方法(更容易).除非您的项目非常大,并且您在客户端有 很多 可翻译的字符串.所以修改看起来像:
Both works best if you create one central location for your client-side translatable strings.
In your context, I would recommend the first method (much easier). That is unless your project is pretty large and you have a lot of translatable strings on the client side. So the modification would look like:
<script type="text/javascript">
var strings = new Array();
strings['settings.toogle'] = "<spring:message code='proj.settings.toggle' javaScriptEscape='true' />";
strings['settings.toogle.description'] = "<spring:message code='proj.settings.toggle.description' javaScriptEscape='true' />";
</script>
<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${js}" />
在你的 JS 文件中:
And in your JS file:
buildList('settings', [{
name: strings['settings.toggle'],
id:"setting1",
description: strings['settings.toggle.description'],
installed: true
}]);
请注意,我使用双引号来写出翻译后的字符串.这是因为法语或意大利语中的某些单词可能包含撇号.
Mind you that I used double quotes for writing out translated strings. That is because of some words in French or Italian that could contain apostrophe.
出于这个原因,我们提供了对 JS 文件的翻译.通常,原因是我们想要动态地创建 UI 的某些部分.在某些情况下,我们需要本地化一些 3rd 方组件,我上面的回答很好地解决了它们.
对于我们想要动态创建 UI 部件的情况,使用模板而不是在 JavaScript 中连接 HTML 标记真的很有意义.我决定写这个,因为它提供了更清洁(并且可能可重复使用)的解决方案.
因此,与其将翻译传递给 JavaScript,不如创建一个模板并将其放在页面上(我的示例将使用 Handlebars.js,但我相信可以使用任何其他引擎):
We provide translations to JS files for the reason. Usually, the reason is we want to create some part of UI dynamically. There are also cases where we need to localize some 3rd party component, my answer above deals with them pretty well.
For cases where we want to create UI parts dynamically, it really make sense to use templates rather than concatenate HTML tags in JavaScript. I decided to write this, because it makes for much cleaner (and possibly reusable) solution.
So instead of passing translations to JavaScript one may create a template and put it on the page (my example will use Handlebars.js, but I believe it is possible to use any other engine):
<script id="article" type="text/x-handlebars-template">
<div class="head">
<p>
<span>
<spring:message code="article.subject.header" text="Subject: " />
</span>{{subject}}</p>
</div>
<div class="body">
{{{body}}}
</div>
</script>
在客户端(即在 JavaScript 中),您所要做的就是访问模板(下面的示例显然使用 jQuery)并编译:
On the client side (that is in JavaScript) all you have to do is to access the template (example below obviously uses jQuery) and compile:
var template = Handlebars.compile($("#article").html());
var html = template({subject: "It is really clean",
body: "<p>Don't you agree?</p><p>It looks much better than usual spaghetti with JavaScript variables.</p>"
});
$("#someDOMReference").html(html);
这里有几点需要注意:
<spring:message/>
标签默认同时转义 HTML 和 JS,我们不需要指定javaScriptEscape
属性- 为
<spring:message/>
标签提供text
属性是有意义的,因为它可以用作后备(如果没有翻译对于给定的语言)以及注释(这个元素代表什么).甚至可以创建一个工具来扫描文件中的<spring:message/>
标签并自动生成属性文件 - 为了防止 Handlebars 转义 HTML 内容,我使用了三元组
{{{大括号}}}
<spring:message />
tags escape both HTML and JS by default, we do not need to specify thejavaScriptEscape
attribute- It make sense to provide
text
attribute for<spring:message />
tag as it could be used as a fall-back (if there is no translation for given language) as well as a comment (what this element stands for). One can even create a tool that would scan files for<spring:message />
tags and automatically generate properties files - To prevent Handlebars from escaping HTML contents, I used triple
{{{curly braces}}}
基本上就是这样.如果可能的话,我建议使用模板.
That's basically it. I recommend using templates if that's possible.
相关文章