Pergunta

O Facelets tem todas as características para mais puro ou rótulos internacionalizados mais legíveis texto de interface de usuário que o que você caso contrário pode fazer usando JSF?

Por exemplo, com JSF simples, usando h:. OutputFormat é uma maneira muito detalhada para variáveis ??Interpolar em mensagens

Esclarecimento: Eu sei que eu posso adicionar uma entrada de arquivo de mensagem que se parece com:

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

e exibir este (se eu estou usando Seam) com:

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

mas isso é um monte de lixo para a saída de uma frase -. Exatamente o tipo de coisa que dá JSF um mau nome

Foi útil?

Solução

Você pode criar sua própria biblioteca rostos tag para torná-lo menos extenso, algo como:

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

Em seguida, crie o taglib na sua opinião 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>

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

Você pode provavelmente encontrar uma maneira elegante de passar os argumentos com um pouco de pesquisa.

Agora registrar seu novo taglib em web.xml

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

Basta adicionar xmlns:ph="http://peterhilton.com/core" a seus pontos de vista e está tudo pronto!

Outras dicas

Uma vez que você estiver usando Seam, você pode usar EL no arquivo de mensagens.

propriedade:

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

XHTML:

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

Este ainda usa outputFormat, mas é menos detalhada.

Eu nunca me deparei com uma outra maneira de fazê-lo diferente de outputFormat. Infelizmente, é bastante detalhado.

A única outra coisa que posso sugerir é criar a mensagem em um bean de apoio e, em seguida, a saída que ao invés de MessageFormat.

No meu caso eu tenho MessageSource da Primavera integrado com JSF (usando MessageSourcePropertyResolver ). Então, é bastante fácil em seus beans de apoio para obter mensagens parametrizados - você só precisa saber que Locale seu usuário está em (novamente, eu tenho o Locale vinculado a uma propriedade backing bean por isso é acessível através JSF ou Java) <. / p>

Eu acho parâmetros - particulares em mensagens - são uma coisa JSF poderia realmente fazer melhor

!

Eu estive pensando sobre isso mais, e ocorre-me que eu provavelmente poderia escrever minha própria função JSTL que leva uma chave de mensagem e um número variável de parâmetros:

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

e se a minha função de mensagem HTML-codifica o resultado antes da saída, eu não teria sequer precisa usar o h: outputText

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

Você pode usar o Seam Interpolator:

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

Tem @BypassInterceptors sobre ele para que o desempenho deve ser ok.

Você pode usar o feijão diretamente se você interpolar as mensagens.

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

Este funciona muito bem 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;
    }
}

E ...

Você precisa mudar o EL-Resolver em faces-config.xml de org.springframework.web.jsf.el.SpringBeanFacesELResolver para

Saudações

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

Use arquivos ResourceBundle e propriedade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top