Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework template doesn't have Html type

I have a template named mainBody with the form:

@(title: String)(html: Html, moreScripts: Html = Html(""))

I'm able to call this like

views.html.mainBody("All properties")(views.html.showProperties(list))

views.html.showProperties() is another template. I'm under the impression that templates are just functions that return Html. However, if I extend this to:

views.html.mainBody("All properties")(views.html.showProperties(list), views.html.showPropertiesScripts)

Where views.html.showPropertiesScripts is just a template with some HTML code, I get the error:

play.PlayExceptions$CompilationException: Compilation error[type mismatch;
 found   : views.html.showPropertiesScripts.type
 required: play.twirl.api.Html]
        at play.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at play.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at scala.Option.map(Option.scala:145) ~[scala-library-2.11.2.jar:na]
        at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:234) ~[na:na]
        at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:229) ~[na:na]

I don't understand this. Instead of the expected type Html, views.html.showPropertiesScripts is views.html.showPropertiesScripts.type? What is this and why is views.html.showPropertiesScripts not of type Html (like my other templates)?

like image 508
Mike Avatar asked Oct 09 '14 19:10

Mike


Video Answer


2 Answers

Use this like mainBody.scala.html:

@(title: String, moreScripts: Html = Html(""))(html: Html)
<!DOCTYPE html>
<html>
    <head lang="en">
      <title>@title</title>
      @moreScripts
    </head>
    <body>
       @html
    </body>
</html>

The view:

@(list: List[YourType])

@moreScripts = {
    <script>alert ('it works')</script>
}

@mainBody(title = "All properties", moreScripts = moreScripts) {
    @showProperties(list)
}

as moreScripts is optional you can skip it in the other view:

@(list: List[YourType])

@mainBody(title = "Other view") {
    @showProperties(list)
}
like image 56
biesior Avatar answered Oct 12 '22 20:10

biesior


I think you're mixing up "type" with "return type". Presumably is views.html.showPropertiesScripts is a template that doesn't take any parameters (it starts with @()). If this is the case, it does not have type Html, but rather, it's a class with a def apply(): Html, which is why when you "call" it with parentheses, it returns Html. You can think of it as having type () => Html. You should try:

views.html.mainBody("All properties")(views.html.showProperties(list), views.html.showPropertiesScripts())

You might be confused by the concept of calling a method without a parameter list. That can't work when dealing with apply, because if you leave the parameter list off, Scala interprets you as referring to the object itself, not the result of apply.

like image 36
acjay Avatar answered Oct 12 '22 21:10

acjay