Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a template which accepts variable number of args in Play Framework 2

The Play Framework 2 template language is pretty nice. However, though it’s ‘inspired by’ Microsoft’s Razor language, one important design decision is different: how you ‘escape back’ into HTML. Razor looks for HTML-style tags and Play 2 uses some kind of heuristic.

I’m trying to write a template which takes multiple ‘sections’ of HTML, and generates a page with headers and a table of contents. My ‘structuredpage.scala.html’ looks like this:

@(title: String)(sections: Pair[String,Html]*)

@main(title){
    <nav class="page-links">
        @makeTableOfContents(sections)
    </nav>
    @for(section <- sections){
        <section id="@section._1">
            <h2>@section._1</h2>
            @section._2
        </section>
    }
}

Note that its second parameter is a variable number of sections. There does not seem to be a way of calling this in the Play templating language.

I’ve created a helper function called Common.section which looks like this:

    def section(title: String)(content: Html) = title -> content;

I’ve tried this:

@()
@import views.Common.section

@structuredpage("Dashboard")(
    section("Latest Requests") {
        <p>Blah</p>
    },
    section("Your Details") {
        <p>Blah blah</p>
    }
)

…which gives type mismatch; found : scala.xml.Elem required: play.api.templates.Html on line 5, i.e., <p>Blah</p> is being interpreted as Scala, not as template document HTML.

And this:

@()
@import views.Common.section

@structuredpage("Dashboard"){
    @section("Latest Requests") {
        <p>Blah</p>
    },
    @section("Your Details") {
        <p>Blah blah</p>
    }
}

…which gives type mismatch; found : play.api.templates.Html required: (String, play.api.templates.Html) on line 3, i.e., the entire outer curley-brace block is being interpreted as template document HTML, not as Scala code!

Frustratingly they don’t seem to be hugely different than some code samples in the official Play 2 documentation, for example: http://www.playframework.org/documentation/2.0/ScalaTemplateUseCases

Any ideas? I’m using Play Framework 2.0.4

like image 286
andrewf Avatar asked Dec 13 '12 12:12

andrewf


1 Answers

Here's what you might be looking for. It's not exactly FP though

structuredpage.scala.html

@(title: String)(content: scala.collection.mutable.MutableList[Pair[String, Html]] => Unit)

@main(title){
    @defining(new scala.collection.mutable.MutableList[Pair[String,Html]]()) { sections =>
        @content(sections)
        @for(section <- sections){
            <section id="@section._1">
                <h2>@section._1</h2>
                @section._2
            </section>
        }
    }
}

frontpage.scala.html

@()

@import views.Common.section

@structuredpage("Front Page") { implicit sections =>
    @section("Section 1") {
        <h1>stuff</h1>
    }

    @section("Section 2") {
        <h1>more stuff</h1>
    }
}

section method:

def section(title: String)(content: Html)(implicit sections: scala.collection.mutable.MutableList[Pair[String, Html]]) {
    sections += title -> content
}
like image 72
thatsmydoing Avatar answered Oct 16 '22 08:10

thatsmydoing