go 模板

template.ParseFiles()
实现: func ParseFiles(filenames ...
string) (*Template, error) { return parseFiles(nil, readFileOS, filenames...) }
func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
    return parseFiles(t, readFileOS, filenames...)
}

template.ParseFiles函数和ParseFiles方法都是调用底层函数parseFiles

func parseFiles(t *Template, readFile func(string) (string, []byte, error), filenames ...string) (*Template, error) {
    if err := t.checkCanParse(); err != nil {
        return nil, err
    }

    if len(filenames) == 0 {  //检查是否有模板文件名
        // Not really a problem, but be consistent.
        return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
    }
    for _, filename := range filenames {   //遍历模板文件名
        name, b, err := readFile(filename) //读取模板文件内容 
        if err != nil {
            return nil, err
        }
        s := string(b)        
        // First template becomes return value if not already defined,
        // and we use that one for subsequent New calls to associate
        // all the templates together. Also, if this file has the same name
        // as t, this file becomes the contents of t, so
        //  t, err := New(name).Funcs(xxx).ParseFiles(name)
        // works. Otherwise we create a new template associated with t.
        var tmpl *Template
        if t == nil {    //检查t是否为nil,为nil是template.ParseFiles函数调用
            t = New(name)  //若是nil则生成一个*Template实例,名字为第一个模板文件名
        }
        if name == t.Name() {//若t不为nil,为ParseFiles方法调用,检查所有的模板文件名
            tmpl = t     //是否有和t名字一样的,如果有则解析那个模板文件。
        } else {
            tmpl = t.New(name)
        }
        _, err = tmpl.Parse(s)
        if err != nil {
            return nil, err
        }
    }
    return t, nil
}

解析模板的几种方法:

①使用template.ParseFiles。模板名为第一模板文件名,使用t.Execute(w, data)使用模板只会使用执行第一个模板。

使用t.ExecuteTemplate(w, 模板文件名,data)可以指定使用哪个模板文件。

t, _ := template.ParseFiles("template2.html", "template1.html");
fmt.Println(t.Name())
//结果:template2.html

②先使用template.New(模板名)生成一个*Template实例,然后使用这个实例调用其ParseFiles()。New()中使用的模板名,要和传入ParseFiles()中的文件名中的一个对应,即解析了那个模板文件。

//template1.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{.}}
</body>
</html>
//template2.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ol>{{.}}</ol>
</body>
</html>
func main() {
    t := template.New("template2.html")
    fmt.Println(t.Name())    //输出t的模板名
    t, _ = t.ParseFiles("template2.html", "template1.html")
    t.Execute(os.Stdout, "hello")//输出内容
}

结果

template2.html    //输出的模板名
<!DOCTYPE html>      //输出的内容     
<html lang="en">          
<head>                    
    <meta charset="UTF-8">
    <title>Title</title>  
</head>
<body>
    <ol>hello</ol>
</body>
</html>

③解析字符串。使用*Template的方法Parse来解析字符串

func (t *Template) Parse(text string) (*Template, error)
func articlesCreateHandler(w http.ResponseWriter, r *http.Request) {
    html := `
<!DOCTYPE html>     
<html lang="en">          
<head>                    
    <meta charset="UTF-8">
    <title>Title</title>  
</head>
<body>
    <ol>{{.}}</ol>
</body>
</html>
`
t := template.New("tmpl")
t, _ = t.Parse(html)
t.Execute(w, "hello world")

模板动作

条件动作

 

posted on 2023-01-25 23:38  博览天下with天涯海角  阅读(89)  评论(0)    收藏  举报