一尘不染

解析Spring:使用JavaScript进行i18n国际化的消息

spring

我正在尝试使我们的某些代码国际化。我在JSPX中有一个页面,该页面正在使用<spring:message>标记来解析message.properties文件中的字符串。对于JSPX页面中的HTML和CSS来说,这很好用,但是有一个javascript文件,并且<spring:message>在那里用标记代替字符串只是意味着它被逐字打印出来。

我的JSPX像这样提供javascript:

<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${js}" />

我正在寻找替换字符串的JS如下:

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类似于:

proj.settings.toggle=Click here to toggle
proj.settings.toggle.description=This toggles between on and off

所以我想知道的是,这应该工作吗?从我在各种论坛上收集到的信息来看,我觉得应该这样做,但我不知道哪里出了问题。有没有更好的方法来解决这个问题?

我还应该注意,这些文件在WEB-INF文件夹之外,但是通过将ReloadableResourceBundleMessageSource放在根applicationContext.xml中,可以拾取spring标记。

谢谢你的帮助!


阅读 569

收藏
2020-04-18

共1个答案

一尘不染

在我看来,你想要做的就是将JS文件像JSP文件一样对待,并通过spring:message标签解析其内容。
我不会那样做。

通常,JS i18n通过以下两种方式之一完成:

  • 通过从JSP页面写出翻译后的字符串数组
  • 通过创建翻译过滤器并向请求的客户端提供预翻译的JS文件

如果你为客户端可翻译字符串创建一个中心位置,则两种方法都效果最好。
在你的情况下,我建议第一种方法(容易得多)。除非你的项目很大,并且在客户端上有很多可翻译的字符串,否则这是不可行的。因此,修改如下所示:

<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文件中:

buildList('settings', [{
    name: strings['settings.toggle'],
    id:"setting1",
    description: strings['settings.toggle.description'],
    installed: true
}]);

请注意,我使用双引号写出翻译后的字符串。那是因为法语或意大利语中的某些单词可能包含撇号。

编辑:附加输入
由于这个原因,我们提供了JS文件的翻译。通常,原因是我们要动态创建UI的某些部分。在某些情况下,我们需要本地化一些第三方组件,上面我的回答很好地解决了这些问题。
对于我们要动态创建UI部件的情况,使用模板而不是在JavaScript中连接HTML标签确实很有意义。我决定写这篇文章,因为它使解决方案更加简洁(并且可能可重用)。
因此,可以将模板传递到JavaScript而不是将翻译传递给JavaScript(我的示例将使用Handlebars.js,但我相信可以使用任何其他引擎):

<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)并进行编译:

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属性
  • text为<spring:message />标签提供属性是有意义的,因为它可以用作后备(如果给定语言没有翻译)以及注释(此元素代表什么)。甚至可以创建一种工具,该工具将扫描文件中的<spring:message />标签并自动生成属性文件
  • 为防止把手逃脱HTML内容,我使用了三重 {{{curly braces}}}
    基本上就是这样。我建议尽可能使用模板。
2020-04-18