30

创建一个基本模板。有了这个呈现的 first.html 另一个模板。

eg. :
    var tmpl = template.Must(template.ParseFiles(
    "templates/base.html",
    "templates/first.html",
    ))

但我也想添加更多 .html 文件来渲染。有什么参考吗?

4

4 回答 4

86

如果您在模板文件夹中定义所有模板,您可以轻松地解析整个目录:

template.Must(template.ParseGlob("YOURDIRECTORY/*"))

例如:

头.html

{{define "header"}}
     <head>
         <title>Index</title>
     </head>
{{end}}

索引.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
    }
}

您执行 indexPage-Template 与templates.ExecuteTemplate(w, "indexPage", nil)

于 2013-06-20T08:13:47.157 回答
9

您只需将它们添加为参数即可轻松添加更多 .html 文件:

var tmpl = template.Must(template.ParseFiles(
    "templates/base.html",
    "templates/first.html",
    "templates/second.html",
))

只要第一个和第二个不定义相同的模板,这工作就很好。
但是,模板包不允许使用模板名称的管道值动态调用模板。因此,如果您尝试执行类似于我下面的示例的操作,那么它将无法正常工作。

存在一些解决方法, Go-nuts上有关于它的讨论。*Template但似乎模板包的设计是每页应该有一个对象。

尝试动态模板调用的损坏示例:
错误:模板调用中的意外“.Content”

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)
    }
}

play.golang.org 上的代码

于 2013-06-20T07:24:18.877 回答
3

如果你想用特定文件解析多个目录,这里有一个代码片段:

//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
    }
}

快捷方式:

allTemplates := template.Must(
        template.Must(
        template.Must(
            template.ParseGlob("directory/*.tmpl")).
            ParseGlob("another_directory/*.tmpl")).
            ParseFiles("path/to/file.tmpl")),
                )

file.tmpl可以如下所示:

<html>
This is a template file 
</html>

name.tmpl应该是这样的

{{define "handlerName" }}
<p>this is a handler</p>
{{end}}
于 2019-02-12T20:45:07.723 回答
2

本教程的第 3 部分很有用:

http://golangtutorials.blogspot.co.nz/2011/11/go-templates-part-3-template-sets.html

教程中的示例:

完整的模板文件 - t1.tmpl

{{define "t_ab"}}a b{{template "t_cd"}}e f {{end}}

上面的文件将被解析为名为“t_ab”的模板。它在其中有“ab /missing/ e f”,但缺少字母表中的几个字母。为此,它打算包含另一个名为“t_cd”的模板(应该在同一个集合中)。

完整的模板文件 - t2.tmpl

{{define "t_cd"}} c d {{end}}

上面的文件将被解析为一个名为“t_cd”的模板。

完整程序

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
}
于 2016-06-23T00:05:24.523 回答