最近又尝试了一下 Golang 的 Template,发现一般功能都满足了,而且语法也相对比较简单,所以稍作总结。在 Go语言中,模板有 text/templatehtml/template 两个,但是接口都是一致的,区别在于 html/template 用于生成 HTML 输出,会自动得转移 HTML 标签用于防范攻击。

模板规则

Go 语言中,模板的特殊表达式都是通过 {{ 和 }} 引起来的,没有引起来的一般都是直接翻译出来就好了,所以也没啥特别说的。在 Go 语言的模板里面,掌握几个概念基本上就可以使用了,分别是:

  • pipeline
  • 变量
  • 函数

这基本上就是 Go 里面模板的主要功能了,后面就对这几个组件进行详述,看看分别是什么东西。

pipeline

pipeline 我觉得是 Go 语言的模板中差不多最复杂的一个东西了,其实 pipeline 可以理解成管道(如果你玩 Linux 的话),前面条命令的输出就是后面条命令的输入,而且 Go 语言的 pipeline 也支持变量取值,而且变量取值的本身就是 pipeline 中的一个环节。

除此之外,pipeline 中的函数还支持多个参数,2 个 3 个甚至多个参数都是支持的,除了管道前面的输出作为第一个参数之外,在函数后面接着的所有变量都是参数,依次排序。下面就是一个管道的示例:

.Name | toUpper | toEnglish

这里包含了 .Name 是一个变量,用于取值,然后 toUppertoEnglish 都是函数,除了使用 .Name 用于取值之外,还支持 .Method 用于调用函数,那么这里的取值和调用方法的对象主体是谁?这就是在渲染这个模板的时候传进来的对象,所有关于 . 的操作都以这个传递的对象为基准进行操作。

可使用表达式

  • {{pipeline}}: pipeline 结果的值会被直接输出
  • {{if pipeline}} T1 {{end}}: 如果 pipe 不 empty,那么 T1 就会被执行
    • The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero.
  • {{if pipeline}} T1 {{else}} T0 {{end}}:如果 pipeline 不 empty,T0 会被执行,否则 T1 会被执行
  • {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}:含义同上
  • {{range pipeline}} T1 {{end}}
    • pipeline 的结果必须是 array, slice, map 或者 channel
    • If the value is a map and the keys are of basic type with a defined order ("comparable"), the elements will be visited in sorted key order.
  • {{range pipeline}} T1 {{else}} T0 {{end}}: 如果 pipeline 是空的,那么 T1 不会被执行,T0 会被执行
  • {{with pipeline}} T1 {{end}}:如果 pipeline 不空,则 T1 会被执行
  • {{with pipeline}} T1 {{else}} T0 {{end}}:如果 pipeline 空,T0 会执行,否则,T1 会被执行
  • {{block "name" pipeline}} T1 {{end}}
    • {{define "name"}} T1 {{end}} 再加上 {{template "name" .}}

定义模板

  • 定义模板以 {{define "name"}} 开头,以 {{end}} 结尾
  • {{template "name"}}: 指定名字为 name 的模板并以 nil 的数据渲染
  • {{template "name" pipeline}}:执行名字为 name 的模板,并以 pipeline 的值渲染
  • 示例:

    // home.tmpl
    {{define "title"}}Home{{end}}
    {{define "content"}}This is the Home page.{{end}} // base.tmpl, template 里面没有默认内容
    <title>{{template "title" .}}</title>
    <body>{{template "content" .}}</body> // base.tmpl 和 home.tmpl 顺序很重要,错误了将得不到输出
    t, err := template.ParseFiles("base.tmpl", "home.tmpl")
    if err != nil {

Block

  • 和 template 差不多,但是 block 有默认值,可以通过 define 覆盖
  • template 没有默认值,只能通过 define 来定义
  • 示例:

    // home.tmpl
    {{define "title"}}Home{{end}}
    {{define "content"}}This is the Home page.{{end}} // base.tmpl, block 里面有默认内容,如果上面没有定义,依旧会输出内容
    <title>{{block "title" .}}Default Title{{end}}</title>
    <body>{{block "content" .}}This is the default body.{{end}}</body> // base.tmpl 和 home.tmpl 顺序很重要,错误了将得不到输出
    t, err := template.ParseFiles("base.tmpl", "home.tmpl")
    if err != nil {

渲染模板

  • 直接渲染默认的模板:tmpl.Execute(os.Stdout, "no data needed")
  • 根据名字渲染模板:tmpl.ExecuteTemplate(os.Stdout, "name", "no data needed")

常用变量

  • boolean,string,character,interget,float,复杂常量等常用数据类型
  • nil 表示 Go 中的无类型 nil
  • '.' 表示 dot 的值
  • $ 符号加变量名表示变量的值,例如:$username
  • struc 的 field 值:.Filed 或者 .File1.File2 或者 $arg.Field1.Field2
  • map 的值,.Key 或者 $map.Key
  • 调用方法:.Method
  • 调用函数:.Fun

变量赋值

在模板中也可以对 pipeline 的值进行赋值,赋值的方式如下:

$variable := pipeline
range $index, $element := pipeline

模板函数

During execution functions are found in two function maps:

  • first in the template
  • then in the global function map.

预定义的全局函数

  • and:返回第一个空的参数或者最后一个元素(所有都不为空?)!注意,所有的参数都会被计算
  • call:调用第一个参数,使用后面的参数作为调用的参数
  • html:返回 HTML 转义的值
  • index:返回第一个参数的索引位置的值
  • js:返回转义过的 JS 代码
  • len:返回参数的长度
  • not:返回唯一一个参数的反值
  • or:返回所有参数中第一个不为空的,或者最后一个元素(所有都为空?)!无论如何,所有的值都会被计算
  • print:alias for fmt.Sprint
  • printf:alias for fmt.Sprintf
  • println:alias for fmt.Sprintln
  • urlquery:将值转义成可嵌入 URL Query 语句的值

预定义的布尔函数

  • eq:返回 arg1 == arg2
  • ne:arg1 != arg2
  • le:arg1 < arg2
  • le:arg1 <= arg2
  • gt:arg1 > arg2
  • ge:arg1 >= arg2

注释

{{/* a comment */}}

特殊字符

  • {{ }}: 用于输出变量的值
  • {{- 或 -}}:用于删除后面或前面的空格(注意,不是变量的空格)

Glob

从一个目录中加载一系列的模板

函数的使用

  • func New(name string) *Template:等价于 {{define "name"}} {{end}}
  • func Must(t *Template, err error) *Template:helper 函数,如果 err 为 False 则 panic,否则返回 Template
  • func ParseFiles(filenames ...string) (*Template, error):如果 filenames 有不同目录相同的名字,那么,后面的将会覆盖前面的
    • 所以 filenames 的顺序很重要,弄错了将会导致无法正确渲染
    • 但是所有定义在这些文件中的 template 和 block 都会被保存在返回的 Template 中

Reference

  1. How to Use Template Blocks in Go 1.6

Golang 模板的更多相关文章

  1. golang模板语法简明教程

    [模板标签] 模板标签用"{{"和"}}"括起来   [注释] {{/* a comment */}} 使用“{{/*”和“*/}}”来包含注释内容   [变量 ...

  2. golang 模板(template)的常用基本语法

    1. 模板 在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页,golang提供了html/template包来支持模板渲染. 这篇文章不讨论gola ...

  3. golang模板语法简明教程(后面有福利哦)

    template是go 语言web开发中必不可少的,特此记录下来: [模板标签] 模板标签用"{{"和"}}"括起来   [注释] {{/* a comment ...

  4. golang 模板语法使不解析html标签及特殊字符

    场景 有时候需要使用go的模板语法,比如说用go 去渲染html页面的时候,再比如说用go的模板搞代码生成的时候.这时候可能会遇到一个麻烦,不想转译的特殊字符被转译了. 我遇到的情况是写代码生成器的时 ...

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

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

  6. golang模板语法

    https://www.cnblogs.com/Pynix/p/4154630.html https://blog.csdn.net/huwh_/article/details/77140664 ht ...

  7. golang深坑记录

    go深坑:1.gin.context.JSON,如果没有make数组时,数组返回为null,make后,数组为[]2.json.Number转int64类型 datatemp.(json.Number ...

  8. istio1.0.2配置

    项目的组件相对比较复杂,原有的一些选项是靠 ConfigMap 以及 istioctl 分别调整的,现在通过重新设计的Helm Chart,安装选项用values.yml或者 helm 命令行的方式来 ...

  9. libnetwork插件化网络功能

    Docker把网络跟存储这两部分的功能实现都以插件化形式剥离出来,允许用户通过指令来选择不同的后端实现.这也是Docker希望构建围绕着容器的强大生态系统的一些积极的尝试.剥离出来的独立容器网络项目叫 ...

随机推荐

  1. 646. Maximum Length of Pair Chain

    You are given n pairs of numbers. In every pair, the first number is always smaller than the second ...

  2. 《Python绝技:运用Python成为顶级黑客》 用Python进行取证调查

    1.你曾经去过哪里?——在注册表中分析无线访问热点: 以管理员权限开启cmd,输入如下命令来列出每个网络显示出profile Guid对网络的描述.网络名和网关的MAC地址: reg query &q ...

  3. 前端入门html(常用标签及标签分类)

    day47 参考:https://www.cnblogs.com/liwenzhou/p/7988087.html 任何标签都有有三个属性:ID,class.style <!DOCTYPE ht ...

  4. Linux零碎知识

    ln -s用法: 创建软连接,命令如下: ln -s / /home/good/linkname ln的链接分软链接和硬链接两种: .软链接就是:“ln –s 源文件 目标文件”,只会在选定的位置上生 ...

  5. Storm Trident详解

    Trident是基于Storm进行实时留处理的高级抽象,提供了对实时流4的聚集,投影,过滤等操作,从而大大减少了开发Storm程序的工作量.Trident还提供了针对数据库或则其他持久化存储的有状态的 ...

  6. jvm(1)类的加载(三)(线程上下文加载器)

    简介: 类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的. Java Applet 需要从远程下载 Java 类文件到浏览器中并执行. 现在类加载器在 ...

  7. Storm系列一: Storm初步

    初入Storm 前言 学习Storm已经有两周左右的时间,但是认真来说学习过程确实是零零散散,遇到问题去百度一下,找到新概念再次学习,在这样的一个循环又不成体系的过程中不断学习Storm. 前人栽树, ...

  8. 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)

    转载请注明出处:http://www.cnblogs.com/bethansy/p/6890972.html 一.已知真实社区划分结果 1.NMI指数,互信息和标准化互信息 具体公式和matlab代码 ...

  9. javascript中的浅拷贝和深拷贝 分类: JavaScript 2015-05-07 15:29 831人阅读 评论(1) 收藏

    1.js对象浅拷贝 简单的赋值就是浅拷贝.因为对象和数组在赋值的时候都是引用传递.赋值的时候只是传递一个指针. 看下面的实例代码: var a = [1,2,3]; var b =a ; var te ...

  10. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...