美文网首页
Go语言 Web开发(9)模板处理

Go语言 Web开发(9)模板处理

作者: 小杰的快乐时光 | 来源:发表于2018-08-23 06:07 被阅读0次

    什么是模板?
    在做JavaWeb开发时,经常会在JSP页面中通过插入 <%=....=%>来实现插入动态语言生成数据,而在Go语言中也有类似的功能处理。

    Go模板的使用
    在Go语言中,我们使用 template 包来进行模板处理,使用类似 Parse 、 ParseFile 、 Execute 等方法从文件或者字符串加载模板,然后执行类似上面图片展示的模板的merge操作。

    模板规则
    模板是一个包含了一个或多个双花括号标记({{...}})的字符串,这种双花括标记号叫做Action。模板中所有的除Action的字符串都按照原样打印。通过Action可以打印变量的值、字段的值、调用函数或方法、表达控制流程等。 {{.}} 表示当前的对象,这和Java或者C++中的this类似,如果要访问当前对象的字段通过 {{.FieldName}} ,但是需要注意一点:这个字段必须是导出的(字段首字母必须是大写的),否则在渲染的时候就会报错。

    相关函数:
    text/template与html/template提供了相同的API来创建、解析和执行模板,区别是html/template提供了HTML转义。

    // 创建一个名字为name的模板
    func New(name string) *Template
    // 解析模板字符串
    func (t *Template) Parse(text string) (*Template, error)
    // 解析文件
    func ParseFiles(filenames ...string) (*Template, error)
    // 执行模板,将结果写入wr
    func (t *Template) Execute(wr io.Writer, data interface{}) error
    

    使用Must()来处理Parse()的结果,作用是检测模板是否正确,例如大括号是否匹配,注释是否正确的关闭,变量是否正确的书写
    如果Parse()失败,则调用panic(),如果成功,返回Template对象。

    func Must(t *Template, err error) *Template
    

    Funcs()用来给函数注册模板,注册之后模板就可以通过名字调用外部函数了

    func (t *Template) Funcs(funcMap FuncMap) *Template
    

    示例一:普通创建模板

    import (
       "html/template"
       "log"
       "os"
    )
    
    func main()  {
       //创建一个 Welcome 模板,并解析指定字符串
       tem,err := template.New("Welcome").Parse("Hello {{.}},Welcome come to Go")
       if err != nil {
          log.Fatal(err)
       }
       //执行模板,传入对应的参数
       tem.Execute(os.Stdout,"zengjie")
    }
    ----output----
    Hello zengjie,Welcome come to Go
    

    示例二:访问结构体字段

    func main()  {
       //emplate访问结构体字段时利用了反射机制,因此必须导出字段才能在模板里访问
       tem:= template.Must(template.New("Welcome").Parse("Hello {{.Name}} {{.Age}},Welcome come to Go"))
       //执行模板,传入对应的参数
       //tem.Execute(os.Stdout,"zengjie")
       tem.Execute(os.Stdout, struct {
          Name string
          age int
       }{"zengjie",12})
    }
    ----output----
    Hello zengjie 12,Welcome come to Go
    
    注意:{{.Age}}中的Age与struct {  Age int  } 必须都是大写才能正确被输出
    

    示例三:循环输出
    可以使用 {{with …}}…{{end}} 和 {{range …}}{{end}} 来表示循环数据输出,每次迭代中点(.)代表当前迭代的值。
    {{range}}:这个和Go语法里面的range类似,循环操作数据
    {{with}}:操作是指当前对象的值,类似上下文的概念

    type Car struct {
       CarName string
       CarType string
       Wheels []*Wheel
    }
    type Wheel struct {
       WheelName string
    }
    
    
    func main()  {
       //创建车的四个轮子
       wheel1 := Wheel{WheelName:"前轮"}
       wheel2 := Wheel{WheelName:"后轮"}
       wheel3 := Wheel{WheelName:"左轮"}
       wheel4 := Wheel{WheelName:"右轮"}
       //创建一辆车
       car := Car{CarName:"红旗",CarType:"国产",Wheels:[]*Wheel{&wheel1,&wheel2,&wheel3,&wheel4}}
    
       //创建新模板
       tem := template.New("Car Tempplate")
       tem,err := tem.Parse("This is {{.CarName}}! it is {{.CarType}},have {{range .Wheels}}  {{.}} {{end}} ")
       if err == nil {
          tem.Execute(os.Stdout,car)
       }
    }
    
    ----output----
    This is 红旗! it is 国产,have   {前轮}   {后轮}   {左轮}   {右轮}  
    

    将上面的 {{range …}}{{end}} 改为 {{with …}}…{{end}},结果不变。

    tem,err := tem.Parse("This is {{.CarName}}! it is {{.CarType}},have {{with.Wheels}} {{range.}} {{.WheelName}} {{end}}{{end}} ")
    

    示例四:条件处理 if else
    模板中使用if else判断,格式为:if bool + 输出内容+ else +输出内容,if后面只能跟bool类型的值,无法使用条件判断,如1==1等

    Execute(os.Stdout, value)的value值如果为空,则if会认为是false,反之认为是true

    tEmpty := template.New("template test")
    tEmpty = template.Must(tEmpty.Parse(" {{if true}}内容输出111{{end}}\n"))
    tEmpty.Execute(os.Stdout, nil)
    -----output-----
    内容输出111
    
    tWithValue := template.New("template test")
    tWithValue = template.Must(tWithValue.Parse("{{if false}}内容输出111 {{end}}\n"))
    tWithValue.Execute(os.Stdout, "abc")
    ----output----
    无输出内容
    
    tIfElse := template.New("template test")
    tIfElse = template.Must(tIfElse.Parse("{{if false}}if部分{{else}}else部分{{end}}\n"))
    tIfElse.Execute(os.Stdout, nil)
    ----output----
    else部分
    

    示例五:用 | 将其左边的输出作为其右边的输入

    func main() {
       const temStr = `{{. | printf "%v"}}`
       t := template.Must(template.New("Welcome").Parse(temStr))
       t.Execute(os.Stdout, "zengjie")
    }
    

    示例七:模板调用函数

    //外部函数
    func Welcome(name string) string {
       return "Welcome, " + name + "!"
    }
    
    func main() {
       const temStr = `{{. |Welco}}`
       //通过Funcs()来将函数注册为模板,FuncMap(K:函数别名,v:对应的函数)
       t := template.Must(template.New("report").Funcs(template.FuncMap{"Welco": Welcome}).Parse(temStr))
       t.Execute(os.Stdout, "zengjie")
    }
    ----output----
    Welcome, zengjie!
    

    示例八:模板嵌套
    一个网页可以分为上,中,下三部分,那么在嵌套时也可以划分为三个模块的组合,分为以下几个步骤:
    ①定义三个文件, header.tmpl 、 content.tmpl 、 footer.tmpl 文件

    //header.tmpl
    {{define "header"}}  
    <html>
    <head>
            <meta charset="UTF-8">
            <title> 演示信息 </title>
    </head>
    <body>
    {{end}}
    //content.tmpl
    {{define "content"}}
    {{template "header"}}
            <h1> 演示嵌套 </h1>
            <ul>
            <li> 嵌套使用 define 定义子模板 </li>
            <li> 调用使用 template</li>
            </ul>
    {{template "footer"}}
    {{end}}
    //footer.tmpl
    {{define "footer"}}
    </body>
    </html>
    {{end}}
    

    ②后台代码如下:

    import (
    "fmt"
    "os"
    "text/template"
    )
    func main() {
      //  通过 template.ParseFiles 把所有的嵌套模板全部解析到模板
       s1, _ := template.ParseFiles("header.tmpl", "content.tmpl", "footer.tmpl")
       s1.ExecuteTemplate(os.Stdout, "header", nil)
       fmt.Println()
       s1.ExecuteTemplate(os.Stdout, "content", nil)
       fmt.Println()
       s1.ExecuteTemplate(os.Stdout, "footer", nil)
       fmt.Println()
       s1.Execute(os.Stdout, nil)
    }
    

    参考文章:https://blog.csdn.net/u011304970/article/details/71195675

    参考书籍:Go Web 编程

    相关文章

      网友评论

          本文标题:Go语言 Web开发(9)模板处理

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