【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Hugo】搭建私人博客:面包屑(二)
分析了 breadcrumbs.html 的剩余内容,并配置了 ShowBreadCrumbs = true,展示了面包屑的效果,下面再来看另一个搜索功能
搭建私人博客
下面先来看搜索功能的模板文件 search.html,和之前介绍的面包屑 breadcrumbs.html 功能不同,breadcrumbs.html 是位于 layouts/partials/ 目录下,而 search.html 是位于 layouts/_default/ 目录中

在 Hugo 中,layouts/_default/ 和 layouts/partials/ 是两个不同用途的模板系统目录,下面分析下这俩的核心区别
1、首先是 layouts/_default/ 目录,是 Hugo 或主题中默认的页面模板,里面存放一些通用,默认的页面布局模板,用于渲染内容(比如文章正文,页面等)
当某个内容类型,比如 posts,没有专属的模板(比如 layouts/posts/single.html)时,Hugo 就会回退到 _default/single.html 来渲染单个内容页面
在 layouts/_default/ 中,常见的文件有
single.html:之前介绍侧边栏时介绍过,用于渲染单篇内容(比如博客文章)list.html:用于渲染内容列表(比如博客首页,分类页等)baseof.html:基础模板(可被其他模板继承)
可以看到,layouts/_default/ 中的文件与 Hugo 的内容类型和输出格式紧密相关,属于主模板层级,决定整个页面的结构和风格,简单来说,_default 目录里的文件是找不到更具体的模板时用的备用模板
2、然后是 layouts/partials/ 目录,里面存放着可重复使用的模板片段,类似函数或者子模块的功能,里面常见的模板有:导航栏(navbar),页脚(footer),侧边栏,SEO meta 标签等,以及任何想在多个页面中复用的代码块,其他模板可以通过 {``{ partial "filename.html" . }} 对该模板进行调用(Go 模板系统),也可以传入上下文 (.)或自定义数据(比如字典)等,很灵活,比如
go
{{ partial "header.html" (dict "title" "My Page" "site" .Site) }}
layouts/partials/ 里面的文件不直接渲染页面,而是被其他模板包含使用,这样可以提高代码的复用性和可维护性,减少重复代码,可以这么理解,partials 里面的文件是可以在任何地方插入的小零件 ,比如 _defualt/ 或者 partials/ 自身的模板系统可以通过 {``{ partial *.html }} 来引用这些公共代码块

最后对比总结下
| 特性 | _default/ | partials/ |
|---|---|---|
| 用途 | 默认页面布局模板 | 可复用的模板片段 |
| 渲染页面 | 直接渲染 | 需要被调用才会被渲染 |
| 调用方式 | 自动由 Hugo 匹配使用 | 要手动通过 {``{ partial *.html }} 调用 |
| 典型文件 | single.html,list.html | header.html,footer.html |
| 内容类型 | 依赖 | 不依赖(通用) |
OK,下面再介绍下这里的内容类型依赖
在 Hugo 中,每一篇文章都属于某个内容类型,默认情况下,内容类型由这篇文章所在的 content/ 子目录名决定,比如
bash
content/
├── posts/ ← 内容类型是 "posts"
│ ├── post1.md
│ └── post2.md
└── about.md ← 内容类型是 "about"(因为是单个文件)
Hugo 在渲染 post1.md 时,就会首先尝试找 layouts/posts/single.html 模板,如果由就用它,没有的话就退而求其次,用默认模板 layouts/_default/single.html,所以 _default/ 中的模板是按内容类型匹配失败后的备用方案,其存在本身就是为各种内容类型服务的,参与内容类型的匹配逻辑
而 partials/ 里的文件不是用来直接渲染某类内容的,而是像零件一样,被其他模板(不管是 posts/single.html 还是 _default/list.html)主动调用,比如
html
<!-- layouts/_default/single.html -->
<!DOCTYPE html>
<html>
{{ partial "head.html" . }} ← 调用 partial
<body>
{{ partial "navbar.html" . }}
<main>{{ .Content }}</main>
{{ partial "footer.html" . }}
</body>
</html>
html
<!-- layouts/posts/list.html -->
{{ partial "head.html" . }} ← 同一个 partial,用在不同类型页面里
{{ range .Pages }}
<h2>{{ .Title }}</h2>
{{ end }}
head.html 这个 partial 既可以用在 posts 页面,也可以用在 about 页面,甚至首页,partial 不关心自己在渲染哪种内容类型,只负责输出一段通用的 HTML,所以,partials 是通用组件,和内容类型无关,不依赖内容类型
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog