Files
kennethreitz 3b320a0078 DRY: share SEO structured-data via Jinja macros (Commit D of DRY cleanup)
- New templates/macros/seo.html with breadcrumb_jsonld(items): the hand-written
  schema.org BreadcrumbList JSON-LD block (repeated in book, chapter, verse,
  story, topic, and study-guide templates) is now one macro. Verified the parsed
  BreadcrumbList JSON is byte-identical before/after on all six page types.
- base.html twitter:image now defaults to {{ self.og_image() }}, so child
  templates only override og_image; removed the six redundant twitter_image
  overrides (each was byte-identical to its og_image). Eliminates og/twitter
  desync risk. Verified og:image == twitter:image on all six pages.

941 passed, 3 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 01:52:28 -04:00

25 lines
786 B
HTML

{# Shared SEO structured-data macros. #}
{# Emit a schema.org BreadcrumbList JSON-LD block.
`items` is an ordered list of (name, url) pairs. Positions are numbered
automatically. A pair whose url is none renders as a leaf crumb (no "item").
Names and urls are passed through tojson so escaping matches hand-written JSON. #}
{% macro breadcrumb_jsonld(items) -%}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{%- for name, url in items %}
{
"@type": "ListItem",
"position": {{ loop.index }},
"name": {{ name | tojson }}{% if url is not none %},
"item": {{ url | tojson }}{% endif %}
}{{ "," if not loop.last }}
{%- endfor %}
]
}
</script>
{%- endmacro %}