GO语言html模板
模板
一个模板是一个字符串或一个文件,里面包含了一个或多个由双花括号包含的{{action}}对象。大部分的字符串只是按面值打印,但是对于actions部分将触发其它的行为。每个actions都包含了一个用模板语言书写的表达式,一个action虽然简短但是可以输出复杂的打印值,模板语言包含通过选择结构体的成员、调用函数或方法、表达式控制流if-else 语句range循环语句,还有其它实例化模板等诸多特性。Action内部不能有换行,但注释可以有换行。
示例
模板执行时会遍历结构并将指针表示为’.‘(称之为”dot”)指向运行过程中数据结构的当前位置的值。
用作模板的输入文本必须是utf-8编码的文本。
Html示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<p>Hello {{.}}!</p>
</body>
</html>
GO server端:
func sayHi(w http.ResponseWriter,r *http.Request) {
// 解析指定文件生成模板对象
tem,err := template.ParseFiles("xx/hello.html")
if err != nil{
fmt.Println("读取文件失败,err",err)
return
}
// 利用给定数据渲染模板,并将结果写入w
tem.Execute(w,"Ares")
}
func main() {
http.HandleFunc("/",sayHi)
err := http.ListenAndServe("127.0.0.1:8888",nil)
if err != nil{
fmt.Println("监听失败,err",err)
return
}
}
效果:

模板语法
模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。
当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。Html示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<p>Hello {{.Name}}!</p>
<p>年龄 {{.Age}}!</p>
<p>性别 {{.Male}}!</p>
</body>
</html>
GO server端:
type People struct {
Name string
Age int
Male string
}
func sayHi(w http.ResponseWriter,r *http.Request) {
// 解析指定文件生成模板对象
tem,err := template.ParseFiles("xx/hello.html")
if err != nil{
fmt.Println("读取文件失败,err",err)
return
}
// 利用给定数据渲染模板,并将结果写入w
People := People{
Name:"Ares",
Age:28,
Male:"男",
}
tem.Execute(w,People)
}
func main() {
http.HandleFunc("/",sayHi)
err := http.ListenAndServe("127.0.0.1:8888",nil)
if err != nil{
fmt.Println("监听失败,err",err)
return
}
}
效果:

注释
{{/* a comment */}}
可以多行。注释不能嵌套。
变量
Action里可以初始化一个变量来捕获管道的执行结果。初始化语法如下:
$variable := pipeline
示例:
<body>
<p>Hello {{.Name}}!</p>
<p>年龄 {{.Age}}!</p>
<p>性别 {{.Male}}!</p>
{{ $age := . }}
{{ $age.Age }}
</body>
条件判断
初始语法:
{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
示例:
<body>
<p>Hello {{.Name}}!</p>
<p>年龄 {{.Age}}!</p>
<p>性别 {{.Male}}!</p>
{{ $age := . }}
{{ $age.Age }}
{{if gt .Age 18}}
<div>成年啦!</div>
{{else}}
<div>快乐成长!</div>
{{end}}
</body>
比较函数
布尔函数会将任何类型的零值视为假,其余视为真。
eq 如果arg1 == arg2则返回真
ne 如果arg1 != arg2则返回真
lt 如果arg1 < arg2则返回真
le 如果arg1 <= arg2则返回真
gt 如果arg1 > arg2则返回真
ge 如果arg1 >= arg2则返回真
range
使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、字典或者通道。
基本语法:
{{range pipeline}} T1 {{end}}
如果pipeline的值其长度为0,不会有任何输出
{{range pipeline}} T1 {{else}} T0 {{end}}
如果pipeline的值其长度为0,则会执行T0。
map示例:
PeopleMap := map[int]People{
1: {"Ares", 18, "男"},
2: {"龙猫", 28, "女"},
}
tem.Execute(w, PeopleMap)
切片示例:
PeopleSlice := []People{
{"Ares", 18, "男"},
{"龙猫", 28, "女"},
}
tem.Execute(w, PeopleSlice)
HTML模板:
<body>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</thead>
<tbody>
{{range $index, $user := .}}
<tr>
<td>{{$index}}</td>
<td>{{$user.Name}}</td>
<td>{{$user.Age}}</td>
<td>{{$user.Male}}</td>
</tr>
{{end}}
</tbody>
</table>
</body>
效果:

预定义函数
执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用Funcs方法添加函数到模板里。
and
函数返回它的第一个empty参数或者最后一个参数;
就是说"and x y"等价于"if x then y else x";所有参数都会执行;
or
返回第一个非empty参数或者最后一个参数;
亦即"or x y"等价于"if x then x else y";所有参数都会执行;
not
返回它的单个参数的布尔值的否定
len
返回它的参数的整数类型长度
index
执行结果为第一个参数以剩下的参数为索引/键指向的值;
如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。
print
即fmt.Sprint
printf
即fmt.Sprintf
println
即fmt.Sprintln
html
返回其参数文本表示的HTML逸码等价表示。
urlquery
返回其参数文本表示的可嵌入URL查询的逸码等价表示。
js
返回其参数文本表示的JavaScript逸码等价表示。
call
执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
其中Y是函数类型的字段或者字典的值,或者其他类似情况;
call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;
参考:GO语言标准库
示例:
<p>{{index . 1}}</p>
<p>切片长度: {{len .}}</p>
<p>
{{with index . 1}}
{{printf "姓名:%s 年龄:%d 性别:%s" .Name .Age .Male}}
{{end}}
</p>
效果:

自定义函数
自定义一个book函数:
type Book struct {
Name string
Author string
Price float32
}
func info(w http.ResponseWriter,r *http.Request) {
// 打开一个模板文件
htmlByte,err := ioutil.ReadFile("./info.html")
if err != nil{
fmt.Println("读取html文件失败,err",err)
return
}
// 1. 自定义一个函数
// 自定义一个书籍的模板函数
bookFunc := func(arg string) (string, error) {
return arg + "真好看!", nil
}
// 2. 把自定义的函数告诉模板系统
// template.New("info") // 创建一个Template对象
// template.New("info").Funcs(template.FuncMap{"book": bookFunc}) // 给模板系统追加自定义函数
// 解析模板
t,err := template.New("info").Funcs(template.FuncMap{"book": bookFunc}).Parse(string(htmlByte))
if err != nil{
fmt.Println("parse html文件失败,err",err)
return
}
BookMap := map[int]Book{
1:{"跟Ares一起学GO","Ares",9.9},
2:{"斗破苍穹","Ares1",99.9},
}
t.Execute(w,BookMap)
}
func main() {
http.HandleFunc("/info",info)
http.ListenAndServe("127.0.0.1:8888",nil)
}
html:
<body>
<p>
{{with index . 1}}
<p>{{book .Name}}</p>
{{end}}
</p>
<p>
{{with index . 2}}
<p>{{book .Name}}</p>
{{end}}
</p>
</body>
效果:

模板嵌套
我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template.
func index(w http.ResponseWriter,r * http.Request) {
t , err := template.ParseFiles("./index.html","./test.html")
if err != nil{
fmt.Println("读取html文件失败,err",err)
return
}
t.Execute(w,nil)
}
func main() {
http.HandleFunc("/",index)
http.ListenAndServe("127.0.0.1:8888",nil)
}
index.html:
<body>
<h1>测试嵌套template语法</h1>
<hr>
{{template "test.html"}}
<hr>
{{/* 在index.html这个模板中调用了另外一个模板:index.html */}}
{{template "inside.html"}}
</body>
</html>
{{/* 在index.html这个模板中定义了另外一个模板:inside.html */}}
{{ define "inside.html"}}
<h1>inside.html</h1>
<ol>
<li>吃饭</li>
<li>睡觉</li>
<li>打豆豆</li>
</ol>
{{end}}
test.html:
<body>
<ol>
<li>嵌套模板</li>
<li>out模板</li>
</ol>
</body>
效果:

GO语言html模板的更多相关文章
- go语言的模板,text/template包
go语言的模板,text/template包 定义 模板就是将一组文本嵌入另一组文本里 传入string--最简单的替换 package main import ( "os" &q ...
- Xamarin XAML语言教程模板视图TemplatedView(二)
Xamarin XAML语言教程模板视图TemplatedView(二) (2)打开MainPage.xaml文件,编写代码,将构建的控件模板应用于中TemplatedView.代码如下: <? ...
- Xamarin XAML语言教程模板视图TemplatedView(一)
Xamarin XAML语言教程模板视图TemplatedView(一) 模板视图TemplatedView 与模板页面相对的是TemplatedView,它被称为模板视图,它的功能和模板页面类似,也 ...
- Xamarin XAML语言教程模板页面TemplatedPage
Xamarin XAML语言教程模板页面TemplatedPage 模板页面TemplatedPage 在上文中我们提到了TemplatedPage,它被称为模板页面,用来显示控件模版.Templat ...
- django基础 -- 4. 模板语言 过滤器 模板继承 FBV 和CBV 装饰器 组件
一.语法 两种特殊符号(语法): {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 二.变量 1. 可直接用 {{ 变量名 }} (可调用字符串, 数字 ,列表,字典,对象等) ...
- Django框架(十一):模板介绍、模板语言、模板继承、HTML转义
1. 模板介绍 1.1 模板的功能 产生html,控制页面上展示的内容.模板文件不仅仅是一个html文件. 模板文件包含两部分内容: 静态内容:css.js.html. 动态内容:用于动态去产生一些页 ...
- C 语言通用模板队列
前言 嵌入式开发过程中,各个模块之间,各个设备之间进行交互时,都会存在数据的输入输出,由于处理的方式不同,数据不会立即同步处理,因此通常在设计时都会设计缓冲区进行数据的处理,方式数据丢失等问题:一个项 ...
- C语言状态机模板
转载声明:如果转载本博客内容,请联系869119842@qq.com,获得作者书面授权. 前言 上一篇我的博客中探讨了一种非swtich-case结构的状态机写法,但是个人感觉写起来比较麻烦,如果增加 ...
- C 语言中模板的几种实现方式
简单宏定义实现 简单宏定义 - 方式一 这种方式将主要实现部分放在一个宏定义中,利用字符替换的方式实现不同 type 的运算,详细思路见代码: simple_macro_1.c #include &l ...
随机推荐
- python多线程爆破压缩包密码
import zipfile from threading import Thread #多线程库 import optparse #选定字典或者文件 def extractFile(zfile,pa ...
- [转]数据库性能优化(老Key)
数据库性能优化一:数据库自身优化(大数据量) https://www.cnblogs.com/AK2012/archive/2012/12/25/2012-1228.html 数据库性能优化二:数据库 ...
- Http状态码502问题复盘
问题原因分析:502 bade gateway 一般都是upstream出错,对于PHP,造成502的原因常见的就是脚本执行超过timeout设置时间,或者timeout设置过大,导致PHP进程长时间 ...
- 微信小程序---客服消息接口调用,拿来即用
如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人.谢谢大家!❤ 如果解决不了,可以在文末进群交流. 如果对你有帮助的话麻烦点个[推荐]~最好还可以follow一下我的GitHub~感谢观看! 在 ...
- pandas数据处理
首先,数据加载 pandas提供了一些用于将表格型数据读取为DataFrame对象的函数,期中read_csv和read_table这两个使用最多. 1.删除重复元素 使用duplicated()函数 ...
- zabbix Server 4.0 监控TCP的12种状态
zabbix Server 4.0 监控TCP的12种状态 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 大家对TCP三次握手比较熟悉了,都知道当发生DOSS攻击时,客户端发送 ...
- Jmeter 中正则表达式提取器Regular Expression Extractor
正则表达式提取器点击后置处理器中Post Processors 中的正则表达式提取器 Regular Expression Extractor Appy to: 表示作用于哪一个请求Main samp ...
- Java精通并发-wait与notify方法案例剖析与详解
在上一节中对Object的wait.notify.notifyAll方法进行了总结,这次举一个具体案例来进行巩固,题目如下: 编写一个多线程程序,实现这样的一个目标: 1.存在一个对象,该对象有一个i ...
- java -static的特性和使用,静态类/方法/块/内部类/回收机制
mark一下,今天的作业. java-core P115 如果将域定义为static,每个类中只有一个这样的域.(这里的域应该是指一片物理数据空间,而不是单纯的指代某一个变量,而是静态域). publ ...
- Selenium常用API的使用java语言之20-获取窗口截图
自动化用例是由程序去执行,因此有时候打印的错误信息并不十分明确.如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因. WebDriver提供了截图函数getScr ...