aRustyDev / aRustyDev/mdbook-htmx

docs(adr): ADR-0001: Use Tera as Default Template Engine

Open
#9 0 comments 0 reactions 1 assignee Claimed by @aRustyDev View on GitHub
documentation
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.