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

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

问题描述

我试图使我们的一些代码国际化。我在JSPX中有一个页面,它使用< spring:message> 标签来从 message.properties 文件。这可以适用于JSPX页面中的HTML和CSS,但是有一个javascript文件来源,并将< spring:message> 标记替换为字符串中的只是意味着逐字地打印出来。



我的JSPX源代码是这样的:

  :theme code =jsFilevar =js/> 
< script type =text / javascriptsrc =$ {js}/>

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

  buildList('settings',[{
name:'< spring:message code =proj.settings.togglejavaScriptEscape =true />',
id:setting1,
description:'< spring:message code =proj.settings.toggle.descriptionjavaScriptEscape =true/>',
installed:true
}]);

最后,message.properties类似于:

  proj.settings.toggle =点击此处切换
proj.settings.toggle.description =此开关之间切换

所以我想知道的是,应该这样吗?在我看来,我应该从我在各种论坛上收集到的东西,但是我无法确定出错的地方。有没有更好的方法来解决这个问题?



我还应该注意到,这些文件在WEB-INF文件夹之外,而是将ReloadableResourceBundleMessageSource放在根applicationContext中。




感谢任何帮助!

解决方案

在我看来,你想做的就是像JSP文件一样处理JS文件,并通过spring来解决它的内容:message tag。

我不会这样做。



通常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 =jsFilevar =js/>
< script type =text / javascriptsrc =$ {js}/>

在您的JS文件中:

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

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



编辑:附加输入



提供翻译到JS文件的原因。通常,原因是我们想要动态地创建UI的一部分。还有一些情况我们需要本地化一些第三方组件,我的上面的答案很好地处理它们。

对于我们要动态创建UI部分的情况,使用模板真的很有意义在JavaScript中连接HTML标签。我决定写这个,因为它使得更清洁(可能可重用)的解决方案。

所以,而不是将翻译传递给JavaScript,可以创建一个模板并将其放在页面上(我的例子将使用< a href =http://handlebarsjs.com/> Handlebars.js ,但我相信可以使用任何其他引擎):

 < script id =articletype =text / x-handlebars-template> 
< div class =head>
< p>
< span>
< spring:message code =article.subject.headertext =Subject:/>
< / span> {{subject}}< / p>
< / div>
< div class =body>
{{body}}}
< / div>
< / script>

在客户端(即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,我们不需要指定对于$ code>

  • 提供 text 属性是有意义的:message /> 标签,因为它可以用作回退(如果没有给定语言的翻译)以及注释(此元素代表什么)。甚至可以创建一个工具来扫描< spring:message /> 标签的文件,并自动生成属性文件

  • 防止Handlebars转义HTML内容,我使用了三个 {{{curly braces}}}


$ b $基本上是这样的。我建议使用模板。


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.

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

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