Skip to main content

Crate churust_templates

Crate churust_templates 

Source
Expand description

Server-rendered HTML for the Churust web framework, on minijinja.

Install Templates, then take a Renderer in any handler:

use churust_core::{Churust, TestClient};
use churust_templates::{context, Renderer, Templates};

let app = Churust::server()
    .install(
        Templates::new()
            .add("hello.html", "<h1>Hello, {{ name }}!</h1>")
            .expect("template should parse"),
    )
    .routing(|r| {
        r.get("/", |view: Renderer| async move {
            view.render("hello.html", context! { name => "world" })
        });
    })
    .build();

let res = TestClient::new(app).get("/").send().await;
assert_eq!(res.text(), "<h1>Hello, world!</h1>");
assert_eq!(res.header("content-type"), Some("text/html; charset=utf-8"));

§Escaping

Every template is HTML-escaped, whatever it is called. Interpolated values cannot inject markup, so a {{ bio }} holding <script> reaches the browser as text.

minijinja’s own rule is to pick the escaping from the file extension and escape only .html, .htm and .xml. That is the right default for a library that can render into any format, and the wrong one here, because Renderer has a single sink: every method it offers labels its reply text/html; charset=utf-8. Leaving the filename in charge meant a template named page.txt, or partials/nav with no extension at all, was interpolated raw and then served as HTML anyway — a stored XSS waiting on whoever named the file. Naming a template .html is still the clearer thing to do, but it is no longer what keeps you safe.

If you need a template that is genuinely not HTML, install your own policy with Templates::configure before adding it: minijinja resolves the escaping once, when a template is parsed, so a callback set afterwards does not reach templates that are already loaded.

§Templates are parsed at startup

Templates::from_dir reads and parses every template when the server is built, so a syntax error is a startup failure with a filename in it rather than a 500 on the one route nobody visits until Friday. The cost is that a changed template needs a restart, which is the same trade the rest of the framework makes for routes and static roots.

Macros§

context
Build a template context inline.

Structs§

Renderer
Renders templates from the installed Templates environment.
Templates
The template environment, shared by every handler.

Enums§

TemplateSetupError
Why a template environment could not be built at startup.