How to call a template which accepts variable numb

2019-02-17 01:23发布

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

3条回答
爷、活的狠高调
2楼-- · 2019-02-17 02:14

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
}
查看更多
干净又极端
3楼-- · 2019-02-17 02:18

I can't test this right now in this machine, but the following should work (no need of auxiliar method):

@()

@structuredpage("Dashboard"){
   ("Latest Requests", {
        <p>Blah</p>
    }),
   ("Your Details", {
        <p>Blah blah</p>
    })
}
查看更多
劳资没心,怎么记你
4楼-- · 2019-02-17 02:24

Here is a workaround:

@import views.Common.section

@sec1 = { <p>Blah</p> }

@sec2 = { <p>Blah blah</p> }

@structuredpage("Dashboard")(
    section("Latest Requests")(sec1),
    section("Your Details")(sec2)
)

previous attempt:

I think your wish makes it to complicated. Templates should be simple. Here is a simple alternative:

index.scala.html

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

    @section("Your Details") {
        <p>Blah blah</p>
    }
}

section.scala.html

@(title: String)(content: Html)

<section id="@title">
    <h2>@title</h2>
    @content
</section>

structuredpage.scala.html

@(title: String)(sections: Html)

@main(title){
    <nav class="page-links">
        table-of-contents goes here
    </nav>
    @sections
}

I made a gist: https://gist.github.com/4280577 . So you can check it out and play with it.

查看更多
登录 后发表回答