如何为 Hugo 创建工作面包屑?

How to create working Breadcrumbs for Hugo?

令人难以置信的是,要找到关于 Hugo 稍微更高级的技术的可靠信息是多么困难。

经过一段时间的搜索,我发现 this article 有一个非常好的方法来为 Hugo 实现面包屑导航。

我对其进行了一些修改,以便不在最后一条线索中添加不必要的 link 并利用国际化将 URL 段翻译成更易于阅读的内容。我还做了一个小的解决方法来删除一些与翻译条目不匹配的不需要的路径:

{{- $url := replace .Permalink ( printf "%s" ( "/" | absLangURL ) ) "" -}}
{{- $url := replace .Permalink ( printf "%s" ( "/" | absLangURL ) ) "" -}}
{{- $.Scratch.Add "path" ( "/" | absLangURL ) -}}

{{- $.Scratch.Add "breadcrumb" (slice (dict "url" ( "/" | absLangURL ) "name" "home" "position" 1 )) -}}
{{- range $index, $element := split $url "/" -}}
  {{- $.Scratch.Add "path" $element -}}
  {{- $.Scratch.Add "path" "/" -}}
  {{- if ne $element "" -}}
    {{- $.Scratch.Add "breadcrumb" (slice (dict "url" ($.Scratch.Get "path") "name" . "position" (add $index 2))) -}}
  {{- end -}}
{{- end -}}

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{{ range $.Scratch.Get "breadcrumb" }}{{ if ne .position 1 }},{{ end }}{
        "@type": "ListItem",
        "position": {{ .position }},
        "item": {
          "@id": "{{ .url }}",
          "name": "{{ .name }}"
        }
    }{{ end }}]
}
</script>

<nav class="breadcrumb">
  {{- $length := len ($.Scratch.Get "breadcrumb") -}}

  {{- range $index, $.Scratch.Get "breadcrumb" -}}

    <!--
    Assigning a constant as default value for i18n function
    if it doesn't match any entry
    Then check if current Breadcrumb item matches this constant,
    which means that part shouldn't be one of Breadcrumb's trail
    -->
    {{- $i18n := i18n ( print "breadcrumbs-" .name ) | default "__INTERNAL__" -}}

    {{- if not ( eq ($i18n) "__INTERNAL__" ) -}}

      {{ if eq ( (int .position) ) $length }}
  <span class="breadcrumb-item active">{{ $i18n }}</span>
      {{- else -}}
  <a class="breadcrumb-item" href="{{ .url }}" >{{ $i18n }}</a>
      {{- end -}}

    {{- end -}}

  {{ end }}
</nav>

它工作得非常好,除了到目前为止我在浏览分页 links 时注意到的一切都开始复制 N 次,只要分页页增加(即第 2 页的两倍,三次第 3 页等等)。

我搜索了更多,发现 a similar implementation 其中没有重复...但是 link 都搞砸了,每个路径的 URL 是一个所有路径 o.O

的所有 link 的串联

我尽量避免在 Hugo 的 "forum" 上提问,因为那里给出的答案大多数时候难以理解、不完整或带有 "pseudo-pseudo-codes"。

有谁知道如何进行这项工作并可以帮助我吗?

只需两步,灵感来自:http://hugocodex.org/add-ons/breadcrumbs/

  1. 在您的 Hugo 项目的 layouts/partials 文件夹中创建一个名为 breadcrumbs.html 的文件
<span>
    <a href="/">Home</a>
    {{ range (split .URL "/") }}
        {{ if gt (len . ) 0 }}
            / <a href="/{{ . }}">{{ humanize (replace . "posts" "blog") }}</a>
        {{ end }}
    {{ end }}
</span>
  1. 在您需要的地方添加 breadcrumbs.html

{{ partial "breadcrumbs.html" . }}

来自Hugo documentation and building on

  1. 在您的 Hugo 项目或主题的文件夹 layouts/partials 中创建一个名为 breadcrumbs.html 的文件
<ol  class="nav navbar-nav">
    {{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
</ol>
{{ define "breadcrumbnav" }}
{{ if .p1.Parent }}
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 )  }}
{{ else if not .p1.IsHome }}
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 )  }}
{{ end }}
<li{{ if eq .p1 .p2 }} class="active"{{ end }}>
    <a href="{{ .p1.Permalink }}">{{ .p1.Title }}</a>
</li>
{{ end }}
  1. 在您需要的地方添加 breadcrumbs.html
{{ partial "breadcrumbs.html" . }}

这会生成所有有效的链接(包括部分)。

我被迫停止编码,但由于这个问题今天突然弹出通知,让我展示一下我为解决后面的问题中提出的问题所做的工作,尽管我无法真正解释为什么会发生这种情况 - 或者 - 如果现在在较新版本的 Hugo 中仍然发生这种情况(我停止使用 v0.28)

好吧,经过多次测试,我只是用“点”的范围初始化了一个模板变量,该变量在调用局部模板时传递给局部模板,而不是从局部模板的上下文中调用 Scratch美元符号(或在 Hugo/Go 中调用的任何名称)我使用了这个我初始化的变量:

list.html

{{ partial "breadcrumbs.html" . }}

partials/breadcrumbs.html

{{ $dot := . }}
{{ $dot.Scratch.Set "path" "" }}
{{ $dot.Scratch.Set "breadcrumb" slice }}

<!-- Rest of the code in the original question -->

从他们开始,而不是,例如:

{{ $.Scratch.Add "path" $element }}

我用过:

{{ $dot.Scratch.Add "path" $element }}

并且所有分页元素都没有重复。

我写了关于添加 breadcrumb partial for hugo with strucutred data 的博客 post。

不仅要向搜索引擎爬虫显示机器可读的面包屑,还要向用户显示同样的信息。我的博客 post 详细介绍了该主题。

这里回答这个问题是我只针对爬虫的部分。

{{ $url := replace .Permalink (printf "%s" .Site.BaseURL) ""}}
{{ .Scratch.Add "path" .Site.BaseURL }}
{{ .Scratch.Add "breadcrumb" (slice (dict "url" .Site.BaseURL "name" "Home"))}}
{{ .Scratch.Add "permalink" .Permalink }}
{{ .Scratch.Add "title" .Title }}
{{ $pScratch := .Scratch }}

{{ range $index, $element := split $url "/" }}
  {{ $pScratch.Add "path" $element }}
  {{ $pScratch.Add "path" "/" }}
  {{ if ne $element "" }}
    {{ if eq ($pScratch.Get "path") ($pScratch.Get "permalink") }}
        {{ $pScratch.Add "breadcrumb" (slice (dict "url" ($pScratch.Get "path") "name" ($pScratch.Get "title")))}}
    {{ else }}
        {{ $pScratch.Add "breadcrumb" (slice (dict "url" ($pScratch.Get "path") "name" (humanize .)))}}
    {{ end }}
  {{ end }}
{{ end }}

<script type="application/ld+json">
  [{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
      {{ range $index, $breadcrumb := .Scratch.Get "breadcrumb" }}
        {{ if ne $index 0 }},{{ end }}
          {
            "@type": "ListItem",
            "position": {{ add $index 1 }},
            "name": "{{ $breadcrumb.name }}",
            {{ if ne $breadcrumb.url ($pScratch.Get "permalink") }}
              "item": {{ printf "%s" $breadcrumb.url }},
            {{ end }}
          }
      {{ end }}
      ]
    }
    {{ range $index, $category :=  .Params.categories }}
      ,
      {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
          {
            "@type": "ListItem",
            "position": 1,
            "name": "Home",
            "item": "{{$.Site.BaseURL}}",
          },
          {
            "@type": "ListItem",
            "position": 2,
            "name": "Categories",
            "item": "{{$.Site.BaseURL}}categories/",
          },
          {
            "@type": "ListItem",
            "position": 3,
            "name": "{{ humanize . }}",
            "item": "{{$.Site.BaseURL}}categories/{{.}}",
          },
          {
            "@type": "ListItem",
            "position": 4,
            "name": "{{ $pScratch.Get "title" }}",
          },
        ]
      }
    {{ end }}
    ]
</script>

好吧,这可以很容易地通过 replacing.URL 到 .RelPermalink 从 更早的时间线解决。

第 1 步:

 <div class="container" id="breadcrumbs">
     <a href="/">Home</a>
     {{ range (split .RelPermalink "/") }}
         {{ if gt (len . ) 0 }}
            <i class="fas fa-chevron-right"></i><a href="/{{ . }}">{{ humanize (replace . "posts" "blog") }}</a>
         {{ end }}
     {{ end }}
 </div>

第 2 步: 在需要的地方包含 breadcrumbs.html:

{{ partial "breadcrumbs.html" . }}

有关详细信息,请转到 Breadcrumbs | HugoCodex