From e992baf2d253eb70e9f10f1f0e687142af813690 Mon Sep 17 00:00:00 2001 From: andwati Date: Fri, 7 Aug 2026 10:46:09 +0300 Subject: [PATCH 1/2] Migrate templates to Zola 0.23 / Tera v2 bin/update-zola always installs the latest release, which as of v0.23.0 rewrote the template engine to Tera v2. That broke the whole site: removed filters (slice, concat, escape), test calls now require named args, shortcodes are gone in favor of Tera components, and content itself is now Tera-templated before markdown runs. - slice(end=n) -> native [:n] slicing; concat(with=x) -> spread [...arr, x] - escape -> escape_html; starting_with/containing -> named `pat` arg - get_taxonomy_url `name` -> `term` (old name is deprecated) - %+ date format no longer recognized; replaced with explicit RFC3339 pattern - shortcodes (note/tip/warning/danger/youtube) rewritten as components; content call sites updated to component invocation syntax - {% include %} no longer inherits for-loop-local variables (only ambient page/section context) - post-card.html converted to a component that takes page/index explicitly instead of relying on implicit `page`/`loop` - two content code blocks with literal Jinja-style {{ }} syntax (Netlify CMS config, a Flask template snippet) wrapped in {% raw %} so Tera doesn't try to render them, since content is now templated too - fixed a real content corruption bug along the way: the youtube shortcode's multi-line - +{% component youtube(id: string, page, config, title = "", autoplay = false) %} +
+{% endcomponent youtube %} diff --git a/templates/taxonomy_single.html b/templates/taxonomy_single.html index 2954d35..cb81d13 100644 --- a/templates/taxonomy_single.html +++ b/templates/taxonomy_single.html @@ -32,8 +32,8 @@ term.permalink }}{% endblock og_url %} {% block head %} "@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 page.date %},"datePublished": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %} + {% if page.updated %},"dateModified": "{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %} }{% if not loop.last %},{% endif %} {% endfor %} ] From bf4ef2aa29be689a0004e9c57bedcf9d1ec27a35 Mon Sep 17 00:00:00 2001 From: andwati Date: Fri, 7 Aug 2026 10:54:38 +0300 Subject: [PATCH 2/2] Add Dockerfile for self-hosted deployment, bump build.sh to Zola 0.23.1 Adds a multi-stage Dockerfile (Node for llms.txt generation, the official Zola image to build, static-web-server to serve) for deploying via Dokploy/Docker instead of Cloudflare Pages. This is an additional path, not a replacement - wrangler.toml and the Cloudflare build.sh remain in place as an option. Also bumps build.sh's pinned ZOLA_VERSION from 0.22.1 to 0.23.1: the prior commit migrated every template to Tera v2 syntax (components, spread operator, native slicing), which 0.22.1 can't parse - confirmed by a live Cloudflare build failure on this branch. Keeping build.sh and the Dockerfile on the same Zola version avoids maintaining two template dialects across the two deploy paths. Verified: `docker build` succeeds, the container serves the homepage, a post, the youtube embed, and a proper 404; `build.sh` also runs clean standalone (simulating the Cloudflare build) and produces a fully populated public/. --- .dockerignore | 8 ++++++++ Dockerfile | 21 +++++++++++++++++++++ build.sh | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c1dfd89 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +public +node_modules +.wrangler +.git +manimations/*.* +/zola +/zola-v*.tar.gz +/artifacts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a6d1f2f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# Multi-stage build: generate llms.txt with Node, build the site with Zola, +# then serve the static output with static-web-server. +# +# This is the Dokploy/self-hosted deployment path. It's independent of the +# Cloudflare Pages path (`npm run deploy` / wrangler.toml) - that stays in +# place as an option, this doesn't replace it. + +FROM node:22-slim AS llms +WORKDIR /project +COPY . . +RUN node scripts/generate-llms.mjs + +FROM ghcr.io/getzola/zola:v0.23.1 AS zola +WORKDIR /project +COPY . . +COPY --from=llms /project/static/llms.txt static/llms.txt +RUN ["/zola", "build"] + +FROM ghcr.io/static-web-server/static-web-server:2 +COPY --from=zola /project/public /public +EXPOSE 80 diff --git a/build.sh b/build.sh index 6a378d6..812e673 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -ZOLA_VERSION=0.22.1 +ZOLA_VERSION=0.23.1 echo "Downloading Zola ${ZOLA_VERSION}..." curl -sLJO "https://github.com/getzola/zola/releases/download/v${ZOLA_VERSION}/zola-v${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz"