Pregunta

Hace facetas ¿Tiene alguna característica para etiquetas de texto de interfaz de usuario internacionalizadas más ordenadas o más legibles que lo que de otro modo podría hacer usando JSF?

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

Aclaración: Sé que puedo agregar una entrada de archivo de mensaje similar a:

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 mucho desorden para generar una oración, justo el tipo de cosas que le dan mala fama a JSF.

¿Fue útil?

Solución

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

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

Luego cree el taglib en su directorio de vista:/componentes/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 manera elegante de transmitir 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 puntos de vista y ¡listo!

Otros consejos

Ya que estás usando Seam, puedes usar EL en el archivo de mensajes.

Propiedad:

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

HTML:

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

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

Nunca encontré 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 MessageSource de Spring integrado con JSF (usando MensajeFuentePropertyResolver).Entonces, es bastante fácil en sus beans de respaldo obtener mensajes parametrizados; solo necesita saber en qué configuración regional se encuentra su usuario (nuevamente, tengo la configuración regional vinculada a una propiedad del bean de respaldo para que sea accesible a través de JSF o Java).

Creo que los parámetros, particularmente en los mensajes, son algo que JSF realmente podría hacer mejor.

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

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

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

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

Puede utilizar el interpolador de costuras:

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

Tiene @BypassInterceptors, por lo que el rendimiento debería ser bueno.

Puede utilizar el 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 suficiente.

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...

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

Saludos

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

Utilice ResourceBundle y archivos de propiedades.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top