2012-12-13 11 views
7

Język szablonów programu Play Framework 2 jest całkiem niezły. Jednak, chociaż jest "inspirowany" językiem firmy Razor firmy Microsoft, jedna ważna decyzja projektowa jest inna: jak "uciekać z powrotem" do HTML. Razor szuka tagów w stylu HTML, a Play 2 używa jakiejś heurystyki.Jak wywołać szablon akceptujący zmienną liczbę argumentów w Play Framework 2

Próbuję napisać szablon, który zajmuje wiele "sekcji" HTML i generuje stronę z nagłówkami i spisem treści. My „structuredpage.scala.html” wygląda następująco:

@(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> 
    } 
} 

Zauważ, że jego drugi parametr jest liczba zmienna odcinków. Nie wydaje się, aby , a nie było to nazywanie tego w języku szablonowania Play.

I utworzeniu funkcji pomocnika nazwie Common.section który wygląda tak:

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

Próbowałem to:

@() 
@import views.Common.section 

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

... co daje type mismatch; found : scala.xml.Elem required: play.api.templates.Html na linii 5, tj <p>Blah</p> jest interpretowane jako Scala, a nie jako dokument HTML szablonu.

I tak:

@() 
@import views.Common.section 

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

... co daje type mismatch; found : play.api.templates.Html required: (String, play.api.templates.Html) na linii 3, to znaczy cała zewnętrzna blok CURLEY-klamra jest interpretowany jako szablon dokumentu HTML, nie jako kod Scala!

denerwująco nie wydają się być ogromnie różni się od niektórych próbek kodu w oficjalnej dokumentacji play 2, na przykład: http://www.playframework.org/documentation/2.0/ScalaTemplateUseCases

pomysłów? Używam Odtwórz Framework 2.0.4

+0

co to za błąd kompilacji można dostać? –

+0

Dodałem błędy kompilatora i moją interpretację ich na pytanie. Istotą jest to, że interpretuje on za dużo lub za mało szablonu jako kodu Scala. – andrewf

Odpowiedz

1

Oto czego możesz potrzebować. To nie jest dokładnie FP chociaż

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 metoda

@() 

@import views.Common.section 

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

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

sekcja:

def section(title: String)(content: Html)(implicit sections: scala.collection.mutable.MutableList[Pair[String, Html]]) { 
    sections += title -> content 
} 
+0

Haha! To paskudne i przebiegłe! To prawda, że ​​nie jest bardzo funkcjonalny, ale przynajmniej większość nieprzyjemności jest ukryta. Działa, a nagłówki sekcji znajdują się w pobliżu ich zawartości. Mam nadzieję, że ludzie z Play Framework będą mieli inne spojrzenie na reguły ucieczki w języku szablonów, ale ten hack może być przydatny w międzyczasie. – andrewf

0

nie mogę przetestować to teraz w tej maszynie, ale następujące powinny działać (nie ma potrzeby metody auxiliar):

@() 

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

Niestety nie! Po prostu go wypróbowałem, a to nie powiedzie się w taki sam sposób jak mój drugi przykład kodu. 'niedopasowanie typu; found: play.api.templates.Html required: (String, play.api.templates.Html) 'on line 3. Kompilator szablonów interpretuje całą treść zewnętrznych nawiasów klamrowych jako materiał szablonu HTML. – andrewf

+0

spróbujcie jeszcze raz sprawdzić dzisiejszego wieczoru, dlaczego –

+0

(ale oczywiście, podjąłem decyzję o uniknięciu dodatkowej funkcji/szablonu) – andrewf

0

Oto obejście:

@import views.Common.section 

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

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

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

poprzednia próba:

myślę twoje życzenie czyni go skomplikowana. Szablony powinny być proste. Oto prosta alternatywa:

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 
} 

Zrobiłem sens : https://gist.github.com/4280577. Możesz to sprawdzić i grać z nim.

+0

Dzięki, ale niestety to nie jest dobre! Moja wina za nadmierne uproszczenie pierwotnego pytania: chciałbym dynamicznie budować "spis treści" z listy "sekcji", więc nie mogę po prostu wziąć "sekcji" jako bryły html. Zgadzam się, że szablony powinny być tak proste, jak to tylko możliwe. Ale w tym przypadku trudno zobaczyć, jak mogę to uprościć i nadal robić to, co chcę. – andrewf

+0

Dobra. W mojej odpowiedzi dodałem co najmniej obejście problemu. – Schleichardt

+0

To może zadziałać, dzięki. Tytuł nie jest obok treści, ale poza tym wydaje się, że wykonuje to zadanie. Poinformuję Cię, gdy będę miał okazję go wypróbować. – andrewf

Powiązane problemy