Hugo框架中文文档 Hugo模板导引
Contents
下面是Go模板的入门介绍。深入介绍请参考 Go模板的官方文档Go docs.
Go模板提供了一个极端简单的模板语言, Go模板的信仰是只有最基本的逻辑应该出现在模板或视图中.
基本模式
Go模板的变量和函数在{{ }}
访问
访问预定义变量
预定义变量 可以是在当前范围内(如后面部分Variables)已经存在的变量,
或者是定制变量(如后面同样部分的$address
例子)
|
|
函数的多个参数以空格分隔, 一般模式如:
|
|
下面的例子调用了函数add
, 使用了输入1
和2
:
|
|
方法和字段通过点表示法访问
访问页面内容前言设定front matter中定义的页面参数bar
:
|
|
括号可以组合项目单元
|
|
变量 Variables
每个Go模板具有一个数据对象。在Hugo中,每个模板被传递了一个Page
对象.
下面例子中,.Title
是可以在 Page
variable页面变量中访问的元素中的一个.
以页面
为模板的默认范围, Title
元素在当前上下文中(.
– “the dot”)
可以简单的使用点前缀表示法访问(.Title
):
|
|
参数值也可以保存在定制变量中, 后面可以引用:
|
|
|
|
|
|
Hugo V0.48版本以后, 变量可以使用=
操作符号重新定义.(=
是Go语言1.11中出现的新特性).
下面例子只会在Hugo新版本中工作. 例子在主页会打印输出 “Var is Hugo Home”, 在所有其他页面打印输出 “Var is Hugo Page”
|
|
函数
Go语言模板仅仅自带了几个基础函数, 但是给应用提供了扩展原始函数集合的机制。
Hugo 模板函数 特别提供了针对构建网络站点的额外的功能. 通过使用名称调用函数, 后面跟随几个空格符分隔的需要的参数。 模板函数无法添加,除非重新编译Hugo.
例子1: 加法
|
|
例子2: 比较数字大小
|
|
注意两个例子都使用了Go模板的数学函数.
|
|
包含 Includes
当一个模板包含另一个模板时, 需要传递另一个模板需要访问的数据.
|
|
Hugo内模板所在位置总是从 layouts/
目录开始.
部分函数 Partial
函数 partial
用于包含 部分 partial 模板,
调用格式是 {{ partial "<PATH>/<PARTIAL>.<EXTENSION>" . }}
例如, 包含一个部分模板 layouts/partials/header.html
:
|
|
模板函数 Template
在很旧的Hugo版本中,template
函数用于包含 部分partial templates.
现在仅仅用于调用内部模板internal templates.
调用形式是{{ template "_internal/<TEMPLATE>.<EXTENSION>" . }}
.
|
|
包含内部 opengraph.html
模板的例子:
|
|
逻辑函数
Go 模板提供了最基本的迭代和条件逻辑.
迭代
Go 模板重度使用’range’函数迭代 map, array, or slice.
下面是如何使用range
的几个不同例子.
例子1: 使用上下文 (.
)
|
|
例子2: 为数组元素值声明一个变量
|
|
例子3: 为数组元素的索引和值声明变量名称
对于数组或者数组切片, 第一个声明的变量会映射到每个元素的索引.
|
|
例子4: 为Map元素的键 和 值声明变量名称
对于字典Map,第一个声明的变量会映射到map元素的键.
|
|
例子5: 空 map, array, 或者 _slice_的逻辑条件判断.
如果传递给range的 map, array, 或者 slice 为空, 那么else语句会被执行。
|
|
条件逻辑 Conditionals
Go语言模板中的if
, else
, with
, or
, 和 and
提供了处理条件逻辑的框架.
类似range
, 每个语句使用{{ end }}闭合。
Go模板中认为下列值为 false:
false
(boolean)- 0 (integer)
- 任何零长度的数组、切片、字典、和字符串
例子1: with
使用with
编写"如果一些事情存在, 这样做" 之类的语句很常见.
|
|
如果变量不存在,或者评估为上面解释中的"false", 那么会跳过代码块
|
|
例子2: with
.. else
下面的代码片段中,如果内容的前言设定设置了 “description”,就使用 “description"的值,
否则使用默认的 .Summary
页面变量:
|
|
参考 .Param
function.
例子3: if
编写处理 with
逻辑的另一个种选择(更冗长)是使用if
. 这里,.
并未被重新绑定.
下面是用if
重写的 “例子1”:
|
|
例子4: if
.. else
下面的例子是使用if
.. else
重写的 “例子 2”,此处替换成了isset
函数 + .Params
变量 (和.Param
函数不同)
|
|
例子5: if
.. else if
.. else
和 with
不同, if
语句也可以包含 else if
分支.
|
|
例子6: and
和 or
|
|
管道 Pipes
Go模板的最强大组件之一是以堆栈形式一个接一个调用方法的能力. 这通过使用pipes实现。管道概念来自于Unix管道, 概念很简单: 每个管道的输出成为接下来的管道的输入。
Go模板的非常简单的格式,管道是构建方法调用链的基础。 管道的一个限制是仅仅能作用于一个简单值并且它会成为管道下一个方法的最后一个参数.
下面几个简单例子有助于解释管道用法.
例子 1: shuffle
下面两个例子功能上是相同的:
|
|
|
|
例子 2: index
下面的代码访问页面参数 “disqus_url” 并转义为HTML. 例子中也使用了index
函数, 这是Go模板的内置函数:
|
|
例子 3: or
和 isset
|
|
可以重写成如下管道形式:
|
|
例子 4: IE浏览器的条件注释 Internet Explorer Conditional Comments
缺省情况下, Go模板会删除输出中的HTML注释. 这个会导致删除IE浏览器的条件注释的不幸的负效应. 作为解决方法,使用类似下面的方法:
|
|
或者,您可以使用反点号(`
)标记IE 条件 注释, 避免了注释内对每个双引号转义的繁杂的工作,如
Go文档中text/template部分的例子中一样:
|
|
上下文 Context (aka “the dot”)
理解Go模板中最容易被简单忽视的概念是{{ . }}
总是指向 当前上下文current context.
- 在最顶层的模板中, 这指的是它可以获取的数据集合.
- 在循环迭代中, 它具有循环中当前item的值。
{{ . }}
当前不在指向完整页面所有的数据集合.
如果需要在循环内部访问页面级别的数据(比如,在前言设定的页面参数), 可以通过如下方式的一种来实现:
1. 定义一个上下文独立的变量
下面例子展示了如何定义一个独立于上下文的变量.
|
|
|
|
2. 使用 $.
访问全局上下文
$
在模板中具有特殊的重要性. 缺省情况下.
(“the dot”)的最初的值被赋予$
. 这是一个Go语言文本/模板的有文档的特性。这意味着您可以在任何地点访问全局上下文. 下面例子重写了前面的代码块,不过现在是从全局上下文获取.Site.Title
:
|
|
|
|
空白 Whitespace
Go语言1.6包含了从Go tag标签的任何一边删除空白的能力,
只需要在对应的{{
或者 }}
分隔符旁边包含一个连字符号 (-
) 和跟随的空格.
下面列子中,Go模板会包含换行符和水平tag键在HTML输出中:
|
|
输出:
|
|
在下面利用 -
会删除围绕 .Title
多余的空白, 删除换行符:
|
|
输出:
|
|
Go语言认为下面字符是 空白 :
- space 空格键
- horizontal tab 水平tab键
- carriage return 会车
- newline 换行
注释
为了在团队内保持模板的良好结构, 并且分享信息, 需要在模板中添加注释. 在Hugo中有两种方式.
Go 模板注释
Go模板支持使用 {{/*
和 */}}
来开启关闭注释代码块。在注释块内一切不会被输出.
比如:
|
|
会输出 Bonsoir, Eliott.
, 并且会忽略注释块内的格式错误 (add 0 + 2
).
HTML 注释
如果需要从模板生成HTML注释,请参考前面的Internet Explorer 条件注释 例子.
如果需要变量来构建类似HTML注释, 使用 printf
到 safeHTML
管道即可. 比如:
|
|
包含Go模板的HTML注释
默认情况下HTML注释会被剥离,但是注释内容依然会被求值。
这意味着即使HTML注释永远不会生成任何内容到最终HTML页面,
在代码内的注释仍然可能使得构建过程失败.
|
|
|
|
模板引擎会删除HTML注释的内容,但是会首先评估注释内包含的任何Go模板代码。上面例子会生成 Emma Goldman
,
因为 $author
变量在HTML注释内获得值。不过如果HTML注释中代码包含错误会导致构建失败.
Hugo参数 Hugo Parameters
Hugo提供了从站点配置文件 (对于站点范围的值)或者从每个特定内容的元数据(front matter)来传递值给模板层的选项。只要前端格式支持, 您可以定义任何类型的参数,在您的模板中以任何方式使用。
使用内容(Page
)参数
可以通过单独内容的 front matter提供变量给模板使用.
Hugo Doc中使用了这样的例子。大部分Hugo Doc页面从提供的目录中获益,但是有时候文档目录并没有太大用。
我们在前言设定中定义了 notoc
变量, 当这个值特别设置为true
时,会阻止内容目录的生成。
使用front matter(YAML)的例子:
|
|
下面是可以在toc.html
partial template中使用的相应的代码:
|
|
对于没有明确声明的页面的默认行为是包含TOC.
模板检查确认页面前言设定的notoc:
值没有被设置为true
.
使用站点配置参数
可以在站点配置文件中任意定义站点界别的参数,想定义多少就可以定义多少。这些参数在页面模板中全局可以访问.
比如, 声明如下参数:
|
|
在页脚布局中, 你可能想仅当提供copyrighthtml
参数时声明一个
|
|
上面例子使用"if"然后引用同样的值,另一个替代方式是使用with
.
with
在其上下文中重新绑定(.
)符号, 如果变量不存在,代码块将会被忽略。
|
|
最后, 您可以从模板布局中提取"magic constants”. 下面例子使用了first
函数, 以及 .RelPermalink
页面变量和 .Site.Pages
站点变量.
|
|
例子: 仅仅显示未来的事件
Go可以让您做的比这里说的更多。使用Hugo的where
函数和Go语言的内建函数, 我们可以从内容块 content/events/
中仅仅列出日期(在内容文件的前言设定中设定)在未来的条目。
下面例子是一个部分模板partial template的例子:
|
|