template define java jsf internationalization facelets

java - define - ui:composition primefaces



Etiquetas internacionalizadas en JSF/Facelets (7)

¿ Facelets tiene alguna característica para las etiquetas de texto de interfaz de usuario internacionalizadas más legibles o más legibles que lo que puede hacer con JSF?

Por ejemplo, con JSF simple, el uso de h: outputFormat es una forma muy detallada de interpolar variables en los mensajes.

Aclaración: sé que puedo agregar una entrada de archivo de mensaje que se ve así:

label.widget.count = You have a total of {0} widgets.

y mostrar esto (si estoy usando Seam) con:

<h:outputFormat value="#{messages[''label.widget.count'']}"> <f:param value="#{widgetCount}"/> </h:outputFormat>

pero eso es un montón de desorden para emitir una frase, solo el tipo de cosas que le dan un mal nombre a JSF.


Nunca me he encontrado con otra forma de hacerlo que no sea outputFormat. Desafortunadamente es bastante detallado.

La única otra cosa que puedo sugerir es crear el mensaje en un bean de respaldo y luego generarlo en lugar de messageFormat.

En mi caso, tengo el MessageSource de Spring integrado con JSF (usando MessageSourcePropertyResolver ). Entonces, es bastante fácil en sus respaldos obtener mensajes parametrizados; solo necesita saber en qué configuración regional está su usuario (de nuevo, tengo el Locale ligado a una propiedad de bean de respaldo para que sea accesible a través de JSF o Java).

Creo que los parámetros, en particular en los mensajes, ¡son una cosa que JSF realmente podría hacer mejor!


Use ResourceBundle y archivos de propiedades.


Como usa Seam, puede usar EL en el archivo de mensajes.

Propiedad:

label.widget.count = You have a total of #{widgetCount} widgets.

XHTML:

<h:outputFormat value="#{messages[''label.widget.count'']}" />

Esto todavía usa outputFormat, pero es menos detallado.


He estado pensando en esto más, y se me ocurre que probablemente podría escribir mi propia función JSTL que toma una clave de mensaje y una cantidad variable de parámetros:

<h:outputText value="#{my:message(''label.widget.count'', widgetCount)}"/>

y si mi función de mensaje HTML-codifica el resultado antes de la salida, ni siquiera necesitaría usar el h: outputText

#{my:message(''label.widget.count'', widgetCount)}


Puede crear su propia biblioteca de etiquetas de caras para que sea menos detallada, algo así como:

<ph:i18n key="label.widget.count" p0="#{widgetCount}"/>

Luego crea el taglib en tu vista dir: /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>

crear /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>

Probablemente puedas encontrar una forma elegante de pasar los argumentos con un poco de investigación.

Ahora registre su nuevo taglib en web.xml

<context-param> <param-name>facelets.LIBRARIES</param-name> <param-value> /components/ph.taglib.xml </param-value> </context-param>

Solo agrega xmlns:ph="http://peterhilton.com/core" a tus vistas y listo.


Puede usar el Interpolador de costura:

<h:outputText value="#{interpolator.interpolate(messages[''label.widget.count''], widgetCount)}"/>

Tiene @BypassInterceptors en él así que el rendimiento debería estar bien.


Puede usar Bean directamente si interpola los mensajes.

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'']} es enougth.

Este funciona muy bien usando 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; } }

Y...

org.springframework.web.jsf.el.SpringBeanFacesELResolver cambiar el EL-Resolver en faces-config.xml desde org.springframework.web.jsf.el.SpringBeanFacesELResolver a

Saludos

<el-resolver>foo.ELResolver</el-resolver>