0

У меня есть библиотека, которая позволяет пользователю переключаться между английским и валлийским языками во время сеанса браузера, который работает с Play 2.3.Play 2.5 I18n - Switching language

После перехода на Play 2.5 эта библиотека больше не работает. Я пробовал следовать «документации» на https://www.playframework.com/documentation/2.5.x/ScalaI18N, но до сих пор мне не повезло.

Моя реализация до сих пор:

шаблон Twirl, содержащий переключатель

@import play.api.Play.current 
@import play.api.i18n.Messages.Implicits._ 
@import uk.my-org.urls.Link 

@(langMap : Map[String, Lang], langToCall : (String => Call),  customClass: Option[String] = None)(implicit lang: Lang) 

<p>Current = @lang</p> 

<p class="@if(customClass.isDefined) {@customClass.get}"> 
@langMap.map { case (key: String, value: Lang) => 
     @if(lang.code != value.code) { 
      @Link.toInternalPage(
       id  = Some(s"$key-switch"), 
       url  = s"${langToCall(key)}", 
       value = Some(key.capitalize) 
      ).toHtml 
     } else { 
      @key.capitalize 
     } 
     @if(key != langMap.last._1) { @Html(" | ") } 
} 
</p> 

Страница, содержащая переключатель

@import uk.my-org.exampleplay25.controllers.LanguageController 
@import play.api.Application 
@import play.api.i18n.Messages 

@()(implicit request: Request[_], application: Application, messages: Messages, lang: Lang, messagesApi: MessagesApi) 

<h1 id="message">Hello from example-play-25-frontend !</h1> 
<h1>@Messages("test.message")</h1> 


@clc = @{ Application.instanceCache[LanguageController].apply(application) } 

@uk.my-org.exampleplay25.views.html.language_selection(clc.languageMap, clc.langToCall, Some("custom-class")) 

SwitchingController

package uk.my-org.exampleplay25.controllers 

import javax.inject.Inject 

import play.api.Play 
import play.api.i18n._ 
import play.api.mvc._ 
import uk.my-org.play.config.RunMode 

class LanguageController @Inject()(implicit val messagesApi: MessagesApi, lang: Langs) extends Controller with I18nSupport with RunMode  { 
    protected def fallbackURL: String = Play.current.configuration.getString(s"$env.language.fallbackUrl").getOrElse("/") 

    def languageMap: Map[String, Lang] = Map(
     "english" -> Lang("en"), 
     "cymraeg" -> Lang("cy-GB"), 
     "french" -> Lang("fr") 
    ) 

    def langToCall(lang: String): Call = routes.LanguageController.switchToLanguage(lang) 

    def switchToLanguage(language: String) = Action { implicit request => 
    val lang = languageMap.getOrElse(language, LanguageUtils.getCurrentLang) 
    val redirectURL = request.headers.get(REFERER).getOrElse(fallbackURL) 
    Redirect(redirectURL).withLang(Lang.apply(lang.code)).flashing(LanguageUtils.FlashWithSwitchIndicator) 
    } 
} 

Application.conf

play.i18n.langs = [ "en", "cy", "fr" ] 

App маршруты

GET  /hello-world    @uk.my-org.exampleplay25.controllers.HelloWorld.helloWorld 

GET  /language/:lang   @uk.my-org.exampleplay25.controllers.LanguageController.switchToLanguage(lang: String) 

Hello World контроллер

package uk.my-org.exampleplay25.controllers 

import javax.inject.{Inject, Singleton} 

import play.api.Play.current 
import play.api.i18n.{I18nSupport, MessagesApi} 
import play.api.mvc._ 
import uk.my-org.play.frontend.controller.FrontendController 

import scala.concurrent.Future 

@Singleton 
class HelloWorld @Inject()(implicit val messagesApi: MessagesApi) extends FrontendController with I18nSupport { 
    val helloWorld = Action.async { implicit request => 
      Future.successful(Ok(uk.my-org.exampleplay25.views.html.helloworld.hello_world())) 
    } 
} 

Может кто-нибудь увидеть, что я делаю неправильно ??

+0

Это слишком много кода, и этот вопрос на самом деле не был сужен на всех. Я предлагаю вам сначала перейти на 2.4 и проверить, работает ли это. Затем перейдите на 2.5. Если это не сработает, попробуйте сузить проблему и попытаться определить, в какой момент код больше не ведет себя так, как ожидалось. – rethab

ответ

1

Короткий ответ: вы не объявляете cy-GB как язык, но вы пытаетесь переключиться на него.

Долгий ответ: вы слишком усложняете ситуацию. Вот пример демонстрации переключения языков с минимальным кодом.

Шаблон

Это будет отображать сообщение от соответствующих сообщений файл, а также показывающий lang, полученный из заголовка запроса.

@()(implicit messages: Messages, lang: Lang) 

<h3>@messages("greeting")</h3> 

<p>Current = @lang</p> 
<ul> 
    <li><a href="@routes.LanguageController.switchToLanguage("en")">English</a></li> 
    <li><a href="@routes.LanguageController.switchToLanguage("cy")">Welsh</a></li> 
</ul> 

Конфигурация

Объявите языки, которые вы хотите поддержать:

play.i18n.langs = [ "en", "cy" ] 

Применение контроллера

Единственная специальная вещь здесь является I18nSupport черта.

package controllers 

import javax.inject.Inject 

import play.api.i18n.{I18nSupport, MessagesApi} 
import play.api.mvc.{Action, Controller} 
import views.html.index 

import scala.concurrent.{ExecutionContext, Future} 

class FooController @Inject()(val messagesApi: MessagesApi, 
           exec: ExecutionContext) extends Controller with I18nSupport { 

    def home = Action.async { implicit request => 
    Future {Ok(index())}(exec) 
    } 
} 

Изменение языка

Опять же, ничего особенного и нет дополнительной поддержки требуется.

package controllers 

import javax.inject.Inject 

import play.api.i18n._ 
import play.api.mvc._ 

class LanguageController @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport { 

    def switchToLanguage(language: String) = Action { implicit request => 
    Redirect(routes.FooController.home()).withLang(Lang(language)) 
    } 
} 

Переводы

conf/messages.en

greeting=Good morning 

conf/messages.cy

greeting=Bore da 

маршруты

GET /     controllers.FooController.home 
GET  /lang/:lang   controllers.LanguageController.switchToLanguage(lang: String) 

Это все, что вам нужно

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

enter image description here

enter image description here