2015-04-07 33 views
6

Mam projekt Spring MVC, który wykorzystuje płytki Apache. I wprowadziły tak że tytuły mogą być odczytane ze źródła wiadomości jak ta:Obsługa dynamicznych i przetłumaczonych tytułów w Apache Tiles

<tiles-definitions>  
    <definition name="some-definition" extends="public.base"> 
     <put-attribute name="title" value="some-definition.title" cascade="true" /> 
    </definition> 
</tiles-definitions> 

I w moim pliku szablonu (zdefiniowanej przez public.base), mam następujące:

<title><spring:message text="" code="${title}" /></title> 

Teraz to działa świetnie dla statycznych przetłumaczonych tytułów, ale chcę też wspierać dynamiczne tytuły, np do wyświetlania nazwy firmy. mogę to zrobić tak:

<tiles-definitions>  
    <definition name="some-definition" extends="public.base"> 
     <put-attribute name="title" expression="${company.name}" /> 
    </definition> 
</tiles-definitions> 

a następnie po prostu wyjście tytuł w moim szablonu takich jak to: <c:out value="${title}" />. Jednak problem polega na tym, że mój kod ulega uszkodzeniu, ponieważ wartość atrybutu title nie jest już kluczem komunikatu. Chcę mieć możliwość obsługi następujących scenariuszy:

  1. Statyczne tytuły, np. "O nas"
  2. Czysto dynamiczne tytuły, np. "$ {company.name}"
  3. Dynamiczne tytuły z przetłumaczoną treścią, np. "Witamy w $ {nazwa firmy}"

Idealnie mógłbym użyć języka wyrażenia w obrębie mojego źródła wiadomości, ale nie mogłem tego zrobić. Wiele eksperymentowałem z różnymi rozwiązaniami, ale nie mogę znaleźć przyzwoitego. Gdybym mógł użyć języka wyrażenia w moim źródle wiadomości, byłoby to łatwe. Na przykład, czy w jakiś sposób można by wykonać następujące czynności?

some-definition.title = Hello there, ${company.name} 

I w moim szablonu:

<spring:message text="" code="some-definition.title" var="test" /> 
<c:out value="${test}" /> 

Powyższe nie działa, jak wyprowadza ${company.name} zamiast rzeczywistej zawartości zmiennej. Czy istnieje sposób na zrobienie czegoś podobnego do tej pracy? Czy są jakieś inne sposoby, w jakie mogę wesprzeć scenariusze wymienione powyżej?

Pomyślałem o stworzeniu niestandardowego znacznika JSTL, w którym chciałbym parsować wyrażenie tekstowe w zwykłym kodzie Java (przetłumaczonym ciągu), ale zdałem sobie sprawę, że prawdopodobnie musiałbym jawnie określić obiekt główny dla "zmiennej" zamiennik "do pracy, as documented here. Wtedy nie wydaje się tak dynamicznym rozwiązaniem.

Czy jest jakiś sposób, w jaki mogę wykonać to zadanie? Każda pomoc jest doceniana!

+0

Witaj, Andy, użyłem Thymeleaf (z Kafelkami) i twoje pytanie przypomina mi o tym, że po raz pierwszy mam do czynienia z wiadomościami: http://www.thymeleaf.org/doc/tutorials/2.1/usingthymaf. html # messages –

+0

Dziękuję za link, @PatrickLC. Masz rację, że tak właśnie robisz i robiłem to w przeszłości. Jednak nadal nie jestem pewien, jak to zrobić w moim konkretnym przypadku użycia, bez konieczności jawnego przekazywania parametrów podczas tłumaczenia tekstu. Może nie być nawet możliwe robienie tego, co chcę, nie jestem pewien. – Andy0708

Odpowiedz

0

czy w ogóle zlokalizowanie pomocy związanej z definicjami płytek? ref http://tiles.apache.org/framework/tutorial/advanced/l10n.html

inaczej spojrzałbym na ViewPreparer, który rozszerza wiadomości wiosenne dla Ciebie.

+1

Zlokalizowane definicje płytek pomagają, jeśli moje tytuły nie zawierają treści dynamicznych. Zastanawiam się nad próbą zaimplementowania ViewPreparer wcześniej i może to być droga. Dziękuję za sugestie! – Andy0708

0

Definicja kafli może definiować atrybut o nazwie 'controllerClass'. Ta klasa powinna implementować interfejs org.apache.struts.tiles.Controller, a jego przesłonięta metoda execute() jest wywoływana przed renderowaniem definicji płytki.

Metoda execute ma uprawnienia do odczytu/zapisu do par nazwy i wartości atrybutów tiles, a także do obiektu HttpServletRequest.Możesz wyszukać atrybut i zmieniać wartości dynamicznie lub zastąpić go wartością semi statyczną z pliku właściwości.

<definition name="some-definition" extends="public.base" controllerClass="pkgName.CustomController"> 
     <put-attribute name="title" expression="${company.name}" /> 
    </definition> 

A potem w swojej klasie CustomController można zmienić atrybuty

public class CustomController implements Controller{ 
     public void execute(ComponentContext tileContext, 
      HttpServletRequest request, HttpServletResponse response, 
      ServletContext servletContext) throws ServletException, IOException {  
      String attrName = (String)tileContext.getAttribute("title"); 
      String attrVal = request.getAttribute("pageTitle"); //get a dynamic value or else retrieve from a resource bundle 
      tileContext.putAttribute(attrName,attrVal); 
    } 

    public void perform(ComponentContext tileContext, 
      HttpServletRequest request, HttpServletResponse response, 
      ServletContext servletContext) throws ServletException, IOException { 
     execute(tileContext, request, response, servletContext); 
    } 
} 
0

Użytkownik nie może używać płytek do tego, juste swoją Spring-Model:

W Kontroler:

@RequestMapping(value = { "/page1" }, method = RequestMethod.GET) 
public String page1() { 
    model.addAttribute("titre_page", messageSource.getMessage("home.hello", null,null) 
} 

In layout.jsp:

... 
<title>${titre_page}</title> 
... 
<tiles:insertAttribute name="body" /> 
....