Add schema.org BreadcrumbList to JSON+LD (#87)

* Add schema.org BreadcrumbList to JSON+LD

This implementation  depends on .Page.Ancestors, which requires Hugo
version v0.109.0.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>

* Fix extraneous comma in schema

For blog posts we ended up with an extraneous comma due to it being
outside the condition for the breadcrumb
JSON+LD.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>

* Pretty print breadcrumb JSON+LD for schema

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>

* Make breadcrumbs opt-in on non-blogSections

Sections except blogSections (which is a configurable set which is
defaulted to sections 'blog' and 'post'), may be part of
`breadcrumbSections`. For the breadcrumb Sections, the section and any
pages under it will have the `breadcrumb` attribute (of type
`BreadcrumbList`) added to the JSON+LD for their schema.org structured
data.

Update documentation of `params` for example `config.yaml` in README.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>

---------

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
This commit is contained in:
Daniel F. Dickinson 2023-04-23 14:17:52 -04:00 • committed by GitHub
commit eb27a1e023
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 1 deletions

View file

@ -239,6 +239,13 @@ languageCode: "en-GB" # Set your language code (only needed for none multi
params:
alpine: # Add AlpineJS, default false.
blogSections: # Sections whose <schema.org> `JSON+LD` in the page `<head>`
- blog # will be `@type: BlogPosting`.
- post # Defaults to a list including only 'post' and 'blog'.
breadcrumbSections: # Sections in which pages will have a `BreadcrumbListing`
- section2 # in the <schema.org> `JSON+LD` in the page's `<head>`.
- section3 # This theme requires Hugo `v0.109.0` or higher to
# generate the `BreadcrumbListing`.
cookieConsent: true # Show cookie consent form, default false.
contact: "info@example.org"
copyright: "This site is licensed under a

View file

@ -0,0 +1,29 @@
{{- $breadcrumbScratch := newScratch -}}
{{- $crumbScratch := newScratch -}}
{{- $crumbScratch.Set "itemListElement" (slice) -}}
{{- $breadPos := 0 -}}
{{- range .Ancestors.Reverse -}}
{{- $breadPos = (add $breadPos 1) -}}
{{- $crumbScratch.Add "itemListElement" (dict
"@type" "ListItem"
"position" $breadPos
"item" (dict
"@id" .Permalink
"name" .LinkTitle
)
) -}}
{{- end -}}
{{- $breadPos = (add $breadPos 1) -}}
{{- $crumbScratch.Add "itemListElement" (dict
"@type" "ListItem"
"position" $breadPos
"item" (dict
"@id" .Permalink
"name" .LinkTitle
)
) -}}
{{- $breadcrumbScratch.SetInMap "breadcrumb" "@context" "https://schema.org" -}}
{{- $breadcrumbScratch.SetInMap "breadcrumb" "@type" "BreadcrumbList" -}}
{{- $breadcrumbScratch.SetInMap "breadcrumb" "itemListElement" ($crumbScratch.Get "itemListElement") -}}
{{- $jsonifiedBreadcrumb := $breadcrumbScratch.Get "breadcrumb" | jsonify (dict "indent" " " "prefix" " ") -}}
{{- return $jsonifiedBreadcrumb -}}

View file

@ -1,8 +1,17 @@
<script type="application/ld+json">
{{- $blogSections := site.Params.blogSections | default (slice "blog" "post") }}
{{- $breadcrumbSections := site.Params.breadcrumbSections | default (slice) }}
{
"@context": "https://schema.org",
{{ if .IsPage -}}
"@type": {{ if or (eq .Section "blog") (eq .Section "post") }}"BlogPosting"{{ else }}"WebPage"{{ end }},
"@type": {{ if in $blogSections .Section -}}
"BlogPosting",
{{- else -}}
"WebPage",
{{- if in $breadcrumbSections .Section }}
"breadcrumb": {{ safeJS (partial "meta_breadcrumb_json_ld.html" .) }},
{{- end -}}
{{- end }}
"headline": {{ .Title }},
"datePublished": {{ .Date.Format "2006-01-02T15:04:05Z07:00" }},
"dateModified": {{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }},
@ -15,6 +24,9 @@
{{ end -}}
{{ else -}}
"@type": "WebPage",
{{- if in $breadcrumbSections .Section }}
"breadcrumb": {{ safeJS (partial "meta_breadcrumb_json_ld.html" .) }},
{{- end }}
"url" : {{ .Permalink }},
"name": {{ .Title }},
{{ with $.Param "description" -}}