Reputation: 408
Why does this output "html is empty"?
@h = {<br />}
@h match {
case Html("") => {html is empty}
case _ => {html has content}
}
and this outputs "html has content"?
@i = @{Html("<br />")}
@i match {
case Html("") => {html is empty}
case _ => {html has content}
}
The reason this matters to me is because in the common use cases last example (moreScripts and moreStyles equivalents), the first style is used to pass in a chuck of html into another template. I then want to switch based on if that html has content or not. But it always matches to Html("").
Upvotes: 2
Views: 1126
Reputation: 408
The code generated for each of the methods is slightly different.
def h:play.api.templates.Html = {
_display_(
Seq[Any](format.raw("""<br />"""))
)
}
def i = {{Html("<br />")}}
The _display_
method used in creating h
ends up performing a foldLeft
on all the elements of the passed in Seq
This results in:
Html("") + Html("<br />")
The Html
case class turns out to be backed by a mutable StringBuilder
.
case class Html(text: String) extends Appendable[Html] with Content with play.mvc.Content {
val buffer = new StringBuilder(text)
/**
* Appends this HTML fragment to another.
*/
def +(other: Html): Html = {
buffer.append(other.buffer)
this
}
override def toString = buffer.toString
/**
* Content type of HTML (`text/html`).
*/
def contentType: String = "text/html"
def body: String = toString
}
This means that the value of text
is only ever going to be set to the value of the first Html
's text
value. Whenever you create a new Html
via the +
method you only modify the StringBuilder
.
E.g.
val html = Html("1") + Html("2")
html.text == "1"
html.toString == "12"
html.body == "12"
Since it is the text
value that is used for pattern matching this effectively breaks its ability to be used in pattern matching.
E.g.
(Html("1") + Html("2")) match { case Html("1") => "broken" } // returns "broken"
Upvotes: 3
Reputation: 3449
Maybe try doing a string match?
@h.toString() match {
case "" => {html is empty}
case _ => {html has content}
}
Upvotes: 0