Hugo 模板系统负责将内容渲染成 HTML 和其他输出格式。它通过为静态网站生成设计的额外功能和函数来扩展 Go 内置的 HTML 和文本模板包。
模板系统是 Hugo 的一个基本组成部分,它将解析后的内容转换为渲染后的 HTML 或其他输出格式。它实现了一个复杂的查找机制、基于块的继承系统以及带有众多辅助函数的上下文丰富的执行环境。
有关特定模板函数的更多信息,请参阅 模板函数,有关 Hugo 提供的内置模板,请参阅 内置模板。
来源
Hugo 模板系统的核心是在 tpl/template.go34-37 中定义的 Template 接口,它为 Go 的 text/template 和 html/template 包提供了通用抽象
模板系统使用几个关键结构
RenderingContext tpl/template.go39-43 - 代表当前渲染的站点/语言Context tpl/template.go58-71 - 管理传递给模板的值DeferredExecution tpl/template.go137-145 - 持有将被推迟执行的模板数据CurrentTemplateInfo tpl/template.go161-164 - 包含正在执行的当前模板的信息来源
Hugo 使用多种模板类型,每种类型在渲染流程中都有特定用途
| 模板类型 | 目的 | 位置 |
|---|---|---|
| 基本模板 | 定义整体 HTML 结构和布局 | layouts/_default/baseof.html |
| 内容模板 | 渲染特定内容类型(单页、列表) | layouts/_default/single.html, layouts/_default/list.html |
| 区段模板 | 渲染特定区段的内容 | layouts/section/*.html |
| 局部模板 | 可重用的模板片段 | layouts/partials/*.html |
| 简码模板 | 可嵌入内容的模板片段 | layouts/shortcodes/*.html |
| 内部模板 | Hugo 提供的内置模板 | (内置于 Hugo 中) |
来源
Hugo 实现了一个复杂的模板查找算法,该算法为给定的内容项查找最合适的模板。这个查找系统是 Hugo 灵活性的核心,允许站点定义通用模板和特定的覆盖。
在查找基本模板时,Hugo 遵循以下顺序(如 hugolib/template_test.go31-44 中所示)。
对于内容模板(单页、列表等),Hugo 遵循不同的查找顺序
这种分层查找方法支持高度定制的模板。例如,站点可以在 _default/single.html 中定义默认的单页模板,然后使用 blog/single.html 等模板覆盖特定区段的模板。
来源
当 Hugo 渲染页面时,它遵循特定的执行流程
执行过程包括
来源
Hugo 使用基于块的继承系统,允许模板定义可由子模板覆盖的部分。
如 hugolib/template_test.go236-326 所示,这允许灵活的模板组合
下面是一个基本模板和使用它的内容模板的基本示例
基本模板 (_default/baseof.html)
<!DOCTYPE html>
<html>
<head>
<title>{{ block "title" . }}{{ .Site.Title }}{{ end }}</title>
</head>
<body>
<header>{{ block "header" . }}Default Header{{ end }}</header>
<main>{{ block "main" . }}Default Main Content{{ end }}</main>
<footer>{{ block "footer" . }}Default Footer{{ end }}</footer>
</body>
</html>
内容模板 (_default/single.html)
{{ define "title" }}{{ .Title }} | {{ .Site.Title }}{{ end }}
{{ define "main" }}
<article>
<h1>{{ .Title }}</h1>
{{ .Content }}
</article>
{{ end }}
来源
Hugo 在模板上下文中提供了一套丰富的视图数据和函数
如 hugolib/template_test.go384-408 所示,模板上下文提供了对以下内容的访问:
来源
Hugo 通过允许局部模板返回值来扩展局部模板的概念,如 hugolib/template_test.go410-491 所示
局部模板可以
partialCached 进行性能缓存define 在其他模板中内联定义$ 访问父上下文这种模式允许更模块化、更可重用的模板代码。例如:
<!-- layouts/partials/calculate-reading-time.html -->
{{ $wordCount := countwords .Content }}
{{ $readingTime := div $wordCount 200.0 }}
{{ return math.Ceil $readingTime }}
<!-- In a template -->
{{ $readingMinutes := partial "calculate-reading-time.html" . }}
<span>{{ $readingMinutes }} min read</span>
来源
Hugo 为模板错误提供详细的错误信息,使调试更加容易
如 hugolib/hugo_sites_build_errors_test.go 所示,Hugo 的错误处理提供了
例如,模板执行错误可能会产生类似以下的错误消息:
"layouts/_default/single.html:5:14": execute of template failed: template: _default/single.html:5:14: executing "_default/single.html" at <.Titles>: can't evaluate field Titles in type page.Page
这有助于开发人员快速定位和修复其模板中的问题。
来源
模板系统包含多种安全措施
HTML 转义:默认情况下,HTML 模板中的变量会自动转义,以防止跨站点脚本 (XSS) 攻击。
StripHTML 函数:StripHTML 函数在 tpl/template.go102-134 提供了安全移除内容中 HTML 标签的方法。
受控上下文访问:tpl/template.go58-71 中的上下文系统有助于维护系统不同部分之间的分离和安全。
来源
Hugo 的模板系统为网站生成提供了强大而灵活的基础。通过将 Go 的模板引擎扩展为包含特定于站点的函数、复杂的查找规则、错误处理和可组合的块系统,它为 Web 开发人员提供了简单性(用于常见任务)和深度(用于复杂需求)。
模板系统的关键优势包括:
有关特定模板函数的更详细信息,请参阅 模板函数,有关 Hugo 提供的内置模板,请参阅 内置模板。
来源