modo/template/mod.rs
1//! # modo::template
2//!
3//! MiniJinja-based template rendering for modo.
4//!
5//! This module provides an opinionated template layer built on top of
6//! [MiniJinja](https://docs.rs/minijinja). It covers engine construction,
7//! per-request context injection, HTMX-aware rendering, i18n with plural
8//! rules, and cache-busted static-asset URLs.
9//!
10//! ## Provides
11//!
12//! | Type / Trait | Description |
13//! |-----------------------------|-------------|
14//! | [`Engine`] / [`EngineBuilder`] | Compile and cache templates from disk, register custom functions and filters, and override the locale resolver chain. |
15//! | [`TemplateConfig`] | Configuration for template paths, static-asset prefix, locale defaults, and cookie/query-param names. |
16//! | [`TemplateContext`] | Per-request key-value map shared between middleware and handlers; handler values override middleware values on key conflicts. |
17//! | [`TemplateContextLayer`] | Tower middleware that injects per-request data (`current_url`, `is_htmx`, `request_id`, `locale`, `csrf_token`, `flash_messages`, and `tier_*` entries) into every request's extensions. Also re-exported as [`modo::middlewares::TemplateContext`](crate::middlewares::TemplateContext). |
18//! | [`Renderer`] | Axum extractor that gives handlers a ready-to-use render handle. |
19//! | [`HxRequest`] | Infallible axum extractor that detects the `HX-Request: true` header. Also re-exported from [`modo::extractors`](crate::extractors). |
20//! | [`context`] | Re-export of [`minijinja::context!`] for building template data in handlers. |
21//! | [`LocaleResolver`] | Trait for pluggable locale detection from a request. |
22//! | [`QueryParamResolver`] | Resolves the active locale from a URL query parameter. |
23//! | [`CookieResolver`] | Resolves the active locale from a cookie. |
24//! | [`AcceptLanguageResolver`] | Resolves the active locale from the `Accept-Language` header. |
25//! | [`SessionResolver`] | Resolves the active locale from the current session. |
26//!
27//! ## Quick start
28//!
29//! ```rust,no_run
30//! use modo::template::{Engine, TemplateConfig, TemplateContextLayer};
31//!
32//! // Build the engine once at startup.
33//! let engine = Engine::builder()
34//! .config(TemplateConfig::default())
35//! .build()
36//! .expect("failed to build engine");
37//!
38//! // Serve static files and inject per-request context.
39//! // `Engine` is cheaply cloneable (internal `Arc`).
40//! let router: axum::Router = axum::Router::new()
41//! .merge(engine.static_service())
42//! .layer(TemplateContextLayer::new(engine.clone()));
43//! ```
44
45mod config;
46mod context;
47mod engine;
48mod htmx;
49mod i18n;
50mod locale;
51mod middleware;
52mod renderer;
53mod static_files;
54
55pub use config::TemplateConfig;
56pub use context::TemplateContext;
57pub use engine::{Engine, EngineBuilder};
58pub use htmx::HxRequest;
59pub use locale::SessionResolver;
60pub use locale::{AcceptLanguageResolver, CookieResolver, LocaleResolver, QueryParamResolver};
61pub use middleware::TemplateContextLayer;
62pub use minijinja::context;
63pub use renderer::Renderer;