解决 spring:i18n 国际化的 javascript 中的消息 [英] Resolving spring:messages in javascript for i18n internationalization

查看:35
本文介绍了解决 spring:i18n 国际化的 javascript 中的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我的 JSPX 像这样获取 javascript:

<script type="text/javascript" src="${js}"/>

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

buildList('设置', [{name: '<spring:message code="proj.settings.toggle" javaScriptEscape="true"/>',id:"setting1",描述:'<spring:message code="proj.settings.toggle.description" javaScriptEscape="true"/>',已安装:真}]);

最后 message.properties 是这样的:

proj.settings.toggle=点击这里切换proj.settings.toggle.description=这在开和关之间切换

所以我想知道的是,这是否可行?从我在各种论坛上收集的信息来看,在我看来应该是这样,但我无法弄清楚我哪里出错了.有没有更好的方法来解决这个问题?

我还应该注意,这些文件在 WEB-INF 文件夹之外,但是通过将 ReloadableResourceBundleMessageSource 放在根 applicationContext.xml 中,spring 标签会被选中.

感谢您的帮助!

解决方案

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

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

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

如果您为客户端可翻译字符串创建一个中心位置,则两者都能发挥最佳效果.
在您的上下文中,我会推荐第一种方法(更容易).除非您的项目非常大并且在客户端有很多可翻译的字符串.所以修改看起来像:

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

在你的 JS 文件中:

buildList('设置', [{名称:字符串['settings.toggle'],id:"setting1",描述:字符串['settings.toggle.description'],已安装:真}]);

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

附加输入

出于这个原因,我们提供了 JS 文件的翻译.通常,原因是我们想动态创建 UI 的某些部分.还有一些情况我们需要本地化一些 3rd 方组件,我上面的回答很好地处理了它们.
对于我们想要动态创建 UI 部件的情况,使用模板而不是在 JavaScript 中连接 HTML 标签确实很有意义.我决定写这个,因为它提供了更清洁(并且可能可重用)的解决方案.
因此,与其将翻译传递给 JavaScript,不如创建一个模板并将其放在页面上(我的示例将使用 Handlebars.js,但我相信它可以使用任何其他引擎):

在客户端(即 JavaScript 中),您所要做的就是访问模板(下面的示例显然使用 jQuery)并编译:

var template = Handlebars.compile($("#article").html());var html = template({subject: "它真的很干净",body: "<p>你不同意吗?</p><p>它看起来比带有 JavaScript 变量的普通意大利面好多了.</p>"});$("#someDOMReference").html(html);

这里有几点需要注意:

  • <spring:message/> 标签默认同时转义 HTML 和 JS,我们不需要指定 javaScriptEscape 属性
  • <spring:message/> 标签提供 text 属性是有意义的,因为它可以用作后备(如果没有翻译对于给定的语言)以及注释(此元素代表什么).甚至可以创建一个工具来扫描文件中的 <spring:message/> 标签并自动生成属性文件
  • 为了防止 Handlebars 转义 HTML 内容,我使用了三个 {{{花括号}}}

基本上就是这样.如果可能,我建议使用模板.

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.

My JSPX sources the javascript like so:

<spring:theme code="jsFile" var="js" />
<script type="text/javascript" src="${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
}]);

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?

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.

Thanks for any help!

解决方案

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.

Typically JS i18n is done in one of two ways:

  • By writing out Array of translated strings from JSP page
  • By creating translation filter and provide pre-translated JS file to requesting client

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}" />

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.

Edit: Additional input

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>

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);

Few things to note here:

  • <spring:message /> tags escape both HTML and JS by default, we do not need to specify the javaScriptEscape 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.

这篇关于解决 spring:i18n 国际化的 javascript 中的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆