2008-09-17 14 views
5

¿Tiene Facelets 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?Etiquetas internacionalizadas en JSF/Facelets

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 mensajes que se parece 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 un montón de desorden para emitir una frase, solo el tipo de cosas que le dan un mal nombre a JSF.

Respuesta

3

Usted puede crear su biblioteca de etiquetas propias caras para que sea menos detallado, algo así como:

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

continuación, crear el taglib en su opinión 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/componentes/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 pueda encontrar una forma elegante de pasar los argumentos con un poco de investigación.

Ahora registrar su nuevo taglib en web.xml

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

Sólo tiene que añadir xmlns:ph="http://peterhilton.com/core" a sus puntos de vista y ya está todo listo!

+0

Buena respuesta, y cerca de lo que hemos hecho hasta ahora. El problema principal es que no puedes usarlo dentro de los valores de los atributos. –

-1

Utilice ResourceBundle y archivos de propiedades.

+0

¿Podrías explicar un poco más? No sé a qué te refieres, ya que OP ya dijo que lo está usando. – Sietse

3

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.

3

He estado pensando en esto más, y se me ocurre que probablemente podría escribir mi propia función JSTL que tiene 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 mensajes HTML codifica el resultado antes de la salida, que ni siquiera necesita usar el h: outputText

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

Si haces esto y lo haces funcionar, por favor envíame un correo electrónico con el codez;) En serio, sería un gran recurso si pudieras liberarlo en alguna parte. –

5

Dado que está utilizando Seam, you can use 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 sigue utilizando outputFormat, pero es menos detallado.

+0

La única limitación de este enfoque es que está vinculado al uso de esta etiqueta con # {widgetCount} o tiene que expulsar explicitamente "widgetCount" para usarlo. – Damo

3

Puede utilizar la costura interpolador:

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

Ha @BypassInterceptors en él lo que el rendimiento debe ser aceptable.

1

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.

Ésta funciona muy bien el uso de primavera:

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

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

Saludos

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

Tenga cuidado: puede causar un ciclo sin fin, sepa lo que hace. –