fix zola.toml config table scoping bug and JSON-LD safety

[[extra.menu]] silently swallowed ~20 later extra.* keys (posts_page_title,
search_placeholder, show_rss_link, notfound_*, etc.) into the last menu
entry/tag_descriptions table, since TOML absorbs bare keys into the last
open table until a new header appears. show_rss_link was the only visibly
broken one (RSS link missing from homepage); the rest were masked by
matching template defaults.

Also replaced Tera's default() filter with explicit if/else where values
feed into JSON-LD, since default()'s fallback gets escaped in a way `safe`
can't undo. Added author/dateModified to BlogPosting list entries.
This commit is contained in:
2026-07-17 15:59:27 +03:00
parent 3b7cca3cc7
commit 3e1c643283
8 changed files with 59 additions and 41 deletions
+1 -1
View File
@@ -77,7 +77,7 @@
{
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author",
"name": {{ config.extra.author | default(value="andwati") | json_encode | safe }},
"name": {{ config.extra.author | json_encode | safe }},
"url": "{{ config.base_url | safe }}/about/",
"sameAs": [
{% if config.extra.github_url %}"{{ config.extra.github_url | safe }}"{% if config.extra.twitter_url or config.extra.youtube_url %},{% endif %}{% endif %}
+7 -2
View File
@@ -21,9 +21,14 @@ block og_url %}{{ config.base_url }}/{% endblock og_url %} {% block head %}
"@type": "BlogPosting",
"@id": "{{ page.permalink | safe }}#article",
"headline": {{ page.title | json_encode | safe }},
"image": "{{ config.base_url | safe }}/images/og-image.png",
"url": "{{ page.permalink | safe }}"
"image": "{{ config.base_url | safe }}{% if page.extra.image %}{{ page.extra.image | safe }}{% else %}/images/og-image.png{% endif %}",
"url": "{{ page.permalink | safe }}",
"author": {
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author"
}
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
}{% if not loop.last %},{% endif %}
{% endfor %}
]
+6 -6
View File
@@ -14,7 +14,7 @@
{% if page.ancestors is containing("posts/_index.md") %}
{% if page.date %}<meta property="article:published_time" content="{{ page.date | date(format="%+") }}">{% endif %}
{% if page.updated %}<meta property="article:modified_time" content="{{ page.updated | date(format="%+") }}">{% endif %}
<meta property="article:author" content="{{ config.extra.author | default(value="andwati") }}">
<meta property="article:author" content="{{ config.extra.author }}">
{% if page.taxonomies.tags %}
{% for tag in page.taxonomies.tags %}
<meta property="article:tag" content="{{ tag }}">
@@ -41,8 +41,8 @@
"@id": "{{ page.permalink | safe }}"
},
"headline": {{ page.title | json_encode | safe }},
"description": {{ page.description | default(value=config.description) | json_encode | safe }},
"image": "{{ config.base_url | safe }}{{ page.extra.image | default(value="/images/og-image.png") | safe }}",
"description": {% if page.description %}{{ page.description | json_encode | safe }}{% else %}{{ config.description | json_encode | safe }}{% endif %},
"image": "{{ config.base_url | safe }}{% if page.extra.image %}{{ page.extra.image | safe }}{% else %}/images/og-image.png{% endif %}",
"url": "{{ page.permalink | safe }}",
"inLanguage": "en-US",
{% if page.date %}"datePublished": "{{ page.date | date(format="%+") }}",{% endif %}
@@ -50,13 +50,13 @@
"author": {
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author",
"name": {{ config.extra.author | default(value="andwati") | json_encode | safe }},
"name": {{ config.extra.author | json_encode | safe }},
"url": "{{ config.base_url | safe }}/about/"
},
"publisher": {
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author",
"name": {{ config.extra.author | default(value="andwati") | json_encode | safe }},
"name": {{ config.extra.author | json_encode | safe }},
"url": "{{ config.base_url | safe }}/about/"
},
"isPartOf": {
@@ -91,7 +91,7 @@
"@type": "WebPage",
"@id": "{{ page.permalink | safe }}",
"name": {{ page.title | json_encode | safe }},
"description": {{ page.description | default(value=config.description) | json_encode | safe }},
"description": {% if page.description %}{{ page.description | json_encode | safe }}{% else %}{{ config.description | json_encode | safe }}{% endif %},
"url": "{{ page.permalink | safe }}",
"inLanguage": "en-US",
"isPartOf": {
+1 -1
View File
@@ -64,7 +64,7 @@
{
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author",
"name": {{ config.extra.author | default(value="andwati") | json_encode | safe }},
"name": {{ config.extra.author | json_encode | safe }},
"url": "{{ config.base_url | safe }}/about/",
"sameAs": [
{% if config.extra.github_url %}"{{ config.extra.github_url | safe }}"{% if config.extra.twitter_url or config.extra.youtube_url %},{% endif %}{% endif %}
+1 -1
View File
@@ -1,6 +1,6 @@
{% if config.extra.show_profile %}
<div class="masthead">
<p class="masthead-kicker">{{ config.extra.author | default(value="andwati") }}{% if config.extra.profile_subtitle %} — {{ config.extra.profile_subtitle }}{% endif %}</p>
<p class="masthead-kicker">{{ config.extra.author }}{% if config.extra.profile_subtitle %} — {{ config.extra.profile_subtitle }}{% endif %}</p>
<h1 class="hero-title masthead-title">{{ config.title }}</h1>
<p class="hero-subtitle">{{ config.description }}</p>
+7 -2
View File
@@ -30,9 +30,14 @@ og_description %}{{ config.extra.posts_page_subtitle | default(value="Exploring
"@type": "BlogPosting",
"@id": "{{ page.permalink | safe }}#article",
"headline": {{ page.title | json_encode | safe }},
"image": "{{ config.base_url | safe }}{{ page.extra.image | default(value="/images/og-image.png") | safe }}",
"url": "{{ page.permalink | safe }}"
"image": "{{ config.base_url | safe }}{% if page.extra.image %}{{ page.extra.image | safe }}{% else %}/images/og-image.png{% endif %}",
"url": "{{ page.permalink | safe }}",
"author": {
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author"
}
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
}{% if not loop.last %},{% endif %}
{% endfor %}
]
+9 -4
View File
@@ -5,7 +5,7 @@ description %} {% block canonical %}{{ term.permalink }}{% endblock canonical %}
config.extra.tag_descriptions[term.slug] | default(value='Posts tagged "' ~ term.name ~ '" on ' ~ config.title) }}{% endblock og_description %} {% block og_url %}{{
term.permalink }}{% endblock og_url %} {% block head %}
{% set tag_ld_name = 'Posts tagged "' ~ term.name ~ '" | ' ~ config.title %}
{% set tag_ld_description = config.extra.tag_descriptions[term.slug] | default(value='Posts tagged "' ~ term.name ~ '" on ' ~ config.title) %}
{% set tag_ld_fallback_description = 'Posts tagged "' ~ term.name ~ '" on ' ~ config.title %}
<!-- SEO: Tag CollectionPage JSON-LD -->
<script type="application/ld+json">
{
@@ -13,7 +13,7 @@ term.permalink }}{% endblock og_url %} {% block head %}
"@type": "CollectionPage",
"@id": "{{ term.permalink | safe }}#collection",
"name": {{ tag_ld_name | json_encode | safe }},
"description": {{ tag_ld_description | json_encode | safe }},
"description": {% if config.extra.tag_descriptions[term.slug] %}{{ config.extra.tag_descriptions[term.slug] | json_encode | safe }}{% else %}{{ tag_ld_fallback_description | json_encode | safe }}{% endif %},
"url": "{{ term.permalink | safe }}",
"inLanguage": "en-US",
"isPartOf": {
@@ -26,9 +26,14 @@ term.permalink }}{% endblock og_url %} {% block head %}
"@type": "BlogPosting",
"@id": "{{ page.permalink | safe }}#article",
"headline": {{ page.title | json_encode | safe }},
"image": "{{ config.base_url | safe }}{{ page.extra.image | default(value="/images/og-image.png") | safe }}",
"url": "{{ page.permalink | safe }}"
"image": "{{ config.base_url | safe }}{% if page.extra.image %}{{ page.extra.image | safe }}{% else %}/images/og-image.png{% endif %}",
"url": "{{ page.permalink | safe }}",
"author": {
"@type": "Person",
"@id": "{{ config.base_url | safe }}/#author"
}
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
}{% if not loop.last %},{% endif %}
{% endfor %}
]
+27 -24
View File
@@ -45,24 +45,6 @@ utterances_repo = "andwati/andwati.com"
utterances_theme = "gruvbox-dark"
utterances_theme_light = "github-light"
# Navigation Menu
[[extra.menu]]
name = "About"
url = "/about/"
match = "/about"
[[extra.menu]]
name = "Posts"
url = "/posts"
match = "/posts"
[[extra.menu]]
name = "Tags"
url = "/tags/"
match = "/tags"
[[extra.menu]]
name = "Archive"
url = "@/archive/_index.md"
match = "/archive"
# Features
enable_search = true
enable_theme_toggle = true
@@ -95,15 +77,36 @@ post_nav_prev_label = "Previous"
post_nav_next_label = "Next"
share_label = "Share:"
# 404 page
notfound_status = "Status: Not Found"
notfound_title = "Document Not Found"
notfound_body = "This page couldn't be located in the archive. It may have been moved, renamed, or never filed."
# Navigation Menu — array-of-tables must come after all plain [extra] keys,
# since once opened, subsequent bare `key = value` lines belong to the last
# array element, not back to [extra].
[[extra.menu]]
name = "About"
url = "/about/"
match = "/about"
[[extra.menu]]
name = "Posts"
url = "/posts"
match = "/posts"
[[extra.menu]]
name = "Tags"
url = "/tags/"
match = "/tags"
[[extra.menu]]
name = "Archive"
url = "@/archive/_index.md"
match = "/archive"
# Per-tag descriptions (used on /tags/<slug>/ pages instead of the generic
# "Posts tagged X" line — keyed by tag slug, not display name)
# "Posts tagged X" line — keyed by tag slug, not display name). Must be the
# last table in the file for the same reason as [[extra.menu]] above.
[extra.tag_descriptions]
linux = "Practical notes on running Arch-based Linux distributions, from WiFi hotspot quirks to database setup."
subresource-integrity = "How Subresource Integrity (SRI) hashes protect a site from tampered third-party scripts and stylesheets."
garuda = "Setup notes for Garuda Linux, an Arch-based distribution built for performance."
cors = "Notes on Cross-Origin Resource Sharing (CORS) and how browsers enforce cross-origin security policies."
# 404 page
notfound_status = "Status: Not Found"
notfound_title = "Document Not Found"
notfound_body = "This page couldn't be located in the archive. It may have been moved, renamed, or never filed."