質問

する ファセット 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>

しかし、これは 1 つの文を出力するのに非常に煩雑であり、JSF に悪名を与えるようなものです。

役に立ちましたか?

解決

次のような独自の顔タグ ライブラリを作成して、冗長さを軽減することもできます。

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

次に、ビュー ディレクトリに taglib を作成します。/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>

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

おそらく、少し調べれば、議論を渡すエレガントな方法が見つかるでしょう。

次に、新しいタグライブラリを web.xml に登録します。

<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以外にそれを行う別の方法に出会ったことがありません。残念ながら、かなり冗長です。

他に提案できる唯一のことは、バッキング Bean でメッセージを作成し、それを messageFormat ではなく出力することです。

私の場合、Spring の MessageSource を JSF と統合しています (使用 MessageSourcePropertyResolver)。次に、バッキング Bean でパラメータ化されたメッセージを取得するのは非常に簡単です。必要なのは、ユーザーがどのロケールに属しているかを知ることだけです (繰り返しになりますが、ロケールをバッキング Bean プロパティにバインドしてあり、JSF または Java 経由でアクセスできるようにしています)。

パラメーター (特にメッセージ) は、JSF が本当に改善できる点の 1 つだと思います。

これについてさらに考えてみたところ、おそらくメッセージ キーと可変数のパラメーターを受け取る独自の JSTL 関数を作成できるのではないかと思いつきました。

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

また、メッセージ関数が出力前に結果を HTML エンコードする場合は、 h:outputText を使用する必要さえありません。

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

シーム補間器を使用できます。

<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