9

Kontroler:i18n błąd: kontroler i szablony używa różnych językach ukryte

def test = Action { implicit request => 
    import play.api.i18n._ 
    val msg = Messages("error.invalid") 
    implicit val langInController = lang(request) 
    Ok(views.html.test(langInController, msg)) 
} 

Widok:

@(langInController: play.api.i18n.Lang, msg:String)(implicit request: Request[_]) 
<div>Lang from controller: @langInController, Message: @msg</div> 
<div>Message from view: @play.api.i18n.Messages("error.required")</div> 

Wiadomości zasobów, conf/messages.zh-CN:

error.required=该字段必填 

Próbując

  1. Używa angielskiego Firefoksa, który wysyła nagłówek żądania Accept-Language:en-us,en;q=0.5 odwiedzić działania test. Wynikiem jest:

    Language from controller: Lang(en,), Message: This field is required 
    Message in view: 该字段必填 
    
  2. Używa chińskiego Google Chrome, który wysyła nagłówek żądania Accept-Language:zh-CN,zh;q=0.8 do jej odwiedzenia. Wynikiem jest:

    Language: Lang(zh,CN), Message: 该字段必填 
    Message in view: 该字段必填 
    

Z badań wiemy, że:

  1. Językiem ukryte w sterowniku jest od Accept-Language
  2. The języku niejawny nagłówka żądania wykorzystanej w szablonie jest określony przez OS

Środowisko:

  1. play 2 to najnowszy play2.1-SNAPSHOT z GitHub (2012-03-16)
  2. Moja jest system operacyjny Windows 7 x64   chińska wersja

myślę play 2 powinny stosować takie same niejawny język kontrolerów i widoków. Mogę to naprawić dodając coś w Build.sbt:

val main = PlayProject(...) (
    templatesImport ++= Seq("utilis.TemplateMixin._") 
) 

Jeżeli TemplateMixin tylko: (. Rozciąga Controller i jest po prostu do ponownego wykorzystania niektórych metod, jak implicit def lang(request))

object TemplateMixin extends play.api.mvc.Controller 

Ale myślę, że powinno to być zrobione w ramach Play.

Odpowiedz

17

Funkcja play.api.i18n.Messages(key) przyjmuje dodatkowy niejawny parametr typu Lang. Tak więc po napisaniu Messages("foo") jest on rozszerzany do Messages("foo")(l), gdzie l jest wartością typu Lang pobraną z bieżącego niejawnego zasięgu.

Zawsze dostępny jest default implicit lang (który ma low priority), używając domyślnego ustawienia narodowego jvm.

Ale gdy znajdujesz się wewnątrz Controller, niejawna wartość o wyższym priorytecie może zostać znaleziona, jeśli istnieje niejawne żądanie. Ta wartość wygląda w nagłówku żądania Accept-Language.

Gdy znajdujesz się wewnątrz szablonu, domyślny niejawny język zostanie użyty, o ile twój szablon nie zaimportuje innego niejawnego języka.

Dlatego w twoim przykładzie wiadomości wyliczone z kontrolera używają nagłówka żądania Accept-Language, a wiadomości obliczane z widoku używają domyślnego ustawienia narodowego jvm.

Jeśli dodać parametr niejawny typu Lang do szablonu parametr ten ma wyższy priorytet niż domyślny lang i zostaną wykorzystane do obliczenia wiadomości:

@(langInController: Lang, msg:String)(implicit request: RequestHeader, lang: Lang) 

<div>Lang from controller: @langInController, Message: @msg</div> 
<div>Message from view: @Messages("error.required")</div> 

Kiedy zadzwonisz szablon z działania kontrolera, jego niejawny język zostanie przekazany, więc ten sam język będzie używany zarówno w widokach, jak i kontrolerach.

+1

Jeszcze raz dziękuję. Dobra odpowiedź powinna zostać dodana do dokumentów play2. – Freewind

+0

Dlaczego nie może to być zachowanie domyślne? Wyobrażam sobie, że większość aplikacji chciałaby, aby domyślny Land w widoku był taki sam jak w kontrolerze. – Ike

+0

Ustawienie domyślnego zachowania wymagałoby rozróżnienia szablonów przeznaczonych do użycia z kontrolerami Java (które nie mogą dostarczyć wartości niejawnych) i szablonów przeznaczonych do użycia z kontrolerami Scala. –

Powiązane problemy