2013-06-24 15 views
6

In Kohana (framework PHP) il layout viene implementato tramite Template_Controller che contiene una variabile membro chiamata $ template, che funge da visualizzazione layout. Quindi nel metodo azione è possibile popolare il modello $ con ulteriori sottovoci, in genere la vista del contenuto. (http://forum.kohanaframework.org/discussion/3612/kohana-layout-system/p1)Modifica del modello di layout in runtime

Ciò mi consente di modificare il layout "tema" nel runtime. È utile per il sistema multi-tenant, in cui un inquilino può selezionare il proprio tema (due colonne, tre colonne ecc.)

Come posso ottenerlo in Playframework 2 Scala con il motore di template di Scala? In altre parole, mi piacerebbe avere più modelli di layout in cui un tenant può scegliere. Il controller quindi esegue il rendering del modello di layout e del modello di contenuto specifico dell'azione.

Qualcosa di simile (del controller azione pseudocodice):

  1. in base all'utente, recuperare il tema di layout (un nome memorizzato nella stringa in un database, e si è vista corrispondente file di mapping).
  2. Renderizza la visualizzazione del contenuto specifico dell'azione.
  3. Renderizza la vista layout ottenuta da (1) insieme a (2).

Nota: per ogni azione, il tema di layout può cambiare per utente ma la visualizzazione del contenuto rimane la stessa.

nella sua documentazione (http://www.playframework.com/documentation/2.1.1/ScalaTemplateUseCases)
il modello di contenuto, ad esempio, l'index.scala.html, include una chiamata alla principale che è definito nella main.scala.html, il modello di layout. In altre parole, è hard coded, quindi index.scala.html è strettamente associato a main.scala.html.

Ho pensato di chiamare il principale dal controller utilizzando la reflection e quindi passando il contenuto.

Un'alternativa sarebbe utilizzare un motore di modelli interpretato come Scalate.

Qualche suggerimento?

risposta

2

Vedo 2 opzioni per ottenere ciò che state cercando. Il primo sarebbe passare un parametro di tema ai propri modelli (ad esempio qualcosa per indicare al modello chiamato quale tema/layout utilizzare) e usare quel parametro per chiamare condizionatamente un modello di layout. Il secondo sarebbe gestire la condizione all'interno del controller restituendo la vista appropriata in base al tema selezionato.

Opzione 1

Nella vostra azione si vuole passare qualche valore per il modello per indicare quale tema da utilizzare.

def index = Action { 
    Ok(views.html.index("two-col")) 
} 

Poi, nel tuo index.scala.html si farebbe qualcosa di simile:

@(theme: String) 

@content = { 
    <h1>Action Specific Content</h1> 
} 

@if("two-col" eq theme) { 
    @twoCol("title")(content) 
} else { 
    @main("title")(content) 
} 

Questo si aspetta che ci sia un modello twoCol.scala.html, come ad esempio:

@(title: String)(content: Html) 
<!DOCTYPE html> 
<html> 
    ... 
    <body> 
    <h1>Two Column</h1> 
    @content 
    </body> 
</html> 

Nota: È anche possibile passare il tema utilizzando un parametro implicito, vedere questo SO question. Ciò allevierebbe la necessità di passarlo esplicitamente il modello su ogni rendering.

Opzione 2

Questo sarebbe semplice come il seguente nel controller, ma sarebbe forse richiedono molto più codice ripetuto nei modelli di vista.

def index = Action { 
    var theme = ... 
    ... 
    if (theme eq 'tow-col') { 
    Ok(views.html.twocol.index("two-col")) 
    } else { 
    Ok(views.html.default.index()) 
} 

Questa assume c'è un pacchetto twocol e default in /app/views che hanno un index.scala.html.

Ulteriori commenti

Come si può dire da l'opzione 1, index.scala.html non è strettamente accoppiati con main.scala.html. È possibile sostituire la chiamata al principale con una chiamata a qualsiasi altro modello o persino nessun modello.

FWIW, vorrei andare con l'opzione 1 e potrebbe evolvere in una soluzione migliore.

Problemi correlati