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带来坏名声的东西。
答案 0 :(得分:5)
由于您在消息文件中使用了Seam,you can use EL。
属性:
label.widget.count = You have a total of #{widgetCount} widgets.
XHTML:
<h:outputFormat value="#{messages['label.widget.count']}" />
这仍然使用outputFormat,但不那么详细。
答案 1 :(得分:3)
除了outputFormat之外,我从未遇到过其他方式。不幸的是,它非常冗长。
我可以建议的唯一另一件事是在支持bean中创建消息,然后输出而不是messageFormat。
在我的例子中,我将Spring的MessageSource与JSF集成(使用MessageSourcePropertyResolver)。然后,在您的支持bean中获取参数化消息相当容易 - 您只需要知道您的用户所在的Locale(同样,我已经将Locale绑定到支持bean属性,因此可以通过JSF或Java访问它)。 / p>
我认为参数 - 特别是在消息中 - 是JSF真正做得更好的一件事!
答案 2 :(得分:3)
我一直在考虑这个问题,而且我可能会编写自己的JSTL函数来获取消息键和可变数量的参数:
<h:outputText value="#{my:message('label.widget.count', widgetCount)}"/>
如果我的消息函数在输出之前对结果进行HTML编码,我甚至不需要使用h:outputText
#{my:message('label.widget.count', widgetCount)}
答案 3 :(得分:3)
您可以创建自己的面部标记库,使其更简洁,例如:
<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"
添加到您的观看中即可完成设置!
答案 4 :(得分:3)
您可以使用Seam Interpolator:
<h:outputText value="#{interpolator.interpolate(messages['label.widget.count'], widgetCount)}"/>
它上面有@BypassInterceptors,所以性能应该没问题。
答案 5 :(得分:1)
如果插入消息,可以直接使用Bean。
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可以很好地使用它:
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解析器从org.springframework.web.jsf.el.SpringBeanFacesELResolver
更改为
此致
<el-resolver>foo.ELResolver</el-resolver>
答案 6 :(得分:-1)
使用ResourceBundle和属性文件。