JSF / Facelets中的国际化标签
Facelets是否具有用于整洁或者更易读的国际化用户界面文本标签的功能,而这些功能我们可以使用JSF来完成?
例如,对于纯JSF,使用h:outputFormat是在消息中插入变量的非常冗长的方法。
澄清:我知道我可以添加一个如下所示的消息文件条目:
label.widget.count = You have a total of {0} widgets.
并显示以下内容(如果我使用的是Seam):
<h:outputFormat value="#{messages['label.widget.count']}"> <f:param value="#{widgetCount}"/> </h:outputFormat>
但是输出一个句子很麻烦,这只是让JSF取一个不好的名字而已。
解决方案
回答
使用ResourceBundle和属性文件。
回答
除了outputFormat之外,我再也没有遇到过其他方法。不幸的是,它很冗长。
我只能建议的另一件事是在支持bean中创建消息,然后输出该消息而不是messageFormat。
就我而言,我将Spring的MessageSource与JSF集成在一起(使用MessageSourcePropertyResolver)。然后,在支持bean中获取参数化消息非常简单,我们只需要知道用户所在的语言环境即可(同样,我将Locale绑定到支持bean属性,因此可以通过JSF或者Java进行访问)。
我认为消息中特定的参数是JSF确实可以做得更好的一件事!
回答
我一直在考虑这个问题,我想到我可能可以编写自己的JSTL函数,该函数需要一个消息密钥和可变数量的参数:
<h:outputText value="#{my:message('label.widget.count', widgetCount)}"/>
并且如果我的消息函数在输出之前对结果进行HTML编码,那么我什至不需要使用h:outputText
#{my:message('label.widget.count', widgetCount)}
回答
由于我们正在使用Seam,因此可以在消息文件中使用EL。
财产:
label.widget.count = You have a total of #{widgetCount} widgets.
XHTML:
<h:outputFormat value="#{messages['label.widget.count']}" />
它仍然使用outputFormat,但是不太冗长。
回答
我们可以创建自己的faces标签库,以使其不再那么冗长,例如:
<ph:i18n key="label.widget.count" p0="#{widgetCount}"/>
然后在视图目录中创建taglib:/components/ph.taglib.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "https://facelets.dev.java.net/source/browse/*checkout*/facelets/src/etc/facelet-taglib_1_0.dtd"> <facelet-taglib xmlns="http://java.sun.com/JSF/Facelet"> <namespace>http://peterhilton.com/core</namespace> <tag> <tag-name>i18n</tag-name> <source>i18n.xhtml</source> </tag> </facelet-taglib>
创建/components/i18n.xhtml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:outputFormat value="#{messages[key]}"> <!-- crude but it works --> <f:param value="#{p0}" /> <f:param value="#{p1}" /> <f:param value="#{p2}" /> <f:param value="#{p3}" /> </h:outputFormat> </ui:composition>
通过一些研究,我们可能会找到一种传递论点的优雅方法。
现在,在web.xml中注册新的taglib
<context-param> <param-name>facelets.LIBRARIES</param-name> <param-value> /components/ph.taglib.xml </param-value> </context-param>
只需在视图中添加xmlns:ph =" http://peterhilton.com/core"`就可以了!
回答
我们可以使用接缝插值器:
<h:outputText value="#{interpolator.interpolate(messages['label.widget.count'], widgetCount)}"/>
它上面有@BypassInterceptors,因此性能应该还可以。