Hugo 核心概念
概述
本文档旨在帮助您理解 Hugo 的核心概念和基本机制。掌握这些概念是有效使用 Hugo 的基础,涵盖模板系统、变量管理、控制流程以及内置函数的使用。
模板系统
模板引擎基础
Hugo 采用 Go 的 text/template
包作为模板引擎基础,并对其进行了扩展:
- 模板语法:使用双大括号
{{ }}
包围动作和表达式 - 上下文访问:通过点号
.
访问当前上下文的数据 - 函数调用:支持内置函数和自定义函数的调用
- 管道操作:可以将函数和操作串联起来处理数据
模板类型
Hugo 使用不同类型的模板来渲染不同种类的页面:
1. Home(首页)模板
渲染网站的首页,通常是 layouts/home.html
。
2. Page(页面)模板
渲染常规内容页面,如博客文章或产品页面。
3. Base(基础)模板
定义网站的整体结构,其他模板可以继承它:
<!DOCTYPE html>
<html>
<head>
<title>{{ .Title }}</title>
</head>
<body>
{{ block "main" . }}{{ end }}
</body>
</html>
4. 部分模板(Partial Templates)
存储在 layouts/_partials
目录下的可复用代码片段:
<!-- layouts/_partials/header.html -->
<header>
<h1>{{ .Site.Title }}</h1>
</header>
在其他模板中调用:
{{ partial "header.html" . }}
变量系统
上下文(点 .
)
.
符号代表当前上下文,用于访问数据:
{{ .Title }} <!-- 页面标题 -->
{{ .Content }} <!-- 页面内容 -->
{{ .Date }} <!-- 页面日期 -->
{{ .Site.Title }} <!-- 站点标题 -->
变量声明和赋值
初始化变量
使用 :=
初始化新变量:
{{ $title := .Title }}
{{ $posts := where .Site.RegularPages "Type" "post" }}
变量赋值
使用 =
给已初始化的变量赋值:
{{ $title := "默认标题" }}
{{ if .Title }}
{{ $title = .Title }}
{{ end }}
变量作用域
变量的作用域规则:
- 块内变量:在
if
、range
或with
块内部初始化的变量,作用域仅限于该块 - 模板级变量:在块外部初始化的变量,作用域为整个模板
{{ $globalVar := "全局变量" }}
{{ if .Title }}
{{ $localVar := "局部变量" }}
{{ $globalVar = "修改全局变量" }}
{{ end }}
<!-- $localVar 在此处不可访问 -->
<!-- $globalVar 保持修改后的值 -->
访问集合数据
切片和数组访问
使用 index
函数访问:
{{ $array := slice "apple" "banana" "cherry" }}
{{ index $array 0 }} <!-- 输出: apple -->
字典和映射访问
{{ $dict := dict "name" "Hugo" "type" "generator" }}
{{ index $dict "name" }} <!-- 输出: Hugo -->
{{ $dict.name }} <!-- 也可以这样访问 -->
控制流语句
条件语句
if/else if/else
{{ if .Title }}
<h1>{{ .Title }}</h1>
{{ else if .Description }}
<h1>{{ .Description }}</h1>
{{ else }}
<h1>默认标题</h1>
{{ end }}
比较操作符
{{ if eq .Type "post" }}
这是一篇文章
{{ end }}
{{ if and (gt .WordCount 100) (lt .WordCount 500) }}
这是中等长度的文章
{{ end }}
循环语句
range 遍历
遍历集合并为每个元素绑定上下文:
<!-- 遍历页面列表 -->
{{ range .Site.RegularPages }}
<article>
<h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
<p>{{ .Summary }}</p>
</article>
{{ end }}
<!-- 带索引的遍历 -->
{{ range $index, $page := .Site.RegularPages }}
<li>{{ add $index 1 }}. {{ $page.Title }}</li>
{{ end }}
循环控制
{{ range .Site.RegularPages }}
{{ if eq .Type "draft" }}
{{ continue }} <!-- 跳过草稿 -->
{{ end }}
{{ if gt .WordCount 1000 }}
{{ break }} <!-- 停止遍历 -->
{{ end }}
<p>{{ .Title }}</p>
{{ end }}
with 语句
将上下文设置为指定值:
{{ with .Params.author }}
<p>作者:{{ . }}</p>
{{ end }}
<!-- 等同于 -->
{{ if .Params.author }}
<p>作者:{{ .Params.author }}</p>
{{ end }}
block 语句
定义可在继承模板中重新定义的模板块:
<!-- baseof.html -->
{{ block "title" . }}
<title>{{ .Site.Title }}</title>
{{ end }}
<!-- single.html -->
{{ define "title" }}
<title>{{ .Title }} - {{ .Site.Title }}</title>
{{ end }}
高级控制流
return 语句
在部分模板中终止执行并返回值:
<!-- layouts/_partials/get-author.html -->
{{ with .Params.author }}
{{ return . }}
{{ end }}
{{ return "匿名作者" }}
try 语句
用于错误处理:
{{ $result := try (index .Params "nonexistent") }}
{{ if $result.Error }}
处理错误:{{ $result.Error }}
{{ else }}
值:{{ $result.Value }}
{{ end }}
内置函数分类
类型转换函数
{{ $number := "123" | int }} <!-- 字符串转整数 -->
{{ $string := 123 | string }} <!-- 整数转字符串 -->
{{ $float := "123.45" | float }} <!-- 字符串转浮点数 -->
集合操作函数
<!-- 过滤集合 -->
{{ $posts := where .Site.RegularPages "Type" "post" }}
<!-- 排序 -->
{{ $sorted := sort .Site.RegularPages "Date" "desc" }}
<!-- 获取前几项 -->
{{ $recent := first 5 $posts }}
<!-- 分组 -->
{{ $grouped := group .Site.RegularPages "Type" }}
字符串处理函数
{{ "Hello World" | lower }} <!-- hello world -->
{{ "hello world" | title }} <!-- Hello World -->
{{ .Content | truncate 100 }} <!-- 截取前100个字符 -->
{{ .Title | urlize }} <!-- 转换为URL友好格式 -->
数学运算函数
{{ add 1 2 }} <!-- 3 -->
{{ sub 10 3 }} <!-- 7 -->
{{ mul 4 5 }} <!-- 20 -->
{{ div 15 3 }} <!-- 5 -->
{{ mod 10 3 }} <!-- 1 -->
日期时间函数
{{ .Date.Format "2006-01-02" }} <!-- 格式化日期 -->
{{ now.Format "January 2, 2006" }} <!-- 当前时间 -->
{{ .Date.AddDate 0 0 7 | dateFormat "2006-01-02" }} <!-- 7天后 -->
比较函数
{{ eq .Type "post" }} <!-- 等于 -->
{{ ne .Draft true }} <!-- 不等于 -->
{{ gt .WordCount 500 }} <!-- 大于 -->
{{ lt .ReadingTime 5 }} <!-- 小于 -->
{{ and (not .Draft) (gt .WordCount 100) }} <!-- 逻辑与 -->
调试和开发工具
调试函数
<!-- 打印变量内容 -->
{{ printf "%#v" .Params }}
<!-- 调试输出 -->
{{ debug.Dump . }}
<!-- 错误输出 -->
{{ errorf "缺少必需的参数: %s" .Type }}
<!-- 警告输出 -->
{{ warnf "建议设置页面标题" }}
性能测试
{{ $timer := debug.Timer "section-render" }}
<!-- 一些复杂的模板逻辑 -->
{{ $timer.Stop }}
数据检查
<!-- 检查变量是否存在 -->
{{ if isset .Params "author" }}
作者:{{ .Params.author }}
{{ end }}
<!-- 检查变量类型 -->
{{ if reflect.IsSlice .Params.tags }}
标签数量:{{ len .Params.tags }}
{{ end }}
最佳实践
1. 模板组织
- 使用部分模板提高代码复用性
- 合理使用基础模板建立页面结构
- 按功能模块组织模板文件
2. 变量命名
- 使用有意义的变量名
- 遵循一致的命名约定
- 适当使用注释说明复杂逻辑
3. 性能优化
- 避免在循环中进行复杂计算
- 使用
partialCached
缓存部分模板 - 合理使用条件语句减少不必要的处理
4. 错误处理
- 使用
with
语句检查变量存在性 - 提供合理的默认值
- 使用
try
语句处理可能的错误
掌握这些核心概念后,您就可以有效地使用 Hugo 创建复杂而强大的静态网站了。