JSF / Facelets中的国际化标签

时间:2020-03-05 18:59:38  来源:igfitidea点击:

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,因此性能应该还可以。