自己创建 hugo 主题

2019-07-26 16:56:43 hugo 前端

hugo 作为一个很受欢迎的静态网站生成工具,其核心只是将网站的内容结构化,然后通过主题(theme)来 渲染这些结构化的数据,这样就可以非常灵活的修改网站的展示层。许多网友都贡献了 hugo 主题,当然最适合你自己的还是需要 do it youself,下面就开始吧。

实在忍不住先吐槽几句:hugo 使用 golang 来实现,golang 标准库中有个 template 模块用来支持模板功能,不过理念 和常见的 jinja、erb 模板功能相差太远,用起来也是十分别扭,灵活性差的一塌糊涂(吐血。。。)。 唯一的优点就是速度很快,当然这应该是得益于 golang 语言的优势。

下面正式开始。

模板文件结构

应该还记得hugo快速入门中安装主题的过程,不过这次我们是新建一个我们自己的主题。比如我们的主题名称叫做 sweety,下文都以此为例。

首先在 themes 目录下新建一个目录 sweety,并进入这个目录。

然后创建目录 layouts,我们所有的布局文件都放在这里,接着还要创建几个文件才能使我们的主题变得合法:

  • _default/baseof.html 整个站点的骨架文件,其他所有的布局文件都自动继承该文件
  • _default/list.html 列表页,比如文章列表页,某个类别或标签下属的文章列表页
  • _default/single.html 详情页,比如文章详情页面
  • _default/terms.html 分类页面,展示站点的分类维度,比如 category 分类、tag 分类
  • index.html 首页

这些文件可以先随意增加些内容,以便测试时有显示内容。

模板语法

基础语法

hugo 使用的 golang template 标准库来渲染模板,语法比较怪异,不过涉及的概念很少,可以很快上手。

执行命令或输出变量类似都是在双大括号中,块级命令有需要显式的 end 命令来结束:

<!-- 输出变量的值 -->
{{ .Title }}

<!-- 输出变量的值 -->
{{ if true }}
{{ end }}

上下文

golang 中属性通过首字母大小写来控制可见性,所以所有的内置变量首字母都是大写的。 另外变量前有个小数点 .,这个 . 表示当前的上下文,页面的上下文是 Page,具体的值由 hugo 负责传递给模板。

上下文是可变的,比如:

{{ range slice 'a' 'b' 'c'}}
    {{.}}
{{ end}}

上线的循环遍历了一个slice,每次都会将当前的上下文换成遍历到的元素,当前这个被置换的上下文仅在循环中可见。

如果我们在循环中想要访问全局上下文中的 Site 属性,应该怎么做呢,有两种方式:

第一种先将要用到的全局属性赋值给自定义变量,然后在循环中访问这个自定义的变量:

{{ $site := .Site }}
{{ range slice 'a' 'b' 'c'}}
    {{.}} - {{$site.Title}}
{{ end}}

另一种方法,可以通过使用 $. 在任何地方访问全局的上下文:

{{ range slice 'a' 'b' 'c'}}
    {{.}} - {{$.Site.Title}}
{{ end }}

需要注意 $. 是可以被赋值的,虽然不建议这么做。

自定义变量

定义变量语法和 golang 很像,但变量名要求 $ 开头:

{{ $pagesCount = len .Site.Pages}}

函数调用

函数调用语法比较奇怪,没有括号,参数用空格分割:

{{ index .Pages 0 }}

上面代码调用了 index 函数,读起来不甚明了,设置有些语言内置的关键字,在模板中竟然也是函数,比如逻辑或:

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

模板继承