Un modèle de base est créé . Avec ce rendu en premier.html, un autre modèle.
eg. :
var tmpl = template.Must(template.ParseFiles(
"templates/base.html",
"templates/first.html",
))
Mais je veux aussi ajouter plus de fichiers .html à rendre . Une référence?
Si vous définissez tous vos modèles dans un dossier de modèles, vous pouvez facilement analyser tout le répertoire avec:
template.Must(template.ParseGlob("YOURDIRECTORY/*"))
Par exemple:
head.html
{{define "header"}}
<head>
<title>Index</title>
</head>
{{end}}
index.html
{{define "indexPage"}}
<html>
{{template "header"}}
<body>
<h1>Index</h1>
</body>
</html>
{{end}}
main.go
package main
import(
"html/template"
)
// compile all templates and cache them
var templates = template.Must(template.ParseGlob("YOURTEMPLATEDIR/*"))
func main(){
...
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
// you access the cached templates with the defined name, not the filename
err := templates.ExecuteTemplate(w, "indexPage", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Vous exécutez votre template indexPage avec templates.ExecuteTemplate(w, "indexPage", nil)
Vous pouvez facilement ajouter plus de fichiers .html en les ajoutant simplement comme arguments:
var tmpl = template.Must(template.ParseFiles(
"templates/base.html",
"templates/first.html",
"templates/second.html",
))
Cela fonctionne bien tant que les premier et second ne définissent pas le même modèle.
Cependant, le package de modèles n'autorise pas l'appel dynamique de modèles, en utilisant une valeur de pipeline pour le nom du modèle. Donc, si vous essayez de faire quelque chose de similaire à mon exemple ci-dessous, cela ne fonctionnera pas.
Certaines solutions de contournement existent et il en est question sur Go-nut . Mais il semble que le package de modèle ait été conçu pour que vous ayez un objet *Template
par page.
Exemple cassé de tentative d'appel de modèle dynamique:
Erreur: ".Content" inattendu dans l'appel du modèle
package main
import (
"log"
"os"
"text/template"
)
const base= `<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
{{template .Content}}
</body>
</html>`
const first = `{{define "first"}}This is the first page{{end}}`
const second = `{{define "second"}}And here is the second{{end}}`
type View struct {
Content string
}
func main() {
var view = &View{ "first" } // Here we try to set which page to view as content
t := template.Must(template.New("base").Parse(base))
t = template.Must(t.Parse(first))
t = template.Must(t.Parse(second))
err := t.Execute(os.Stdout, view)
if err != nil {
log.Println("executing template:", err)
}
}
la partie 3 de ce tutoriel est utile:
http://golangtutorials.blogspot.co.nz/2011/11/go-templates-part-3-template-sets.html
Exemple du tutoriel:
Fichier de modèle complet - t1.tmpl
{{define "t_ab"}}a b{{template "t_cd"}}e f {{end}}
Le fichier ci-dessus sera analysé comme un modèle nommé "t_ab". Il contient "a b/missing/e f", mais il manque quelques lettres dans l'alphabet. Pour cela, il a l'intention d'inclure un autre modèle appelé "t_cd" (qui devrait être dans le même ensemble).
Fichier de modèle complet - t2.tmpl
{{define "t_cd"}} c d {{end}}
Le fichier ci-dessus sera analysé comme un modèle appelé "t_cd".
Programme complet
package main
import (
"text/template"
"os"
"fmt"
)
func main() {
fmt.Println("Load a set of templates with {{define}} clauses and execute:")
s1, _ := template.ParseFiles("t1.tmpl", "t2.tmpl") //create a set of templates from many files.
//Note that t1.tmpl is the file with contents "{{define "t_ab"}}a b{{template "t_cd"}}e f {{end}}"
//Note that t2.tmpl is the file with contents "{{define "t_cd"}} c d {{end}}"
s1.ExecuteTemplate(os.Stdout, "t_cd", nil) //just printing of c d
fmt.Println()
s1.ExecuteTemplate(os.Stdout, "t_ab", nil) //execute t_ab which will include t_cd
fmt.Println()
s1.Execute(os.Stdout, nil) //since templates in this data structure are named, there is no default template and so it prints nothing
}
Si vous souhaitez analyser plusieurs répertoires avec des fichiers spécifiques, voici un extrait de code:
//parse a pattern in a specific directory
allTemplates := template.Must(template.ParseGlob("Directory/*"))
//add another directory for parsing
allTemplates = template.Must(allTemplates.ParseGlob("Another_Directory/*.tmpl"))
//add specific file name
allTemplates = template.Must(allTemplates.ParseFiles("path/to/file.tmpl"))
func main() {
...
}
func FileHandler(w http.ResponseWriter, r *http.Request) {
// access cached template by file name (in case you didn't define its name)
err := allTemplates.ExecuteTemplate(w, "file.tmpl", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func NameHandler(w http.ResponseWriter, r *http.Request) {
// access cached template by handler name
err := allTemplates.ExecuteTemplate(w, "handlerName", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
un raccourci rapide:
allTemplates := template.Must(
template.Must(
template.Must(
template.ParseGlob("directory/*.tmpl")).
ParseGlob("another_directory/*.tmpl")).
ParseFiles("path/to/file.tmpl")),
)
file.tmpl
peut ressembler à ceci:
<html>
This is a template file
</html>
name.tmpl
devrait ressembler à ceci
{{define "handlerName" }}
<p>this is a handler</p>
{{end}}