【问题标题】:Using play.i18n.Lang or play.api.i18n.Messages at Play framework with Scala在 Play 框架中使用 play.i18n.Lang 或 play.api.i18n.Messages 和 Scala
【发布时间】:2016-10-05 06:44:54
【问题描述】:

我正在尝试将国际化放在我的 Play for Scala 示例中。我正在关注 Play for Scala 这本书。我收到关于长期使用哪个参数(play.i18n.Langplay.api.i18n.Messages)的错误。问题是当我使用play.api.i18n.Messages 方法@Messages("products.form") 时,我必须使用play.i18n.Lang 中的@Messages.get("products.form")。错误是:

[info] Compiling 21 Scala sources and 1 Java source to /home/felipe/workspace-play/products/target/scala-2.11/classes...
[error] /home/felipe/workspace-play/products/app/controllers/Products.scala:34: could not find implicit value for parameter lang: play.i18n.Lang
[error]       Ok(views.html.products.details(product))
[error]                                     ^
[error] /home/felipe/workspace-play/products/app/views/products/editProduct.scala.html:13: could not find implicit value for parameter messages: play.api.i18n.Messages
[error]      @helper.inputText(productForm("ean"))
[error]                       ^
[error] /home/felipe/workspace-play/products/app/views/products/editProduct.scala.html:14: could not find implicit value for parameter messages: play.api.i18n.Messages
[error]      @helper.inputText(productForm("name"))
[error]                       ^
[error] /home/felipe/workspace-play/products/app/views/products/editProduct.scala.html:15: could not find implicit value for parameter messages: play.api.i18n.Messages
[error]      @helper.textarea(productForm("description"))
[error]                      ^
[error] /home/felipe/workspace-play/products/app/views/products/list.scala.html:4: could not find implicit value for parameter lang: play.i18n.Lang
[error] @main(Messages.get("application.name")) {
[error]                                         ^
[error] 5 errors found

我的控制器:

package controllers

import models.Product
import play.api.mvc.{Action, Controller}
import play.api.data.Form
import play.api.data.Forms.{mapping, longNumber, nonEmptyText}
import play.api.mvc.Flash
import play.i18n._
// import play.api.i18n.Messages
// import play.api.Play.current
// import play.api.i18n.Messages.Implicits._

/**
  * Created by felipe on 6/4/16.
  */
class Products extends Controller {

  private val productForm: Form[Product] = Form(
    mapping(
      "ean" -> longNumber.verifying(
        "validation.ean.duplicate", Product.findByEan(_).isEmpty),
      "name" -> nonEmptyText,
      "description" -> nonEmptyText
    )(Product.apply)(Product.unapply)
  )

  def list = Action { implicit request =>
    val products = Product.findAll
    Ok(views.html.products.list(products))
  }

  def show(ean: Long) = Action { implicit request =>
    Product.findByEan(ean).map { product =>
      Ok(views.html.products.details(product))
    }.getOrElse(NotFound)
  }

  def save = Action { implicit request =>

    val newProductForm = productForm.bindFromRequest()

    newProductForm.fold(
      hasErrors = { form =>
        Redirect(routes.Products.newProduct()).
          flashing(Flash(form.data) +
            ("error" -> Messages.get("validation.errors")))
      },
      success = { newProduct =>
        Product.add(newProduct)
        val message = Messages.get("products.new.success", newProduct.name)
        Redirect(routes.Products.show(newProduct.ean)).flashing("success" -> message)
      }
    )
  }

  def newProduct = Action { implicit request =>
    val form = if (request.flash.get("error").isDefined)
      productForm.bind(request.flash.data)
    else
      productForm
    Ok(views.html.products.editProduct(form))
  }
}

我的看法:

@(productForm: Form[Product])(implicit flash: Flash, lang: Lang)
@import play.i18n._
@import helper._

@main(Messages.get("products.form")) {
  <h2>@Messages.get("products.form")</h2>

  @helper.form(action = routes.Products.save()) {
    <fieldset>
     <legend>
      @Messages.get("products.details", Messages.get("products.new"))
     </legend>
     @helper.inputText(productForm("ean"))
     @helper.inputText(productForm("name"))
     @helper.textarea(productForm("description"))
    </fieldset>
    <p>
      <input type="submit" class="btn primary" value='@Messages.get("products.new.submit")'>
    </p>
   }
}

【问题讨论】:

  • 您使用的是哪个版本的 Play?
  • activator-dist-1.3.10 - 玩 2.5.3 和 scalaVersion := "2.11.7"

标签: scala playframework internationalization playframework-2.0


【解决方案1】:

我让它工作了!不管怎么说,还是要谢谢你。这是我基于this question的解决方案。

我正在使用视图表单助手(例如@inputText)要求您将implicit play.api.i18n.Messages 参数传递给您的视图。您可以将 (implicit messages: Messages) 添加到签名中。然后我使用应用程序控制器,这个参数在我的范围内隐式可用。最简单的方法是实现 play 的 I18nSupport trait。

package controllers

import javax.inject.Inject

import models.Product
import play.api.mvc.{Action, Controller}
import play.api.data.Form
import play.api.data.Forms.{longNumber, mapping, nonEmptyText}
import play.api.i18n.{I18nSupport, Messages, MessagesApi}
import play.api.mvc.Flash

/**
  * Created by felipe on 6/4/16.
  */
class Products @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport {

  private val productForm: Form[Product] = Form(
    mapping(
      "ean" -> longNumber.verifying(
        "validation.ean.duplicate", Product.findByEan(_).isEmpty),
      "name" -> nonEmptyText,
      "description" -> nonEmptyText
    )(Product.apply)(Product.unapply)
  )

  def list = Action { implicit request =>
    val products = Product.findAll
    Ok(views.html.products.list(products))
  }

  def show(ean: Long) = Action { implicit request =>
    Product.findByEan(ean).map { product =>
      Ok(views.html.products.details(product))
    }.getOrElse(NotFound)
  }

  def save = Action { implicit request =>

    val newProductForm = productForm.bindFromRequest()

    newProductForm.fold(
      hasErrors = { form =>
        Redirect(routes.Products.newProduct()).
          flashing(Flash(form.data) +
            ("error" -> Messages("validation.errors")))
      },
      success = { newProduct =>
        Product.add(newProduct)
        val message = Messages("products.new.success", newProduct.name)
        Redirect(routes.Products.show(newProduct.ean)).flashing("success" -> message)
      }
    )
  }

  def newProduct = Action { implicit request =>
    val form = if (request.flash.get("error").isDefined)
      productForm.bind(request.flash.data)
    else
      productForm
    Ok(views.html.products.editProduct(form))
  }
}

观点:

@(productForm: Form[Product])(implicit flash: Flash, messages: Messages)
@import helper._

@main(Messages("products.form")) {
  <h2>@Messages("products.form")</h2>

  @helper.form(action = routes.Products.save()) {
    <fieldset>
     <legend>
      @Messages("products.details", Messages("products.new"))
     </legend>
     @helper.inputText(productForm("ean"))
     @helper.inputText(productForm("name"))
     @helper.textarea(productForm("description"))
    </fieldset>
    <p>
      <input type="submit" class="btn primary" value='@Messages("products.new.submit")'>
    </p>
   }
}

【讨论】:

  • 您是否尝试让这个示例在 playframework 2.6.x 中工作?如果是,请您发布 2.6 的更新。我有同样的问题,但我无法让它工作。我不明白出了什么问题 - 它似乎没有正确解决隐含问题。
  • 我想通了。和你一样,控制器有with I18nSupport,然后html模板有(implicit messagesProvider: MessagesProvider),一个简单的动作使用implicit request =&gt;。很痛苦!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 2012-02-20
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多