mono/plain; a11y=true

An accessible, monospace plain Zola Theme

Development

Created:

Post Permalink

Author:
Simon Gattner

Introduction

This post shows a practical workflow for developing Zola themes locally:

  • check out the repository
  • install Zola, rumdl, Node.js and pnpm
  • run development mode
  • understand Tera templates and editor support
  • debug templates and components
  • run local accessibility checks
  • run test and check
  • commit and push changes
  • release a new version

Prerequisites

For this repository, the JavaScript toolchain expects:

  • Cargo >=1.95.0
  • Zola >=0.22.1
  • rumdl >=0.2.48
  • Node.js >=22.0.0 <25.0.0
  • pnpm >=10.0.0 <12.0.0

Repository scripts are defined in the workspace root package.json, while the theme package also has its own local package.json under themes/zola-monoplain/.

1. Check Out the Repository

git clone https://github.com/exiguus/zola-monoplain.git
cd zola-monoplain

2. Install Cargo, Zola, Node.js and Pnpm

Preferred: install Zola with Cargo and pin the same version used by this repository's GitHub Actions.

At the moment, workflows use zola@0.22.1, so this is the recommended development version.

Preferred (Cargo)

cargo install --locked --git https://github.com/getzola/zola zola@0.22.1
zola --version

You can verify the CI pin in .github/workflows/prod.yml and .github/workflows/preview.yml.

Package Manager Alternatives

If you do not use Rust/Cargo locally, install Zola with your package manager only if it provides a recent enough version (>=0.22.1).

Linux (Debian/Ubuntu)

sudo apt update
sudo apt install zola
zola --version

macOS (Homebrew)

brew install zola
zola --version

Alternative

Use the official installation guide if your platform/package manager differs:

https://www.getzola.org/documentation/getting-started/installation/

Rumdl

Rumdl is a Rust-based tool to lint and format Markdown files. It is used in this repository to check and format Markdown content.

cargo install rumdl

Node, Pnpm

If Node.js is not installed yet, install Node.js 22 or newer and then enable pnpm via Corepack:

node --version
corepack enable
corepack prepare pnpm@11.9.0 --activate
pnpm --version

Install dependencies from the repository root:

pnpm install

3. Run Development Mode

You can run development in two ways.

Option A: Workspace Root (Turbo)

From the repository root:

pnpm dev

This runs the workspace dev pipeline.

Option B: Theme Package Directly

From the theme directory:

cd themes/zola-monoplain
pnpm dev

This runs zola serve (after checking that Zola is installed).

4. Understand Tera Templates and Editor Support

Zola templates use the Tera template engine.

Tera documentation:

https://keats.github.io/tera/docs/

If your IDE/editor does not provide a dedicated Tera extension, the Twig syntax extension works well for highlighting and basic template readability.

VS Code extension:

https://marketplace.visualstudio.com/items?itemName=mblode.twig-language-2

5. Understand the Theme Structure

The theme keeps content, templates, styles, and client-side scripts in separate folders so each part stays easy to find:

  • templates/ contains the page layout layer.
    • base.html provides the shared shell.
    • index.html, page.html, post.html, posts.html, and taxonomy_*.html define the main page types.
    • components/ holds reusable partials such as the header, footer, and latest content blocks.
    • macros/ and shortcodes/ contain shared template helpers and shortcode implementations.
  • sass/ contains the SCSS source files.
    • base.scss, layout.scss, typography.scss, markdown.scss, and related partials are split by concern.
    • _variables.scss and _extends.scss hold shared values and reusable style rules.
    • a11y.scss, image.scss, scheme.scss, spotify.scss, and youtube.scss group feature-specific styles.
  • static/js/ contains JavaScript shipped directly to the browser.
    • main.js is the general site script.
    • search.js powers the search page behavior.

Keeping these areas separated makes template changes, styling changes, and script changes easier to debug independently.

6. Debug Templates and Components

Enable Debug Mode in Config

In config.toml set:

[extra]
debug = true

When debugging a component, render the current page context in a template (for example in templates/post.html):

{% if config.extra.debug %}

<details>
  <summary>Debug: page</summary>
  <pre>{{/* page | default(value="{}") | json_encode | safe */}}</pre>
</details>
{% endif %}

The escaped braces are for Markdown examples. In your actual template file, use normal braces:

{{/* page | default(value="{}") | json_encode | safe */}}

This is useful to inspect available keys while developing components.

Scope Component Debugging

For reusable components/macros, print only the value you need first, then expand:

{{/* page.title | default(value="(no title)") */}}

for example, to check if the page.title key is available in a component.

{{/* page.extra | default(value="{}") | json_encode | safe */}}

or page.extra to check if the page.extra key is available in a component.

{{/* __tera_context */}}

or __tera_context to inspect the full template context.

Keeping debug output focused makes it easier to identify missing keys and wrong assumptions.

7. Run Local Accessibility Checks

To test accessibility against a local running dev server:

  1. Start the local dev server (default: http://127.0.0.1:1111):
pnpm dev
  1. In a second terminal from the repository root, run:
pnpm test:pa11y

This command runs pa11y checks against the local server and writes HTML reports to pa11y-report/.

8. Run Test and Check

From the repository root:

pnpm test
pnpm check

If you need to run the full build pipeline locally:

pnpm build

Useful script references:

  • pnpm dev runs the workspace dev pipeline.
  • pnpm test runs the workspace test pipeline.
  • pnpm check runs fta validation and the workspace check pipeline.
  • pnpm format reformats files with Dprint.
  • pnpm release:patch, pnpm release:minor, and pnpm release:major create releases with conventional versioning.
  • In themes/zola-monoplain/, pnpm dev runs zola serve after checking that Zola is installed.
  • In themes/zola-monoplain/, pnpm build runs zola build after checking that Zola is installed.

9. Write Documentation

Features and usage are documented in the repository's README.md and via post content in content/posts/ like this one. If you add a new feature, update the documentation accordingly.

10. Commit and Push Changes

From the repository root:

git add .
git commit -m "feat(posts): short summary of your change"
git push

Use a conventional commit message (feat:, fix:, docs:, and so on) so release tooling can derive changelog entries.

For pull requests, create a new branch and push to that branch instead of main.

Preview deployments are automatically built for pull requests and can be accessed at:

https://exiguus.github.io/zola-monoplain/pr-preview/pr-<PR_NUMBER>

If a post is marked as a draft, it will be included in the preview deployment, but not in the production deployment.

11. Release a New Version

Choose the release type and run one of:

pnpm release:patch
pnpm release:minor
pnpm release:major

Then push commit and tags:

git push --follow-tags origin main

If we have breaking changes, like removing, adding or changing a variable in the config.toml file, we must release a new major version. The change is considered breaking if it requires users to change their configuration or templates to continue using the theme.

Resources

Feedback

Have thoughts or experiences you'd like to share? I'd love to hear from you! Whether you agree, disagree, or have a different perspective, your feedback is always welcome. Drop me an email and let's start a conversation.

<​​​​development.monoplain​​​@0x38​.​​de​​​>

Tags