模板概述

模板是hugo的灵魂

hugo的模板

hugo采用go语言编写,hugo模板采用go的html模板引擎(库)。

hugo所有的输出都在模板中完成,包括过滤、分页、逻辑控制、变量输出等等。

基本模板

hugo的基本模板分为三种:详细页,列表页,首页。

详细页名称为single.html,用于对应单独一篇文章的输出。

列表页名称为list.html,用于一个栏目、类型、章节、日期等等归集的列表输出。列表页可以分页。

首页名称为index.html,用于导航列表页和详细页。单页面站点可以只有首页。

扩展模板(可选)

片段

把重复的部分分离到单独的文件中,例如头部、导航和底部。

内容视图

与编程是视图相同,就是组织一片内容输出,比如一个列表。

分类术语

一个分类术语的列表页,使用了“标签”也会生成响应的标签列表页。

其他模板

RSS模板用于生成rss聚合。不过这东西是web2.0的产物,到了现在似乎不怎么受人欢迎。

sitemap站点地图,生成XML格式的站点地图。站点地图是给搜索引擎看的。

404页面。这个需要服务器支持自定义,一般都支持。

hugo的Go模板

go模板是一个轻量级的模板引擎,如果你有过其他模板,比如php模板引擎的基础,你会发现go模板非常简单。

模板要做的事情只有一件,就是输出。其他的东西只是在控制输出,过滤输出,选择输出等。

go模板是被墙了的,所以能搜到学到的东西不多。

基本语法

go模板是html模板,使用go语言混合html代码的方式编写,后缀就是html。

  • 引入模板语言

例如使用“{{ a }}”来输出变量a。

{{a}}

在hugo中,所有的模板语句都放在双大括号“{{ }}”之中,用于区分html标签和go模板语言。

  • 参数用空格分开

与其他编程语言不同,两个参数使用 空格 分开

{{ add 1 2}}

上面是一个add函数,传入了两个参数1和2,注意这里函数也不需要括号“()”。上面的函数等同于“1+2”

  • 对象访问

点在很多编程语言中都是对象访问的。

{{.}}
{{.Params.bar}}

hugo模板可以只用一个点来输出当前的对象!

  • 括号分组

括号用于分开不同语句组

{{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }}

这个语句有点长,是个if or语句,其中or逻辑判断的两个语句用括号分组。

  • 变量输出

hugo的不同模板页(首页、列表页和详细页)可用的变量不同。

<title>{{ .Title }}</title>

上面的语句是html与hugo的混合,用于输出页面的标题title。

在hugo模板中,面向对象的编程,所有的变量都是以点开头的,好比“this.Title”,变量输出时是需要首字母大写的,而定义则不用。

更多可用的模板变量参看模板变量篇。

  • 函数

和上面的参数一样,hugo模板使用函数不需要括号,写名字就可以

{{ lt 1 2 }}
  • 包含文件

hugo模板可以互相包含,可以用以下两种方法把其他的文件包含进来。

{{ template "partials/header.html" . }}
{{ partial "header.html" . }}

包含的作用就是复制该文件的内容到插入点。因为在模板层里面有一个“partial”文件夹,使用第二种方式可以省略该文件夹,推荐使用第二种方式。

partial适合存放一些公共的部分,比如页面的head部分。在html5支持一些“伪”标签,比如footer、section这样的,对于内容组织和搜索引擎非常友好,建议partial片段划分以这样的伪标签为最小单位(辅助于视图)。

逻辑控制

  • 迭代

迭代就是我们常说的循环、遍历,用于输出数组的所有内容。迭代用 range 函数控制

例子一:

{{ range array }}
    {{ . }}
{{ end }}

例子二:

{{range $element := array}}
    {{ $element }}
{{ end }}

例子三:

{{range $index, $element := array}}
    {{ $index }}
    {{ $element }}
{{ end }}

通过上面的迭代语句,基本可以看出hugo的go模板语法。range迭代以“ end ”结束。

go的语法取了很多成熟语言的优点,当然有的保留了,有的改了,比如“$”开始的变量名,“:=”的赋值语句。

  • 条件判断

与迭代类似的,hugo模板采用if、else、with、or、and进行条件判断,并以end结束。

判断的条件值是布尔值,可以是true、false、1、0、数组和变量等。

例子一if条件:

{{ if isset .Params "title" }}
    <h4>{{ index .Params "title" }}</h4>
{{ end }}

例子二if,else:

{{ if isset .Params "alt" }}
    {{ index .Params "alt" }}
{{else}}
    {{ index .Params "caption" }}
{{ end }}

例子三and,or:

{{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}

例子四with:

{{ with .Params.title }}<h4>{{ . }}</h4>{{ end }}

with就是if的另外一种表示,是真则运行,否则直接跳过。

例子五if,else if:

{{ if isset .Params "alt" }}
    {{ index .Params "alt" }}
{{ else if isset .Params "caption" }}
    {{ index .Params "caption" }}
{{ end }}
  • 管道

管道是借用unix管道的概念,使用“|”分割,前一个语句的结果,作为后一个函数的最后一个参数带入,管道是条件等复杂操作的简化写法。

例子一:

{{ if eq 1 1 }} Same {{ end }}

可以改写为:

{{ eq 1 1 | if }} Same {{ end }}

例子二:

{{ index .Params "disqus_url" | html }}

例子三:

{{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}
    一些输出
{{ end }}

可以改写为:

{{  isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" | if }}
    一些东西
{{ end }}

使用管道判断浏览器:

{{ "<!--[if lt IE 9]>" | safeHTML }}
  <script src="html5shiv.js"></script>
{{ "<![endif]-->" | safeHTML }}

总结

hugo的模板是非常简单的,基本语法可以从官方下载几个模板看一看就知道了。

学习代码的最好方法是多读多写,因为index.html首页模板可以访问列表页list.html和详细页single.html中的全部变量,调试学习模板在首页里面进行是比较好的方式。