0

我想通过以下的Play documentation做一个自定义模板格式(播放2.5_ & _Scala 2.11.11),但我在这里这样就意味着它不是为我工作。在播放创建自定义的模板格式2.5

我希望新的模板有“”文件扩展名(如this video现在是几岁),所以我创造了这个文件作为文档建议:

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文件:

TwirlKeys.templateFormats += ("stream" -> "ui.HtmlStreamFormat.instance") 

我看不出哪里或如何包括以下隐(上预提到Play documentation - 底部);这可能是问题:

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

implicit def writableHttp(implicit codec: Codec): Writeable[Http] = 
    Writeable[Http](result => codec.encode(result.body), Some(ContentTypes.HTTP)) 

当我尝试创建一个新的文件view,例如称为test.scala.stream它不能识别它应该是什么类型,所以它看起来有些绝对是错误的。帮助需要这个!

回答

0

因此,我已经破解了这一个,并在社区精神这里。

1)创建一个文件(I称为矿 “HtmlStream” 为我寻找到流HTML):

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) 

    } 

2)I加入这些行到build.sbt文件:

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

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

@(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> 

4)最后,我可以用这个模板,我会通过将其转化为新HtmlStream类型的任何其它模板。

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 

    } 

希望这对别人有帮助!

0

这是一个自定义格式,我按照播放规范对CVS和作品进行编码,包括有关ContentTypes的问题。HTTP:

一些建议:

1,如果你想那部戏的框架可以写一个HTTP响应身体,你需要定义的主体内容。看看隐含def contentTypeCsv这是你必须做的,但在你的具体内容。

2-其他重要的建议,自定义格式的旋转模板应该在您的自定义模板所在的built.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) 
}