【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Hugo】搭建私人博客:面包屑(一)
分析了 Hugo 中,面包屑的一些实现方式,以及 PaperMod 主题中,关于 breadcrumbs.html 的内容,下面继续分析
搭建私人博客
接着 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 -}}
接下来是这一行
go
<a href="{{ "" | absLangURL }}">{{ i18n "home" | default "Home" }}</a>
表示显示首页链接,<a href> 是 HTML 中,用于创建超链接的标签,其基本语法为
html
<a href="目标网址">链接显示的文字</a>
这里的 href 是 Hypertext Reference 的缩写,意思是指定超链接目标的 URL
absLangURLHugo 函数,会根据当前网站的语言设置,把路径转换为带语言前缀的绝对 URL,表示当前语言下的首页,比如zh/或/i18n "home"表示支持多语言翻译,比如中文显示首页,没配置就默认显示Home
所以整体的功能就是生成一个指向首页的链接,显示首页链接
这里再额外说下 href="{``{ "" | absLangURL }}",这里 "" 表示空字符串,代表根路径,所以作为选择器,有两种情况:
- 如果网站是多语言的,比如有中文
/zh/,或者英文/en/,在中文页面时,返回网址/zh/,在英文页面时,返回网址/en - 如果不是多语言网站,就返回根路径
网址/
所以 href 最终指向的是当前语言下的首页
OK,接下来是创建一个临时的变量容器
go
{{- $scratch := newScratch }}
在编程和计算机领域,scratch 的含义通常为临时存储区,草稿区,暂存区等 ,比如 scratch space/scratchpad 指的是一段临时,可读写的内存或存储区域,用于暂存中间结果,变量或计算过程中的数据,这个词的用法最早可以追溯到早期计算机和计算器,它们会有一小块 scratchpad memory 给程序员临时使用
Hugo 这里的 scratch 也是一样,可以动态存取值,用来在循环中逐步拼接路径,比如先 docs/,再 docs/guide
OK,接下来拆分路径遍历每一级
go
{{- range $index, $element := split $lang_url "/" }}
这里把 $lang_url 按 / 拆成数组,比如 docs/guide/ 拆成 ["docs", "guide", ""],然后对每个元素 $element 做循环,注意最后有个空字符串,因为路径结尾有 /,后面会滤掉
然后再根据拆分出来的元素,逐步拼出完整子路径
go
{{- $scratch.Add "path" (printf "%s/" $element )}}
每次循环的时候,把当前的目录名 + / 追加到 path 上,比如第一次循环是 docs/,第二次就是 docs/guide/,然后这些子路径 path 就是要传递给 site.GetPage 的参数
OK,尝试查找这一级对应的页面
go
{{- $bc_pg := site.GetPage ($scratch.Get "path") -}}
{{- if (and ($bc_pg) (gt (len . ) 0))}}
这里用拼好的路径(比如 docs/)去 Hugo 站点里找对应的页面
- 如果页面不存在,
$bc_pg则为nil - 如果页面存在且目录名非空(长度大于 0),就输出显示
最后输出分隔符和链接
html
{{- print " >> " | safeHTML -}}<a href="{{ $bc_pg.Permalink }}">{{ $bc_pg.Name }}</a>
这里的 >> 是面包屑常用的箭头符号,$bc_pg.Permalink 是这一级的链接,$bc_pg.Name 是这一级的名称(注意,是文件夹名称,不是文章的 title),如果想显示标题,这里可以把 $bc_pg.Name 改成 $bc_pg.Title

OK,分析完 breadcrumbs.html,下面在配置文件 hugo.toml 中加入配置项 ShowBreadCrumbs = true 如下

终端输入
bash
hugo server
启动博客站点,打开文章,可以看到面包屑导航路径如下

再额外提一点,每一层目录必须有 _index.md,否则 site.GetPage 找不到页面,面包屑会中断,举一个完整例子,结构如下
text
content/
├── _index.md → title: "首页"
└── docs/
├── _index.md → title: "文档中心"
└── guide/
├── _index.md → title: "入门指南"
└── install.md → ShowBreadCrumbs: true
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:_default&partials