ADR-0006: Unified Zola Website
Status
Implemented
Summary
Consolidate the website from a Zola + mdbook hybrid to a unified Zola-only solution. The language specification currently built with mdbook will be migrated to Zola using custom templates that integrate seamlessly with the existing website styling.
Context
The current website architecture uses two separate static site generators:
- Zola - Main website (homepage, getting started, blog)
- mdbook - Language specification (
docs/spec/)
This creates several pain points:
- Two build systems: The
website/build.shscript must orchestrate both builds, copy mdbook output tostatic/spec/, and maintain synchronization - Styling inconsistency: mdbook has its own theme system separate from the Tailwind-based Zola site
- Navigation fragmentation: The spec is served as a static subdirectory with its own navigation, requiring a "back to site" JavaScript hack
- Two templating systems: mdbook uses Handlebars; Zola uses Tera
- Custom preprocessor: The
mdbook-specpreprocessor handles rule ID rendering, but could be a Zola shortcode or filter
Current mdbook Features Used
The specification uses these mdbook features:
- SUMMARY.md for sidebar navigation structure
- Search (built-in mdbook feature)
- Custom preprocessor (
mdbook-spec) forr[X.Y:Z]rule rendering - Theme customization (CSS for 3-column grid layout)
Test Framework Integration
The gruel-spec crate's traceability system parses spec markdown files to extract r[X.Y:Z] rule definitions. This system is path-agnostic - it finds all .md files under the spec directory. Moving to Zola won't break this as long as:
- The markdown files remain accessible
- The
r[X.Y:Z]syntax is preserved in the source files
Decision
Migrate the specification to Zola using a custom "book" template inspired by Zola's book theme and mdbook's layout, but integrated with the existing Gruel website styling.
Architecture
docs/spec/src/ # Spec content (unchanged location)
├── _index.md # Spec index (new, for Zola)
├── 01-introduction.md
├── 02-lexical-structure/
│ ├── _index.md
│ ├── 01-tokens.md
│ └── ...
└── ...
website/
├── content/
│ ├── _index.md # Homepage
│ ├── getting-started.md # Getting started
│ ├── blog/ # Blog
│ └── spec -> ../../docs/spec/src/ # Symlink to spec
├── templates/
│ ├── base.html # Existing
│ ├── spec/
│ │ ├── base.html # Spec layout with sidebar
│ │ ├── section.html # Chapter index pages
│ │ └── page.html # Individual spec pages
│ └── shortcodes/
│ └── rule.html # Rule ID shortcode
├── static/
│ └── css/
│ └── spec.css # Spec-specific styling
└── config.toml
Rule ID Handling
Replace the mdbook preprocessor with a Zola shortcode:
Before (mdbook preprocessor):
After (Zola shortcode):
The shortcode generates the same HTML structure:
[3.1:1]
Migration script: A one-time script will convert all r[X.Y:Z] patterns to shortcode syntax.
Traceability System Update
The gruel-spec traceability parser must be updated to recognize both:
- The new shortcode syntax:
@@ZOLA_SC_PLACEHOLDER@@ - The original pattern (for backwards compatibility during migration)
This is a simple regex change in crates/gruel-spec/src/traceability.rs.
Sidebar Navigation
Zola's section system with weight front matter provides ordered navigation:
The spec template will generate a sidebar from the section hierarchy, similar to mdbook's SUMMARY.md-driven navigation.
Search
Zola has built-in search index generation. Enable with:
= true
The spec template will include a search box styled to match the site.
Dark Mode
The spec pages will inherit the existing dark mode toggle from base.html, eliminating the need for mdbook's separate theme system.
Implementation Phases
Phase 1: Create spec templates
- Create
templates/spec/base.htmlwith sidebar layout - Create
templates/spec/section.htmlandpage.html - Create
templates/shortcodes/rule.html - Add spec CSS to
css/input.csswith 3-column grid layout
- Create
Phase 2: Migrate content
- Convert
r[X.Y:Z]to shortcodes via migration script - Symlink spec content from
website/content/spectodocs/spec/src/ - Add front matter to all spec pages
- Convert README.md to
_index.mdfor Zola sections
- Convert
Phase 3: Update test framework
- Update traceability parser to handle shortcode syntax
- Verify 100% coverage maintained
Phase 4: Clean up
- Remove mdbook build from
website/build.sh - Remove
docs/spec/tools/mdbook-spec/ - Remove
docs/spec/theme/ - Update CLAUDE.md documentation
- Delete
docs/spec/book.toml
- Remove mdbook build from
Consequences
Positive
- Single build system: One
zola buildcommand, no orchestration needed - Consistent styling: Spec uses same Tailwind classes as rest of site
- Unified navigation: Spec pages have site header/footer, native navigation
- Simpler maintenance: One templating language (Tera), one CSS system
- Faster builds: No mdbook preprocessing step
- Better dark mode: Inherits site-wide theme toggle
Negative
- Migration effort: One-time conversion of ~50 markdown files
- Shortcode verbosity:
@@ZOLA_SC_PLACEHOLDER@@is more verbose thanr[3.1:1#normative] - Learning curve: Contributors must learn Zola's shortcode syntax
Neutral
- Search: Zola's search is comparable to mdbook's
- Rule link references: The
[text]: rule.idsyntax won't work; authors must use explicit links
Open Questions
Should we keep
docs/spec/src/as the source of truth and have Zola reference it?- Pro: Keeps spec near compiler code
- Con: Complicates Zola content structure
- Decision: Keep in
docs/spec/src/- Zola will reference via symlink or config
What about the shortcode verbosity?
- Alternative: Create a Zola filter that processes raw markdown
- This would require writing a Rust Zola plugin
- Decision: Use shortcodes initially; revisit if verbosity is problematic
Future Work
- Consider a Zola plugin to process
r[X.Y:Z]natively (like the mdbook preprocessor) - Add PDF export of specification
- Add version selector for multiple spec versions
References
- Zola book theme - Inspiration for sidebar layout
- Rust Reference mdbook-spec - Original preprocessor inspiration
- Current build:
website/build.sh