美文网首页Go
Go Web开发六:Template

Go Web开发六:Template

作者: 狂奔的胖蜗牛 | 来源:发表于2018-07-04 12:09 被阅读73次

    1.什么是模板?

    Web模板就是一些预先设计好的HTML页面,程序会通过重复的使用这些页面来创建一个或多个HTML页面。
    Go语言标准库有两个模板引擎,text/template和html/template。

    2.自定义模板

    模板中动作默认使用两个大括号{{动作}}包围。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
     {{.}}
    </body>
    </html>
    

    上面编写好了模板,使用Go语言的模板引擎使用模板。.是一个动作,模板引擎执行模板时,会用一个值去替换这个动作本身。

    package main
    
    import (
        "net/http"
        "html/template"
        "fmt"
    )
    
    func main() {
        server := http.Server{
            Addr: ":8080",
        }
        http.HandleFunc("/template", templateFunc)
        server.ListenAndServe()
    }
    
    func templateFunc(w http.ResponseWriter, r *http.Request) {
        t, err := template.ParseFiles("01HelloGo/src/TemplateF/tmpl.html")
        if err!=nil {
            fmt.Fprintln(w, err)
            return
        }
        t.Execute(w, "hello world!")
    }
    
    

    使用浏览器访问可以得到如下结果:

    屏幕快照 2018-07-01 下午10.45.35.png
    • ParseFiles函数对模板文件进行语法分析。
    • Execute执行模板函数将数据应用到模板里面。
    • 如果ParseFiles没有传入文件的绝对路劲,那么,就需要把该文件放入到服务器二进制文件存放的目录中。

    3.动作

    3.1条件动作

    {{if arg}}
    some content
    {{end}}
    

    或者

    {{if arg}}
    some content
    {{else}}
    other content
    {{end}}
    

    3.2使用条件动作

    定义出模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
            {{if .}}
            大于5!
            {{else}}
            小于5或者等于5!
            {{end}}
    </body>
    </html>
    

    编写出server:

    package main
    
    import (
        "net/http"
        "html/template"
        "math/rand"
        "time"
    )
    
    func main() {
        server := http.Server{
            Addr: ":8080",
        }
        http.HandleFunc("/if", ifFunc)
        server.ListenAndServe()
    }
    
    func ifFunc(w http.ResponseWriter, r *http.Request) {
        t, _ := template.ParseFiles("01HelloGo/src/TemplateF/IF.html")
        rand.Seed(time.Now().Unix())
        t.Execute(w, rand.Intn(10) > 5)
    }
    
    

    在上面的代码中.代表的是布尔值。

    3.3迭代动作

    可以对数组、切片、映射或者通道进行迭代,在迭代循环内部,.则会被设置为当前被迭代的元素。

    {{range array}}
    元素为{{.}}
    {{end}}
    

    模板代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
    <ul>
        {{range .}}
        <li>{{.}}</li>
        {{end}}
    </ul>
    </body>
    </html>
    

    服务端代码:

    package main
    
    import (
        "net/http"
        "html/template"
    )
    
    func main() {
        server := http.Server{
            Addr: ":8080",
        }
        http.HandleFunc("/range", rangeFunc)
        server.ListenAndServe()
    }
    
    func rangeFunc(w http.ResponseWriter, r *http.Request) {
        t, _ := template.ParseFiles("01HelloGo/src/TemplateF/Range.html")
        numbers := []int{1, 2, 3, 4}
        t.Execute(w, numbers)
    }
    

    最终结果:


    屏幕快照 2018-07-01 下午11.15.39.png

    如果被迭代的数据为空时,可以使用如下返回一个默认值:

    {{range .}}
    {{.}}
    {{else}}
    默认值
    {{end}}
    

    3.4设置动作

    允许在指定范围内为'.'设置值。

    {{with arg}}
    此时,.的值被设置成arg
    {{end}}
    

    编写html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
    <div>值为{{.}}</div>
    <div>
        {{with "world"}}
                现在设置为{{.}}
        {{end}}
    </div>
    <div>再次设置{{.}}</div>
    </body>
    </html>
    

    在server中添加新的请求处理:

    func withFunc(w http.ResponseWriter, r *http.Request) {
        t, _ := template.ParseFiles("01HelloGo/src/TemplateF/With.html")
        t.Execute(w, "hello")
    }
    

    执行结果:

    屏幕快照 2018-07-04 上午11.07.20.png

    设置动作也能有一个备用方案:

    {{with arg}}
    .被设置成arg
    {{else}}
    假如arg是空的,则执行备选
    {{end}}
    

    修改with.html的代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
    <div>值为{{.}}</div>
    <div>
        {{with ""}}
                现在设置为{{.}}
        {{else}}
                由于with设置值为空,所以值依旧是{{.}}
        {{end}}
    </div>
    <div>再次设置{{.}}</div>
    </body>
    </html>
    

    此时再次访问:

    屏幕快照 2018-07-04 上午11.12.31.png

    3.5包含动作

    允许在一个模板里包含另一个模板,构建出嵌套模板。

    {{template "name"}}
    name为包含的模板的名字
    

    新建一个t1和t2模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
    <div style="background-color: yellow;">
        这是t1的内容
    </div>
    </body>
    </html>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Go Web</title>
    </head>
    <body>
    <div>这是t2的内容--开始</div>
    <hr/>
    {{ template "T1.html"}}
    <hr/>
    <div>这是t2的内容---结束</div>
    </body>
    </html>
    

    添加请求处理函数:

    func templateFun(w http.ResponseWriter, r *http.Request) {
        fmt.Println("template")
        t, _ := template.ParseFiles("01HelloGo/src/TemplateF/T2.html", "01HelloGo/src/TemplateF/T1.html")
        t.Execute(w, "")
    }
    

    请求结果:


    屏幕快照 2018-07-04 上午11.28.59.png

    可以看到,在处理函数中,我们必须将所有模板文件都进行语法分析。需要传入多个文件,其中,第一个模板文件是主模板,也就是说,主模板必须放第一个。

    如果主模板要向字模板传递数据,则需要这样写:

    {{template "name" arg}}
    

    3.6变量,管道

    可以在动作中设置变量:

    $variable := value
    

    也可以使用管道将多个参数、函数或者方法串联起来,将一个参数的输出传递个下一个参数,同Unix的管道:

    {{p1 | p2 | p3}}
    

    示例:

    变量:
    {{range $key, $value := .}}
    键:{{$key}},值:{{$value}}
    {{end}}
    
    管道:
    {{12.123456 | printf "%.2f"}}
    

    相关文章

      网友评论

        本文标题:Go Web开发六:Template

        本文链接:https://www.haomeiwen.com/subject/nkvhuftx.html