go语言的模板,text/template包

定义

模板就是将一组文本嵌入另一组文本里

传入string--最简单的替换

package main

import (
"os"
"text/template"
) func main() {
name := "waynehu"
tmpl, err := template.New("test").Parse("hello, {{.}}") //建立一个模板,内容是"hello, {{.}}"
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, name) //将string与模板合成,变量name的内容会替换掉{{.}}
//合成结果放到os.Stdout里
if err != nil {
panic(err)
}
}
//输出 : hello, waynehu

因为"hello, {{.}}"也是一个字符串,所以可以单独拎出来,如下:

//这句
tmpl, err := template.New("test").Parse("hello, {{.}}")
//等于下面的两句
muban := "hello, {{.}}"
tmpl, err := template.New("test").Parse(muban)
//之后的例子都用两句的方式表达

传入struct

模板合成那句,第2个参数是interface{},所以可以传入任何类型,现在传入struct看看 要取得struct的值,只要使用成员名字即可,看代码吧:

package main

import (
"os"
"text/template"
) type Inventory struct {
Material string
Count uint
} func main() {
sweaters := Inventory{"wool", 17}
muban := "{{.Count}} items are made of {{.Material}}"
tmpl, err := template.New("test").Parse(muban) //建立一个模板
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, sweaters) //将struct与模板合成,合成结果放到os.Stdout里
if err != nil {
panic(err)
}
}
//输出 : 17 items are made of wool

多模板,介绍New,Name,Lookup

//一个模板可以有多种,以Name来区分
muban_eng := "{{.Count}} items are made of {{.Material}}"
muban_chn := "{{.Material}}做了{{.Count}}个项目"
//建立一个模板的名称是china,模板的内容是muban_chn字符串
tmpl, err := template.New("china")
tmpl, err = tmpl.Parse(muban_chn)
//建立一个模板的名称是english,模板的内容是muban_eng字符串
tmpl, err = tmpl.New("english")
tmpl, err = tmpl.Parse(muban_eng)
//将struct与模板合成,用名字是china的模板进行合成,结果放到os.Stdout里,内容为“wool做了17个项目”
err = tmpl.ExecuteTemplate(os.Stdout, "china", sweaters)
//将struct与模板合成,用名字是china的模板进行合成,结果放到os.Stdout里,内容为“17 items are made of wool”
err = tmpl.ExecuteTemplate(os.Stdout, "english", sweaters) tmpl, err = template.New("english")
fmt.Println(tmpl.Name()) //打印出english
tmpl, err = tmpl.New("china")
fmt.Println(tmpl.Name()) //打印出china
tmpl=tmpl.Lookup("english")//必须要有返回,否则不生效
fmt.Println(tmpl.Name()) //打印出english

文件模板,介绍ParseFiles

//模板可以是一行
muban := "{{.Count}} items are made of {{.Material}}"
//也可以是多行
muban := `items number is {{.Count}}
there made of {{.Material}}
`

把模板的内容发在一个文本文件里,用的时候将文本文件里的所有内容赋值给muban这个变量即可
上面的想法可以自己实现,但其实tamplate包已经帮我们封装好了,那就是template.ParseFiles方法

假设有一个文件mb.txt的内容是muban变量的内容
$cat mb.txt
{{.Count}} items are made of {{.Material}} 那么下面2行
muban := "{{.Count}} items are made of {{.Material}}"
tmpl, err := template.New("test").Parse(muban) //建立一个模板 等价于
tmpl, err := template.ParseFiles("mb.txt") //建立一个模板,这里不需要new("name")的方式,因为name自动为文件名

文件模板,介绍ParseGlob

ParseFiles接受一个字符串,字符串的内容是一个模板文件的路径(绝对路径or相对路径)
ParseGlob也差不多,是用正则的方式匹配多个文件

假设一个目录里有a.txt b.txt c.txt的话
用ParseFiles需要写3行对应3个文件,如果有一万个文件呢?
而用ParseGlob只要写成template.ParseGlob("*.txt") 即可

模板的输出,介绍ExecuteTemplate和Execute

模板下有多套模板,其中有一套模板是当前模板
可以使用Name的方式查看当前模板

err = tmpl.ExecuteTemplate(os.Stdout, "english", sweaters)  //指定模板名,这次为english
err = tmpl.Execute(os.Stdout, sweaters) //模板名省略,打印的是当前模板

模板的复用

模板里可以套模板,以达到复用目的,用template关键字

muban1 := `hi, {{template "M2"}},
hi, {{template "M3"}}
`
muban2 := "我是模板2,{{template "M3"}}"
muban3 := "ha我是模板3ha!" tmpl, err := template.New("M1").Parse(muban1)
tmpl.New("M2").Parse(muban2)
tmpl.New("M3").Parse(muban3)
err = tmpl.Execute(os.Stdout, nil)

完整代码:

package main

import (
"os"
"text/template"
) func main() {
muban1 := `hi, {{template "M2"}},
hi, {{template "M3"}}
`
muban2 := `我是模板2,{{template "M3"}}`
muban3 := "ha我是模板3ha!" tmpl, err := template.New("M1").Parse(muban1)
if err != nil {
panic(err)
}
tmpl.New("M2").Parse(muban2)
if err != nil {
panic(err)
}
tmpl.New("M3").Parse(muban3)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
}

输出的内容

hi, 我是模板2,ha我是模板3ha!,
hi, ha我是模板3ha!

模板的回车

模板文件里的回车也是模板的一部分,如果对回车位置控制不好,合成出来的文章会走样 标准库里的Example(Template)写的还是有点乱,我整理如下:

const letter = `Dear {{.Name}},

{{if .Attended}}It was a pleasure to see you at the wedding.
如果Attended是true的话,这句是第二行{{else}}It is a shame you couldn't make it to the wedding.
如果Attended是false的话,这句是第二行{{end}}
{{with .Gift}}Thank you for the lovely {{.}}.
{{end}}
Best wishes,
Josie `

解释一下:

  • Dear某某某的Dear应该是在第一行,所以在D前面不能有回车,否则Dear会跑到第2行去

    • 所以Dear要紧贴```
  • 信件的称唿和正文有一行空行,最好显式的打出一行,而标准库里的回车是包在if里,成为正文的一部分,这样排版容易出错
  • 正确的正文排版如下
    • 如果正文就一行,要把true和false的所有内容都写在一行

      • 比如{{if .Attended}}true line,hello true{{else}}false line,hi false{{end}}
    • 如果正文有多行,就等于把一行拆成多行
      • 会发现true的最后一行和false的第一行是在同一行
      • {{if .Attended}}和ture的第一行在同一行
      • {{end}}和false的最后一行在同一行

如下

{{if .Attended}}true line
hello true{{else}}false line
hi false{{end}}
  • 关于{{with .Gift}},意思是如果Gift不是为空的话,就打印整行,如果为空,就不打印

    • 只有这样写法,with对应的end要写在第2行,才会把“Thank you”这句后面带一个回车进去,这样写法,就像“Thank you”这句是插在正文下面的
    • 只有这样写,不管有没有“Thank you”,正文和Best wishes,之间始终只有1行空白

go语言的模板,text/template包的更多相关文章

  1. [golang]text/template模板

    这个可以用来处理text文本,不过我更偏爱做成代码生成器. [golang]text/template模板 package main import ( "os" "tex ...

  2. golang 模板 html/template与text/template

    html模板生成: html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用t ...

  3. go语言template包中模板语法总结

    package main; import ( "html/template" "os" "fmt" ) type Person struct ...

  4. 前端模板<script type="text/template" id="tmpl">

    前端模板, 比连接字符串好用多了, 还可以使用循环\判断等语句, 减少工作量 <script type="text/template" id="member-tmp ...

  5. 关于MVC模板渲染的一点小事type="text/template"

    先上一个demo,简单粗暴,请自便 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  6. go标准库的学习-text/template

    参考:https://studygolang.com/pkgdoc 导入方式: import "text/template" template包实现了数据驱动的用于生成文本输出的模 ...

  7. Text Template Transformation Toolkit

    Text Template Transformation Toolkit       1.且算简介         笔者以一个英文字母和一个数字取了一个简单的名字.名唤"T4"(名 ...

  8. Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

    前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...

  9. DjangoMTV模型之视图层views及模板层template

    Django视图层中views的内容 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容(render),也可以是一个重定向( ...

随机推荐

  1. GUID分区与MBR分区

    1.MBR分区表类型的磁盘主引导记录(Master Boot Record,缩写:MBR),又叫做主引导扇区,它仅仅包含一个64个字节的硬盘分区表.由于每个分区信息需要16个字节,所以对于采用MBR型 ...

  2. 有关Azure存储帐号监视器中的度量值

    在一次故障排错中,发现存储帐号监视器里'成功百分比'(该度量值的源选择的是blob)这个度量值始终是低于100%.引出几个问题: 1. 这个度量值所代表的意义? A: 存储基于REST协议,对服务的访 ...

  3. 异机恢复perform restores

    Restoring and Recovering the database on a new host 第一台机器上mount模式下做全备   new host:   1.配置oracle_sid和之 ...

  4. noip2008普及组3题题解-rLq

    (第一次写题解,随意喷) (只是前一天的作业哈) (先凑个数) 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈 ...

  5. HDU 3600 Simple Puzzle 归并排序 N*N数码问题

    先介绍八数码问题: 我们首先从经典的八数码问题入手,即对于八数码问题的任意一个排列是否有解?有解的条件是什么? 我在网上搜了半天,找到一个十分简洁的结论.八数码问题原始状态如下: 1 2 3 4 5 ...

  6. 数字对 (长乐一中模拟赛day2T2)

    2.数字对 [题目描述] 小H是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R < ...

  7. <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_acce

    在tomcat/conf/server.xml里的<host>标签下加上 <Valve className="org.apache.catalina.valves.Acce ...

  8. Mybaits学习总结1

    http://www.cnblogs.com/xdp-gacl/p/4261895.html 参考了这篇文章搭建了Mybaits环境,原作者有些地方没有标注使用某种编码,我是自学SQL的,所以深知编码 ...

  9. FusionCharts参数的详细说明和功能特性(转)

    功能特性animation                    是否动画显示数据,默认为1(True)showNames                    是否显示横向坐标轴(x轴)标签名称ro ...

  10. [转]在Ubuntu 下安装Redis 并使用init 脚本启动

    1. 下载安装:   cd /tmp wget http://redis.googlecode.com/files/redis-2.2.4.tar.gz tar -zxf redis-2.2.4.ta ...