I know about this and this, but the answers are very strange, and in any case, I am looking to understand why this particular approach does not work:
@myPackage.views.html.ol(
{
Hello
}, {
World
}
)
myPackage.views.html.ol.scala.html
@(ol:Html*)
<ol>
@for(li <- ol) {
<li>
(hi)
<span class="li-body">@li</span>
</li>
}
</ol>
Error:
not found: value Hello
I must lack fundamental understanding about the rules of the template engine, because this seems intuitively correct to me.
The @
character marks the beginning of a dynamic statement, so you are no longer in template syntax. It's trying to interpret the arguments to the ol()
function as straight Scala/Java code, not the template syntax.
It depends on what exactly you're trying to do, but here are two ways to do it. You could probably also use the @defining
helper.
@myPackage.views.html.ol(Html("Hello"), Html("World"))
Another way is to define the Html blocks at the beginning of your view.
@html1 = { Hello }
@html2 = { <strong>World</strong> }
@main(){
@myPackage.views.html.ol(html1, html2)
}
estimatic's answer was correct.
Of what he presented, I would probably have used the @html1 = ...
solution, but I found something else, which I hope will benefit some future reader.
HtmlVarArgs.scala
import play.api.templates.Html
import scala.collection.mutable.ListBuffer
class HtmlVarArgs(html: Html) {
private val templates = ListBuffer(html)
def apply(html: Html) = {
templates += html
this
}
def passTo(f: Seq[Html] => Html) = f(templates)
}
object HtmlVarArgs {
def apply(html: Html) = new HtmlVarArgs(html)
}
ol.scala.html
myPackage.views.html.ol.scala.html
@(ol:Html*)
<ol>
@for(li <- ol) {
<li>
(hi)
<span class="li-body">@li</span>
</li>
}
</ol>
And then I can use it in a template as follows:
@HtmlVarArgs {
Hello
} {
World
}.passTo(myPackage.views.html.ol.apply)