html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。它提供了和 text/template包相同的接口,Go语言中输出HTML的场景都应使用html/template这个包。

html/template会自动帮你转义掉有风险的代码,避免xss攻击

模板需要注意的

  • 模板文件通常定义为.tmpl和.tpl为后缀(也可以使用其他的后缀),必须使用UTF8编码。
  • 模板文件中使用{{和}}包裹和标识需要传入的数据。
  • 传给模板这样的数据就可以通过点号(.)来访问,如果数据是复杂类型的数据,可以通过{ { .FieldName }}来访问它的字段。
  • 除{{和}}包裹的内容外,其他内容均不做修改原样输出。
  • 模板三步
    1. 定义模板
    2. 解析模板
    3. 渲染模板

模板文件

{{/*定义模板*/}}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello</title>
</head>
<body>
<p>hello {{ . }}</p>
</body>
</html>

go服务端

package main

import (
"net/http"
"text/template"
) func hello(w http.ResponseWriter, r *http.Request) {
//打开模板
t, err := template.ParseFiles("template/hello.tmpl")
if err != nil {
return
}
//渲染模板
name := "hello"
err := t.Execute(w, name)
if err != nil {
return
}
} func main() {
http.HandleFunc("/", hello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
return
}
}

map作为参数传入,直接使用参数访问

服务端

m1 := map[string]interface{}{
"name": "ll",
"gender": "female",
"age": 0,
}

模板文件

<p>hello {{ .name }}</p>
<p>hello {{ .age }}</p>
<p>hello {{ .gender }}</p>

结构体传入

名称必须是要大写才能被外界访问到

type User struct {
Name string
Gender string
Age int
} u1 := User{
Name: "ll",
Gender: "female",
Age: 0,
}

模板文件

<p>hello {{ .Name }}</p>
<p>hello {{ .Age }}</p>
<p>hello {{ .Gender }}</p>

想要一次传入多个参数,可以使用map来进行传入

u1 := User{
Name: "struct_para",
Gender: "female",
Age: 0,
}
m1 := map[string]interface{}{
"name": "map_para",
"gender": "female",
"age": 0,
}
err = t.Execute(w, map[string]interface{}{
"struct": u1,
"map_itf": m1,
})

模板文件

<p>hello {{ .struct.Name }}</p>
<p>hello {{ .map_itf.name }}</p>

变量

{{$v := 114}}
{{$}}

移除空格

移除左右的空格
{{- .name -}}

条件判断

{{ $v1 := 114 }}
{{if $v1}}
{{$v1}}
{{else}}
Nothing
{{end}}

预定义函数

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。
这个函数在html/template中不可用。
urlquery
以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。
这个函数在html/template中不可用。
js
返回与其参数的文本表示形式等效的转义JavaScript。
call
执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
其中Y是函数类型的字段或者字典的值,或者其他类似情况;
call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;

比较函数

eq      如果arg1 == arg2则返回真
ne 如果arg1 != arg2则返回真
lt 如果arg1 < arg2则返回真
le 如果arg1 <= arg2则返回真
gt 如果arg1 > arg2则返回真
ge 如果arg1 >= arg2则返回真

循环

{{range $idx,$hobby := .hobby}}
<p>{{$idx}} - {{$hobby}}</p>
{{else}}
empty
{{end}}

with共同前缀

类似    var . = .struct
{{with .struct}}
<p>hello {{ .Name }}</p>
<p>hello {{ .Age }}</p>
<p>hello {{ .Gender }}</p>
{{end}}

自定义函数

len := func(str string) (int, error) {
return len(str), nil
}
//渲染模板
//name := "hello"
t.Funcs(template.FuncMap{"len": len})

自定义函数用法

<p>hello {{ len .struct.Name }}</p>

模板嵌套

主模板


<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello</title>
</head>
<body> {{template "a.tmpl"}}
{{template "b.tmpl"}}
</body>
</html>
{{/*内部嵌套*/}}
{{define "a.tmpl"}}
<a>
<li>test_a_tmpl</li>
</a>
{{end}}

外部嵌套

b.tmpl

<b>
<li>test_b_tmpl</li>
</b>

服务端

package main

import (
"html/template"
"net/http"
) func hello(w http.ResponseWriter, r *http.Request) {
//先导入主文件 然后再导入嵌套文件
t, err := template.ParseFiles("template/hello.tmpl", "template/b.tmpl")
if err != nil {
return
}
t.Execute(w, nil)
} func main() {
http.HandleFunc("/", hello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
return
}
}

block模板继承

利用根模板进行组合

根模板

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ . }}</title>
<style>
*{
margin: 0;
}
.nav{
height: 50px;
width: 100%;
position: fixed;
top: 0; background-color: yellow;
}
.main{
margin-top: 50px;
}
.context{
width: 20%;
height: 100%;
position: fixed;
left: 0;
background-color: blue;
}
.center {
text-align: center;
} </style>
</head>
<body>
<div class="nav"></div>
<div class="main">
<div class="menu"></div>
<div class="context center">
{{block "content" .}}{{end}}
</div>
</div>
</body>
</html>

继承模板

{{template "base.tmpl"}}
{{/*此处定义的模板要和上面的相同*/}}
{{define "content"}}
<h1>home_page</h1>
{{end}}

服务端

先根模板后继承模板

func home2(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("template/base.tmpl", "template/test_home.tmpl")
if err != nil {
return
}
t.Execute(w, "home")
}

自定义标识符

防止和其他语言发生冲突

在解析模板的时候来定义

func test(w http.ResponseWriter, r *http.Request) {
t,err := template.New("test.tmpl").
Delims("{[", "]}").
ParseFiles("template/test.tmpl")
if err != nil{
return
}
t.Execute(w,nil)
}
这样标识符就成了 {[ name ]}了

使用gin框架的template模板

package main

import (
"github.com/gin-gonic/gin"
"html/template"
"net/http"
) func main() {
r := gin.Default()
//静态文件 解析前添加路径
r.Static("/name", "statics")
//自定义函数 解析前添加
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
//模板解析 ** -> 所有文件夹 * -> 所有文件
r.LoadHTMLGlob("templates/**/*")
//访问index的时候就执行后面的函数
r.GET("/users/index", func(ctx *gin.Context) {
//http请求
ctx.HTML(http.StatusOK, "users/index.tmpl", gin.H{ //模板渲染
"title": "moreac.top",
})
})
r.GET("/posts/index", func(ctx *gin.Context) {
//http请求
ctx.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ //模板渲染
"title": "moreac.top",
})
}) err := r.Run(":9090") if err != nil {
return
}
}
{{define "posts/index.tmpl"}}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>posts/index</title>
</head>
<body>
{{ .title }}
</body>
</html>
{{end}}

静态文件处理

网页上面使用到的样式文件 .css .js pic等


Go语言的template的更多相关文章

  1. djiango的模板语言(template)

    老师的博客:http://www.cnblogs.com/liwenzhou/p/7931828.html 官方文档:https://docs.djangoproject.com/en/1.11/re ...

  2. django模板语言之Template

    当前端的一些数据需要后端传送过来并展示时,用到了django的模板语言,模板语言的作用就是,在后端把一些处理好的数据,通过模板语言所规定的格式,通过render渲染,放到前端页面固定的位置展示.这之间 ...

  3. Django模板语言(Template)

    1.变量 变量相关用 { { } }   逻辑相关用{% %} 2.Filter过滤器 (1)default 如果一个变量是false或者为空,使用给定的默认值. 否则,使用变量的值.   {{ va ...

  4. 【转】Velocity模板(VM)语言介绍

    http://www.blogjava.net/caizh2009/archive/2010/08/20/329495.html Velocity是什么? Velocity是一个基于java的模板引擎 ...

  5. 【转载】Velocity模板引擎的介绍和基本的模板语言语法使用

    原文地址http://www.itzhai.com/the-introduction-of-the-velocity-template-engine-template-language-syntax- ...

  6. <Django> MVT三大块之Template(模板)

    1.模板简介 创建项目,基本配置 第一步:配置数据库 第二步:创建APP,配置APP 第三步:配置模板路径 第四步:配置分发urls.py(APP里面的) 根目录下,增加命名空间namespace,作 ...

  7. Vue + Webpack + Vue-loader 系列教程(1)功能介绍篇

    原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ Vue-loader 是什么? vue-loader 是一个加载器,能把如下格式的 Vue ...

  8. 只需2分钟,简单构建velocity web项目

    Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象 velocity ...

  9. NVelocity介绍,NVelocity中文手册文档及实例下载

    NVelocity是什么velocity英音:[vi'lɔsiti]美音:[və'lɑsətɪ]近在做一个项目,客户要求有网站模板功能,能够自主编辑网站的风格,因为这个系统是为政府部门做子站系统,举个 ...

  10. Velocity 语法(转)

    一.基本语法 1."#"用来标识Velocity的脚本语句,包括#set.#if .#else.#end.#foreach.#end.#iinclude.#parse.#macro ...

随机推荐

  1. python tcp select 多路复用

    1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 # 文件名:tcpserver.py 4 5 import socket 6 import time 7 ...

  2. ysoserial CommonsCollections2 分析

    在最后一步的实现上,cc2和cc3一样,最终都是通过TemplatesImpl恶意字节码文件动态加载方式实现反序列化. 已知的TemplatesImpl->newTransformer()是最终 ...

  3. 将自己的组件打包发布到npm

    在项目中有些组件在各个项目中都会调用,那么将组件发布到npm ,用到的项目去下载,这样会省去一些不必要的麻烦. 将组件发布到npm 中的步骤 做个记录 1.项目的创建,我这里使用 vue init w ...

  4. 词向量word2vec(图学习参考资料)

    介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现. 项目链接: https://aistudio.baidu.com/aistudio/projectdetail/500940 ...

  5. 关于C++ find

    #include <bits/stdc++.h> using namespace std; int a[1005]; int main() { for(int i = 0;i < 1 ...

  6. 第2-3-7章 个人网盘服务接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss

    目录 5.8 导入其他接口代码 5.8.1 接口导入-分页查询附件 5.8.2 接口导入-根据业务类型/业务id查询附件 5.9 导入网盘服务接口 5.9.1 导入FileController 5.9 ...

  7. python编程学习方法及计算机基础理论

    **从零开始学习编程 ** 一.学习前语 在学习python之前首先先说几点学习建议,首先是培养自己能解决问题的能力: 1.遇到问题时给自己设置一个解决该问题的时间限制 0-5min:自己解决问题(百 ...

  8. MySQL数据库下载以及启动软件的详细步骤

    第一步>>>在浏览器上百度上搜索MySQL 如何判断官网?有官网两个字的或者纯英文解释的大概率就是官网 第二步>>>点击DOWNLOAWDS 第三步>> ...

  9. PGL图学习之基于GNN模型新冠疫苗任务[系列九]

    PGL图学习之基于GNN模型新冠疫苗任务[系列九] 项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5123296?contributio ...

  10. Nginx rewrite 详解

    Nginx rewrite 详解 本篇主要介绍 nginx 的 rewrite 重定向这个功能进行 详解介绍, 以及介绍它的使用场景 1. rewrite 基本介绍 rewrite是实现URL重写的关 ...