2008-09-17 4 views
5

Имеет ли функции Facelets какие-либо функции для более аккуратных или более читаемых интернационализированных текстовых меток пользовательского интерфейса, которые вы можете использовать с помощью JSF?Интернационализированные этикетки в JSF/Facelets

Например, с открытым 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 плохое имя.

ответ

3

Вы можете создать свой собственный рожи библиотеку тегов, чтобы сделать его менее многословным, что-то вроде:

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

создать/компоненты/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> 

Возможно, вы можете найти элегантный способ передачи аргументов с небольшим исследованием.

Теперь зарегистрировать новый TagLib в 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" в ваши взгляды, и вы все готово!

+0

Хороший ответ, и близко к тому, что мы сделали до сих пор. Основная проблема заключается в том, что вы не можете использовать его внутри значений атрибутов. – 2009-03-19 16:50:26

-1

Используйте ResourceBundle и файлы свойств.

+0

Не могли бы вы объяснить немного больше? Я не знаю, что вы имеете в виду, поскольку ОП уже сказал, что использует это. – Sietse 2008-09-19 08:35:03

3

Я никогда не сталкивался с другим способом делать это иначе, чем outputFormat. Это, к сожалению, довольно многословно.

Единственное, что я могу предложить, это создать сообщение в бэкэнде и затем вывести его, а не messageFormat.

В моем случае у меня есть источник сообщений Spring, интегрированный с JSF (с использованием MessageSourcePropertyResolver). Затем в ваших бэкэн-бэндах довольно легко получить параметризованные сообщения - вам просто нужно знать, в какой Locale ваш пользователь (опять же, у меня есть Locale, привязанный к свойству бэкэнд-бэка, чтобы он был доступен через JSF или Java).

Я думаю, что параметры - особенно в сообщениях - это одно, что JSF действительно может сделать лучше!

3

Я думал об этом больше, и это происходит со мной, что я мог бы написать свою собственную функцию JSTL, которая принимает ключ сообщения и переменное число параметров:

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

и если моя функция сообщения HTML кодирует результат до выхода, я даже не нужно будет использовать час: outputText

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

Если вы сделаете это и заработаете, напишите мне по электронной почте:) Серьезно, но это был бы отличный ресурс, если бы вы могли его выпустить. – 2008-09-19 08:42:20

5

Поскольку вы используете Шов, you can use EL в файле сообщений.

недвижимости:

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

XHTML:

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

Это все еще использует OUTPUTFORMAT, но менее многословным.

+0

Единственным ограничением этого подхода является то, что вы привязаны к использованию этой метки с # {widgetCount} или вам нужно явно вывести «widgetCount», чтобы использовать ее. – Damo 2009-04-07 12:10:12

3

Вы можете использовать Seam интерполятор:

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

Он @BypassInterceptors на него, так что производительность должна быть в порядке.

1

Вы можете использовать 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']} is enougth.

Это один прекрасно работает с использованием 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-Разрешитель в faces-config.xml от org.springframework.web.jsf.el.SpringBeanFacesELResolver к

С уважением

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

Позаботьтесь: может вызвать бесконечную петлю, знать, что вы делаете. – 2014-02-16 06:54:19

Смежные вопросы