Использование scala.xml.Node в шаблонах воспроизведения Scala - PullRequest
3 голосов
/ 05 сентября 2011

Я использую игровую платформу Scala.Для большинства моих страниц я держу свой HTML строго в шаблонах представления.В частности, для одной страницы я хотел бы иметь возможность проходить через какой-то XML, который я сгенерировал программно в моем контроллере.У меня есть следующий тривиальный шаблон:

@(session:play.mvc.Scope.Session, flash:play.mvc.Scope.Flash, analysisTable : scala.xml.Node )

@main(title="Home", session=session, flash=flash) {
    <h1>Some title</h1>
    @{analysisTable}
}

Когда я прохожу через какой-то предварительно сгенерированный XML-код, который я надеюсь внедрить, и перехожу на соответствующую страницу, я получаю:

Execution exception
InvocationTargetException occured : null

На странице, и то, что выглядит как переполнение стека на консоли (отрывок ниже):

at play.templates.BaseScalaTemplate._display_(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at scala.xml.NodeSeq.foreach(NodeSeq.scala:43)
at scala.xml.NodeSeq.foldLeft(NodeSeq.scala:43)
at play.templates.BaseScalaTemplate._display_(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at scala.xml.NodeSeq.foreach(NodeSeq.scala:43)
at scala.xml.NodeSeq.foldLeft(NodeSeq.scala:43)
at play.templates.BaseScalaTemplate._display_(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at scala.xml.NodeSeq.foreach(NodeSeq.scala:43)
at scala.xml.NodeSeq.foldLeft(NodeSeq.scala:43)
at play.templates.BaseScalaTemplate._display_(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at play.templates.BaseScalaTemplate$$anonfun$_display_$1.apply(ScalaTemplate.scala:618)
at scala.xml.NodeSeq.foreach(NodeSeq.scala:43)
at scala.xml.NodeSeq.foldLeft(NodeSeq.scala:43)

Я явно делаю что-то глупое или недопустимое.Кто-нибудь захочет избавить меня от моих страданий?

1 Ответ

2 голосов
/ 05 сентября 2011

OK. Я прочитал источники и разработал исправление. Кажется, что шаблонизатор scala play допускает определенный набор различных типов в шаблоне для внутреннего рендеринга (исключая play-scala / src / play / templates / ScalaTemplate.scala), не включая scala.xml.Node:

 case class BaseScalaTemplate[T<:Appendable[T],F<:Format[T]](format: F) {

    def _display_(o:Any):T = {
        o match {
            case escaped:T => escaped
            case () => format.raw("")
            case None => format.raw("")
            case Some(v) => _display_(v)
            case escapeds:Seq[Any] => escapeds.foldLeft(format.raw(""))(_ + _display_(_))
            case string:String => format.escape(string)
            case v if v != null => _display_(v.toString)
            case _ => format.raw("")
        }
    }
}

В основном, в строку вводятся строки, но есть несколько других типов. Глядя на верхнюю строку выражения match выше, все, что является подтипом Appendable, разрешено. И так уж получилось, что чуть дальше определен следующий класс:

case class Html(text:String) extends Appendable[Html] {
    val buffer = new StringBuilder(text)

    def +(other:Html) = {
        buffer.append(other.buffer)
        this
    }
    override def toString = buffer.toString
}

Тогда мое решение - преобразовать исходное поддерево xml в строку, а затем обернуть его в класс Html следующим образом:

@(session:play.mvc.Scope.Session, flash:play.mvc.Scope.Flash, analysisTable : scala.xml.Node )

@main(title="Home", session=session, flash=flash) {
    <h1>Some title</h1>
    @{new play.templates.Html(analysisTable.toString)}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...