Facelets是否具有通过使用JSF可以更整洁或更可读的国际化用户界面文本标签的功能?
例如,对于纯JSF,使用h:outputFormat是在消息中插入变量的非常冗长的方法。
说明:我知道我可以添加一个如下所示的消息文件条目:
1
| label.widget.count = You have a total of {0} widgets. |
并显示以下内容(如果我正在使用Seam):
1 2 3
| <h:outputFormat value="#{messages['label.widget.count']}">
<f:param value="#{widgetCount}"/>
</h:outputFormat> |
但是输出一个句子会很混乱-只是那种使JSF不好名的东西。
由于您正在使用Seam,因此可以在消息文件中使用EL。
属性:
1
| label.widget.count = You have a total of #{widgetCount} widgets. |
XHTML:
1
| <h:outputFormat value="#{messages['label.widget.count']}" /> |
这仍然使用outputFormat,但是不太冗长。
您可以使用接缝内插器:
1
| <h:outputText value="#{interpolator.interpolate(messages['label.widget.count'], widgetCount)}"/> |
上面带有@BypassInterceptors,因此性能应该可以。
您可以创建自己的faces标签库,以使其不再那么冗长,例如:
1
| <ph:i18n key="label.widget.count" p0="#{widgetCount}"/> |
然后在视图目录中创建taglib:/components/ph.taglib.xml
1 2 3 4 5 6 7 8 9 10 11 12
| <?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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?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
1 2 3 4 5 6
| <context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>
/components/ph.taglib.xml
</param-value>
</context-param> |
只需将xmlns:ph="http://peterhilton.com/core"添加到您的视图中,便一切就绪!
我一直在考虑这个问题,我想到我可能可以编写自己的JSTL函数,该函数需要一个消息密钥和可变数量的参数:
1
| <h:outputText value="#{my:message('label.widget.count', widgetCount)}"/> |
,如果我的消息功能在输出之前对结果进行HTML编码,则我什至不需要使用h:outputText
1
| #{my:message('label.widget.count', widgetCount)} |
除了outputFormat之外,我再也没有遇到过其他方法。不幸的是,它很冗长。
我只能建议的另一件事是在后备bean中创建消息,然后将其输出而不是messageFormat。
在我的情况下,我将Spring的MessageSource与JSF集成在一起(使用MessageSourcePropertyResolver)。然后,在支持bean中获取参数化消息非常容易-您只需要知道用户所在的语言环境即可(同样,我将Locale绑定到支持bean属性,因此可以通过JSF或Java对其进行访问)。铅>
我认为参数-特别是消息中的参数-是JSF确实可以做得更好的一件事!
如果对消息进行插值,则可以直接使用Bean。
1 2 3
| label.widget.count = You have a total of #{widgetCount} widgets.
label.welcome.message = Welcome to #{request.contextPath}!
label.welcome.url = Your path is ${pageContext.servletContext}. |
${messages['label.widget.count']}是整数。
使用Spring可以很好地工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package foo;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.ResourceBundleELResolver;
import javax.faces.context.FacesContext;
import org.springframework.web.jsf.el.SpringBeanFacesELResolver;
public class ELResolver extends SpringBeanFacesELResolver {
private static final ExpressionFactory FACTORY = FacesContext
.getCurrentInstance().getApplication().getExpressionFactory();
private static final ResourceBundleELResolver RESOLVER = new ResourceBundleELResolver();
@Override
public Object getValue(ELContext elContext, Object base, Object property)
throws ELException {
Object result = super.getValue(elContext, base, property);
if (result == null) {
result = RESOLVER.getValue(elContext, base, property);
if (result instanceof String) {
String el = (String) result;
if (el.contains("${") | el.contains("#{")) {
result = FACTORY.createValueExpression(elContext, el,
String.class).getValue(elContext);
}
}
}
return result;
}
} |
然后...
您需要将faces-config.xml中的EL-Resolver从org.springframework.web.jsf.el.SpringBeanFacesELResolver更改为
致谢
1
| <el-resolver>foo.ELResolver</el-resolver> |
使用ResourceBundle和属性文件。