aRustyDev / aRustyDev/mdbook-htmx
docs(adr): ADR-0001: Use Tera as Default Template Engine
- Dominant language
- Rust
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
# ADR-0001: Use Tera as Default Template Engine
## Status
Accepted
## Context
The mdbook-htmx backend needs a template engine to render HTMX-enhanced HTML pages. The skeleton files indicated support for multiple engines:
- Nunjucks (JavaScript)
- Handlebars (Rust/JS)
- Liquid (Ruby/Rust)
- Tera (Rust-native)
The backend is written in Rust to align with MDBook's ecosystem and ensure seamless integration via the `mdbook-renderer` crate.
## Decision Drivers
1. **Language Consistency** - Backend is Rust; prefer Rust-native engines
2. **Performance** - Compile-time template validation, no FFI overhead
3. **Feature Parity** - Must support: includes, extends, filters, conditionals
4. **Ecosystem Fit** - Used by other Rust documentation tools (Zola)
5. **Maintenance** - Active development, good documentation
## Options Considered
### Option A: Tera
**Pros:**
- Pure Rust, compiles with the backend
- Jinja2-compatible syntax (familiar to Python/Django developers)
- Template inheritance (`{% extends %}`, `{% block %}`)
- Custom filters and functions
- Used by Zola (similar documentation use case)
- Compile-time syntax validation
**Cons:**
- Less feature-rich than full Jinja2
- Smaller community than Handlebars
### Option B: Handlebars (handlebars-rs)
**Pros:**
- Rust implementation available
- Wide adoption across languages
- Logic-less philosophy (simpler templates)
**Cons:**
- No template inheritance (only partials)
- Verbose for complex layouts
- Logic-less can be limiting for HTMX patterns
### Option C: Liquid (liquid-rust)
**Pros:**
- Rust implementation available
- Simple syntax
- Used by Jekyll
**Cons:**
- Limited control flow
- No template inheritance
- Less expressive for component-based layouts
### Option D: Nunjucks (via wasm or subprocess)
**Pros:**
- Full Jinja2 compatibility
- Rich feature set
**Cons:**
- JavaScript runtime dependency
- Performance overhead (subprocess or WASM)
- Complicates build/distribution
## Decision
**Use Tera as the default template engine.**
Rationale:
1. Pure Rust eliminates external dependencies
2. Template inheritance is essential for `layout.html` → `page.html` pattern
3. Jinja2 syntax is widely known
4. Zola uses Tera for similar documentation purposes, proving suitability
5. Custom filters enable `{{ asset('path') }}` helper for hashed filenames
## Consequences
### Positive
- Single-binary distribution (no runtime dependencies)
- Fast template compilation and rendering
- Familiar syntax for most developers
- Strong typing integration with Rust structs
### Negative
- Users familiar with Handlebars/Liquid need to learn Tera
- Some advanced Jinja2 features not available
### Mitigation
- Document Tera syntax in SPEC
- Provide example templates
- Consider optional Handlebars support in future (via feature flag)
## References
- [Tera Documentation](https://keats.github.io/tera/)
- [Zola Template Engine Choice](https://www.getzola.org/documentation/templates/overview/)
- [handlebars-rs](https://github.com/sunng87/handlebars-rust)
Contributor guide
Assessment
This issue has not been assessed yet.