【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(六)
分析了 .sidebar-related * 和 .sidebar-related 的区别,各个常用标签,比如 <p>,<span> 的含义,以及正文内容 .post-single 的布局,最后展示了侧边导航栏的效果,下面继续看下一个功能:breadcrumbs 面包屑
搭建私人博客
首先,面包屑是一种常见的网页导航模式,一般显式在页面顶部,用来展示用户当前所处的位置,比如类似这样
首页 > 文档 > 入门指南 > 安装 Hugo
其作用包括
- 帮助用户理解当前页面在网站结构中的位置
- 快速返回上一级或更高层级页面
- 提升用户体验和 SEO(搜索引擎喜欢清晰的站点结构)
由于 Hugo 是静态站点生成器,没有运行时路由,所以面包屑必须在构建时根据内容结构生成,常见的实现方式如下
- 利用
content/目录下的文件夹嵌套关系,比如下面的结构
text
content/
└── docs/
├── _index.md ← title: "文档"
└── getting-started/
├── _index.md ← title: "入门"
└── install.md ← 当前页面
通过遍历使用
-
.File.Path(当前内容文件在content/目录下的相对路径)
-
.Parent链(Hugo 自动为每个.Page页面设置的,一个指向.Page父页面的页面对象,通常是上一级目录中的_index.md所代表的section列表页)
等,逐级向上获取父页面,然后拼出路径
-
基于 Front Matter 自定义字段,在文章头部指定父页面,比如

这个
parent是一个普通自定义参数,Hugo 不会做任何处理,然后需要用户手动在模板中,用site.GetPage来读取这个字段,并自己递归查找祖先,这种方式灵活性很高 -
混合方式,结合目录结构 + Front Matter 覆盖,适合复杂站点
上述方式需要用户手动实现面包屑功能,适合一定基础,并且想实现高度自定义的用户,这里 PaperMod 已经提供了一个面包屑模板 breadcrumbs.html,下面来分析 PaperMod 提供的这个模板,路径在 PaperMod/layouts/partials/breadcrumbs.html

其内容如下
go
{{- if (.Param "ShowBreadCrumbs") -}}
<div class="breadcrumbs">
{{- $url := replace .Parent.Permalink (printf "%s" site.Home.Permalink) "" }}
{{- $lang_url := strings.TrimPrefix (printf "%s/" .Lang) $url -}}
<a href="{{ "" | absLangURL }}">{{ i18n "home" | default "Home" }}</a>
{{- $scratch := newScratch }}
{{- range $index, $element := split $lang_url "/" }}
{{- $scratch.Add "path" (printf "%s/" $element )}}
{{- $bc_pg := site.GetPage ($scratch.Get "path") -}}
{{- if (and ($bc_pg) (gt (len . ) 0))}}
{{- print " >> " | safeHTML -}}<a href="{{ $bc_pg.Permalink }}">{{ $bc_pg.Name }}</a>
{{- end }}
{{- end -}}
</div>
{{- end -}}
首先是第一行

表示是否显示面包屑,通过参数 ShowBreadCrumbs 检查当前页面是否启用了面包屑,看文章 Front Matter 或者全局配置 hugo.toml 有没有 ShowBreadCrumbs = true,如果为 true,才继续渲染面包屑
接着定义了 <div class="breadcrumbs"> 容器,在里面渲染面包屑
go
{{- $url := replace .Parent.Permalink (printf "%s" site.Home.Permalink) "" }}
这里表示获取父页面的相对路径(去掉域名)
.Parent.Permalink:表示当前页面的父页面完整 URL(PermaLink是 Permanent Link 的缩写,表示永久链接,或者静态链接)site.Home.Permalink:网站首页的 URLreplace ... "":表示把首页 URL 从父页面 URL 中删掉,得到相对路径,比如假设
.Parent.Permalink = https://example.com/docs/guide/
site.Home.Permalink = https://example.com/
那么最后就能得到 $url = docs/guide/,注意,这里用的是 .Parent,所以只取直接父级的路径,而不是当前页面自己的路径
接着下一行
go
{{- $lang_url := strings.TrimPrefix (printf "%s/" .Lang) $url -}}
strings.TrimPrefix 是 Go 语言标准库 strings 包中的函数,可以从字符串开头删除指定的前缀,在这里会去掉多语言前缀 ,比如 /zh/,如果站点是多语言的,比如中文版路径是 /zh/docs/guide,这行就会把开头的 zh/ 去掉,得到干净的 docs/guide,单语言站点中的 .Lang 通常为空,这步基本无影响
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog