Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在Play 2.5中创建自定义模板格式_Scala_Model View Controller_Types_Playframework_Customization - Fatal编程技术网

Scala 在Play 2.5中创建自定义模板格式

Scala 在Play 2.5中创建自定义模板格式,scala,model-view-controller,types,playframework,customization,Scala,Model View Controller,Types,Playframework,Customization,我正试图通过以下步骤创建自定义模板格式(在播放2.5和Scala 2.11.11中),但我在这里,这意味着它不适合我 我希望新模板的文件扩展名为“stream”(现在已有几年了),因此我按照文档建议创建了此文件: package ui import akka.NotUsed import akka.stream.scaladsl.{Source} import play.twirl.api._ import scala.collection.immutable

我正试图通过以下步骤创建自定义模板格式(在播放2.5和Scala 2.11.11中),但我在这里,这意味着它不适合我

我希望新模板的文件扩展名为“stream”(现在已有几年了),因此我按照文档建议创建了此文件:

   package ui

   import akka.NotUsed
   import akka.stream.scaladsl.{Source}
   import play.twirl.api._

   import scala.collection.immutable

   case class HtmlStream(source: Source[Html, NotUsed]) extends Appendable[HtmlStream] {

     def +=(other: HtmlStream): HtmlStream = andThen(other)
     def andThen(other: HtmlStream): HtmlStream = HtmlStream(source.merge(other.source))

   }

   object HtmlStream {

     def apply(text: String): HtmlStream = apply(Html(text))
     def apply(html: Html): HtmlStream = HtmlStream(Source.single(html))

   }

   object HtmlStreamFormat extends Format[HtmlStream] {

     def raw(text: String): HtmlStream = HtmlStream(text)
     def escape(text: String): HtmlStream = raw(HtmlFormat.escape(text).body)

     override def empty: HtmlStream = ???
     override def fill(elements: immutable.Seq[HtmlStream]): HtmlStream = ???

   }
并将其添加到build.sbt文件中:

我看不出在何处或如何包含以下隐含内容(在前面提到的-底部);这可能是个问题:

Play可以为任何类型A的值编写HTTP响应正文,该值 它存在一个隐式play.api.http.Writeable[A]值。那么你呢 需要为模板结果类型定义这样的值。对于 实例,下面是如何为HTTP定义这样的值:


当我尝试创建一个新的
视图
文件时,例如,名为
test.scala.stream
的文件,它无法识别它应该是什么类型,因此看起来肯定是出了问题。这个需要帮助

因此,我已经破解了这个问题,本着社区精神,它就在这里

1) 创建一个文件(我在寻找HTML流时称我的文件为“HtmlStream”):

2) 我在build.sbt文件中添加了以下行:

3) 我添加了一个名为test1.scala.stream的模板(在提示时使用HTML文件关联):


希望这对其他人有帮助

这是一种自定义格式,我根据播放规范为cvs和works编码,包括您关于ContentTypes.HTTP的问题:

一些建议:

1-如果希望play framework可以编写HTTP响应主体,则需要定义主体内容。查看下面的代码implicit def contentTypeCsv这是您必须执行的操作,但具体的正文内容除外

2-其他重要建议,自定义格式的twirl模板应在自定义模板所在的build.sbt中定义,无论项目是单个项目还是多个项目

class Csv(buffer: immutable.Seq[Csv],text:String,escape:Boolean) extends BufferedContent[Csv](buffer, text) {

  val contentType = Csv.contentType

  def this(text: String) = this(Nil, Formats.safe(text),false)
  def this(buffer: immutable.Seq[Csv]) = this(buffer, "",false)


  override protected def buildString(builder: StringBuilder) {
    if (elements.nonEmpty) {
      elements.foreach { e =>
        e.buildString(builder)
      }
    } else if (escape) {
      // Using our own algorithm here because commons lang escaping wasn't designed for protecting against XSS, and there
      // don't seem to be any other good generic escaping tools out there.
      text.foreach {
        case '"' => builder.append("\"\"")
        case c => builder += c
      }
    } else {
      builder.append(text)
    }
  }
}


object Csv {
  val contentType = "text/csv"
  implicit def contentTypeCsv(implicit codec: Codec): ContentTypeOf[Csv] = ContentTypeOf[Csv](Some(Csv.contentType))

  def apply(text: String): Csv = new Csv(text)

  def empty: Csv = new Csv("")
}
object CsvFormat extends Format[Csv] {
  def raw(text: String): Csv = Csv(text)
  def escape(text: String): Csv = {
    new Csv(Nil, text, true)
  }

  def empty: Csv = new Csv("")

  def fill(elements: Seq[Csv]): Csv = new Csv(elements)
}
   implicit def writableHttp(implicit codec: Codec): Writeable[Http] =
  Writeable[Http](result => codec.encode(result.body), Some(ContentTypes.HTTP))
   package ui

   import akka.NotUsed
   import akka.stream.scaladsl.{Source}
   import play.twirl.api._

   import scala.collection.immutable
   import scala.concurrent.ExecutionContext

   case class HtmlStream(source: Source[Html, NotUsed]) extends Appendable[HtmlStream] {

     def +=(other: HtmlStream): HtmlStream = andThen(other)
     def andThen(other: HtmlStream): HtmlStream = HtmlStream(source.merge(other.source))

   }

   object HtmlStream {

     def apply(text: String): HtmlStream = apply(Html(text))
     def apply(html: Html): HtmlStream = HtmlStream(Source.single(html))

   }

   object HtmlStreamFormat extends Format[HtmlStream] {

     def raw(text: String): HtmlStream = HtmlStream(text)
     def escape(text: String): HtmlStream = raw(HtmlFormat.escape(text).body)

     override def empty: HtmlStream = raw("")
     override def fill(elements: immutable.Seq[HtmlStream]): HtmlStream = elements.reduce((agg, curr) => agg.andThen(curr))

   }

   object HtmlStreamImplicits {

      implicit def toSource(stream: HtmlStream)(implicit ec: ExecutionContext): Source[Html, NotUsed] = {
      stream.source.filter(_.body.nonEmpty)

   }
   TwirlKeys.templateFormats += ("stream" -> "ui.HtmlStreamFormat")
   TwirlKeys.templateImports ++= Vector("ui.HtmlStream", "ui.HtmlStream._", "ui.HtmlStreamFormat._", "ui.HtmlStreamImplicits._")
   @(body: HtmlStream)

   <!DOCTYPE html>
   <html lang="en">
      <head>
          <title>title</title>
          <link rel="stylesheet" media="screen" href="assets/stylesheets/main.css">
          <link rel="shortcut icon" type="image/png" href="assets/images/favicon.png">
          <script src="assets/javascripts/hello.js" type="text/javascript"></script>
      </head>
      <body>
      <h1>Streaming the body</h1>

      <div>
          <div>
              @body
          </div>
      </div>
      </body>
   </html>
  def streamHtml = Action { request =>

    val async1: Future[Result] = rr.getAsync(embed = true)(request) // get future
    val async1Html: Future[Html] = async1.flatMap(x => Pagelet.readBody(x)) // separate function to convert Future[Result] to Future[Html]
    val htmlStream: HtmlStream = HtmlStream(fromFuture(async1Html)) // c onvert to HtmlStream type

    Ok.chunked(views.stream.test1(htmlStream)) // chunk the new data type by sending through new template

  }
class Csv(buffer: immutable.Seq[Csv],text:String,escape:Boolean) extends BufferedContent[Csv](buffer, text) {

  val contentType = Csv.contentType

  def this(text: String) = this(Nil, Formats.safe(text),false)
  def this(buffer: immutable.Seq[Csv]) = this(buffer, "",false)


  override protected def buildString(builder: StringBuilder) {
    if (elements.nonEmpty) {
      elements.foreach { e =>
        e.buildString(builder)
      }
    } else if (escape) {
      // Using our own algorithm here because commons lang escaping wasn't designed for protecting against XSS, and there
      // don't seem to be any other good generic escaping tools out there.
      text.foreach {
        case '"' => builder.append("\"\"")
        case c => builder += c
      }
    } else {
      builder.append(text)
    }
  }
}


object Csv {
  val contentType = "text/csv"
  implicit def contentTypeCsv(implicit codec: Codec): ContentTypeOf[Csv] = ContentTypeOf[Csv](Some(Csv.contentType))

  def apply(text: String): Csv = new Csv(text)

  def empty: Csv = new Csv("")
}
object CsvFormat extends Format[Csv] {
  def raw(text: String): Csv = Csv(text)
  def escape(text: String): Csv = {
    new Csv(Nil, text, true)
  }

  def empty: Csv = new Csv("")

  def fill(elements: Seq[Csv]): Csv = new Csv(elements)
}