문제

하다 페이스렛 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에 나쁜 이름을 주는 종류의 일입니다.

도움이 되었습니까?

해결책

다음과 같이 자신만의 얼굴 태그 라이브러리를 만들어 덜 장황하게 만들 수 있습니다.

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

그런 다음 뷰 디렉터리에 taglib를 만듭니다./구성 요소/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>

/comComponents/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" 귀하의 견해에 따라 모든 준비가 완료되었습니다!

다른 팁

Seam을 사용하고 있으므로 EL을 사용할 수 있습니다 메시지 파일에 있습니다.

재산:

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

XHTML:

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

이것은 여전히 ​​​​outputFormat을 사용하지만 덜 장황합니다.

나는 OutputFormat 이외의 다른 방법을 본 적이 없습니다.불행히도 매우 장황합니다.

내가 제안할 수 있는 유일한 다른 방법은 Backing Bean에서 메시지를 생성한 다음 messageFormat 대신 이를 출력하는 것입니다.

내 경우에는 JSF와 통합된 Spring의 MessageSource를 사용합니다. MessageSourcePropertyResolver).그러면 Backing Bean에서 매개변수화된 메시지를 얻는 것이 매우 쉽습니다. 사용자가 어떤 Locale에 있는지 알기만 하면 됩니다. (역시 JSF 또는 Java를 통해 액세스할 수 있도록 Backing Bean 속성에 바인딩된 Locale이 있습니다.)

내 생각에는 매개변수(특히 메시지의 경우)가 JSF가 실제로 더 잘할 수 있는 일 중 하나라고 생각합니다!

나는 이것에 대해 더 많이 생각해 왔으며 아마도 메시지 키와 가변 개수의 매개 변수를 사용하는 내 자신의 JSTL 함수를 작성할 수 있다는 생각이 들었습니다.

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

내 메시지 기능이 출력 전에 결과를 HTML로 인코딩하는 경우 h:outputText를 사용할 필요조차 없습니다.

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

Seam Interpolator를 사용할 수 있습니다.

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

@BypassInterceptors가 있으므로 성능은 괜찮을 것입니다.

메시지를 삽입하면 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;
    }
}

그리고...

EL-Resolver를 변경해야 합니다. faces-config.xml ~에서 org.springframework.web.jsf.el.SpringBeanFacesELResolver 에게

문안 인사

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

ResourceBundle 및 속성 파일을 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top