【问题标题】:Playframework: Use Scalatags instead of TwirlPlayframework:使用 Scalatags 而不是 Twirl
【发布时间】:2017-01-22 23:09:32
【问题描述】:

我更喜欢使用前者而不是后者,但我不确定如何将 Scalatags 合并到 playframework 中。

这是我的简单布局:

object Test
{
  import scalatags.Text.all._
  def build =
  {

    html(
      head(
        title := "Test"
      ),
      body(

        h1("This is a Triumph"),
        div(
          "Test"
        )
      )
    )
  }
}

这是我尝试渲染它的方式:

Ok(views.Test.build.render)

问题是,我将其作为纯字符串而不是 HTML。

现在,一种解决方案当然是简单地追加。

Ok(views.Test.build.render).as("text/html")

但这真的是唯一的方法吗? (没有创建辅助方法就是)

【问题讨论】:

    标签: scala playframework scalatags


    【解决方案1】:

    我假设您希望能够致电Ok(views.Test.build)。 Play 不知道 ScalaTags,所以我们将不得不在这里自己编写一些东西

    Play 使用一些隐式机制来生成 HTTP 响应。当您调用 Ok(...) 时,您实际上是在 play.api.mvc.Results 特征上调用 apply。我们来看看它的签名:

    def apply[C](content: C)(implicit writeable: Writeable[C]): Result
    

    所以我们可以看到我们需要一个隐含的Writeable[scalatags.Text.all.Tag]

    implicit def writeableOfTag(implicit codec: Codec): Writeable[Tag] = {
      Writeable(tag => codec.encode("<!DOCTYPE html>\n" + tag.render))
    }
    

    不要忘记包含一个 doctype 声明。 ScalaTags 没有给你。

    Writeable.apply 的调用本身需要另一个隐式来确定内容类型。这是它的签名:

    def apply[A](transform: A => ByteString)(implicit ct: ContentTypeOf[A]): Writeable[A]
    

    所以让我们写一个隐含的ContentTypeOf[Tag]

    implicit def contentTypeOfTag(implicit codec: Codec): ContentTypeOf[Tag] = {
      ContentTypeOf[Tag](Some(ContentTypes.HTML))
    }
    

    这允许我们避免必须显式编写as("text/html")并且它包含字符集(由隐式编解码器提供),从而产生text/html; charset=utf-8Content-Type 标头。

    把它们放在一起:

    import play.api.http.{ ContentTypeOf, ContentTypes, Writeable }
    import play.api.mvc.Results.Ok
    import scalatags.Text.all._
    
    def build: Tag = {
      html(
        head(
          title := "Test"
        ),
        body(
    
          h1("This is a Triumph"),
          div(
            "Test"
          )
        )
      )
    }
    
    implicit def contentTypeOfTag(implicit codec: Codec): ContentTypeOf[Tag] = {
      ContentTypeOf[Tag](Some(ContentTypes.HTML))
    }
    
    implicit def writeableOfTag(implicit codec: Codec): Writeable[Tag] = {
      Writeable(tag => codec.encode("<!DOCTYPE html>\n" + tag.render))
    }
    
    def foo = Action { implicit request =>
      Ok(build)
    }
    

    您可能希望将这些隐式隐藏在方便的地方,然后将它们导入您的控制器中。

    【讨论】:

    • 为什么 twirl 是默认的模板引擎? scalatags 似乎更简单。
    猜你喜欢
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多