8

I have a generic template in play 2.6, that I want to pass in a variable amount of HtmlContents. I've defined the template like this (including the implicit parameter I have in case that changes anything):

@(foo: String)(content: Html*)(implicit bar: Bar)

On the template side, this works fine-- I can dissect content with for and render it as I want. However, I haven't been able to figure out a clean way to invoke the variable arguments from the underlying template.

e.g, I have a view named "Baz":

@(something: String)(implicit bar: Bar)

In it, I try to invoke the template with multiple Html arguments. I've tried the following:

@template("fooString"){{123},{abc}}
and
@template("fooString")({123}, {abc})
and
@template("fooString"){{123}, {abc}})

And various other permutations, but inside of an enclosing bracket it seems to interpret everything literally as a single parameter in the HtmlContent vararg.

However, this ended up working as I intended, passing in multiple HtmlContents:

@template("fooString")(Html("123"), Html("abc"))

So that works, and I can use a triple-quoted interpolated string for a large Html block-- but it seems like there should be a cleaner way to do this, and the string interpolation is dangerous as it doesn't do html escaping.

Is there a way to do this using the { enclosed syntax? I'd like to understand more what is actually happening on an underlying level, and how play parses and generates HtmlContent in brackets.

Nathan
  • 65,860
  • 11
  • 32
  • 47
  • Your `Html(...)` approach looks quite clean and explicit to me. The [Twirl source code](https://github.com/playframework/twirl) could be one place to try and dig further into your question though. – wwkudu Nov 26 '16 at 11:11
  • Any comments on the answer I posted? – Tarun Lalwani Oct 14 '17 at 07:03

1 Answers1

2

So consider you have below template

// main.scala.html
@(title: String)(contents: Html*)

There are different ways you can call this template

Option #1

This is what you already posted in the question

@main("This is a title")(Html("abc"), Html("123"))

Options #2

@html1 = {
    Hello
}
@html2 = {
    <div>Tarun</div>
}

@main("This is a title")(html1, html2)

Option #3

@main("This is a title")(Html(<div>Tarun
</div>.toString), Html(<div>
Lalwani
</div>.toString))

Options #4

This is not exactly same option, but needs change in Template signature itself

@(title: String)(contents: List[String])  

And then calling it like below

@main("This is a title")(List(
  """<div>
     Tarun
    </div>
  """, """Hello"""))

Option #5

This requires code files and was already answered on another SO thread

Paul Draper's answer on Why doesn't this pass multiple HTML parameters to template

Tarun Lalwani
  • 124,930
  • 8
  • 149
  • 214