Crate rocket_dyn_templates

source ·
Expand description

Dynamic templating engine support for Rocket.

This crate adds support for dynamic template rendering to Rocket. It automatically discovers templates, provides a Responder to render templates, and automatically reloads templates when compiled in debug mode. At present, it supports Handlebars and Tera.

§Usage

  1. Depend on rocket_dyn_templates. Enable the feature(s) corresponding to your templating engine(s) of choice:

    [dependencies.rocket_dyn_templates]
    version = "0.1.0"
    features = ["handlebars", "tera", "minijinja"]
    
  2. Write your templates inside of the configurable ${ROCKET_ROOT}/templates. The filename must end with an extension corresponding to an enabled engine. The second-to-last extension should correspond to the file’s type:

    EngineExtensionExample
    Tera.tera${ROCKET_ROOT}/templates/index.html.tera
    Handlebars.hbs${ROCKET_ROOT}/templates/index.html.hbs
    MiniJinja.j2${ROCKET_ROOT}/templates/index.html.j2
  3. Attach Template::fairing() and return a Template from your routes via Template::render(), supplying the name of the template file minus the last two extensions:

    use rocket_dyn_templates::{Template, context};
    
    #[get("/")]
    fn index() -> Template {
        Template::render("index", context! { field: "value" })
    }
    
    #[launch]
    fn rocket() -> _ {
        rocket::build().attach(Template::fairing())
    }

§Configuration

This crate reads one configuration parameter from the configured figment:

  • template_dir (default: templates/)

    A path to a directory to search for template files in. Relative paths are considered relative to the configuration file, or there is no file, the current working directory.

For example, to change the default and set template_dir to different values based on whether the application was compiled for debug or release from a Rocket.toml file (read by the default figment), you might write:

[debug]
template_dir = "static/templates"

[release]
template_dir = "/var/opt/www/templates"

Note: template_dir defaults to templates/. It does not need to be specified if the default suffices.

See the configuration chapter of the guide for more information on configuration.

§Template Naming and Content-Types

Templates are rendered by name via Template::render(), which returns a Template responder. The name of the template is the path to the template file, relative to template_dir, minus at most two extensions.

The Content-Type of the response is automatically determined by the non-engine extension using ContentType::from_extension(). If there is no such extension or it is unknown, text/plain is used.

The following table contains examples:

template pathTemplate::render() callcontent-type
{template_dir}/index.html.hbsrender("index")HTML
{template_dir}/index.terarender("index")text/plain
{template_dir}/index.hbsrender("index")text/plain
{template_dir}/dir/index.hbsrender("dir/index")text/plain
{template_dir}/dir/data.json.terarender("dir/data")JSON
{template_dir}/data.template.xml.hbsrender("data.template")XML
{template_dir}/subdir/index.template.html.hbsrender("subdir/index.template")HTML

The recommended naming scheme is to use two extensions: one for the file type, and one for the template extension. This means that template extensions should look like: .html.hbs, .html.tera, .xml.hbs, and so on.

§Rendering Context

In addition to a name, Template::render() requires a context to use during rendering. The context can be any Serialize type that serializes to an Object (a dictionary) value. The context! macro can be used to create inline Serialize-able context objects.

use rocket::serde::Serialize;
use rocket_dyn_templates::{Template, context};

#[get("/")]
fn index() -> Template {
    // Using the `context! { }` macro.
    Template::render("index", context! {
        site_name: "Rocket - Home Page",
        version: 127,
    })
}

#[get("/")]
fn index2() -> Template {
    #[derive(Serialize)]
    #[serde(crate = "rocket::serde")]
    struct IndexContext {
        site_name: &'static str,
        version: u8
    }

    // Using an existing `IndexContext`, which implements `Serialize`.
    Template::render("index", IndexContext {
        site_name: "Rocket - Home Page",
        version: 127,
    })
}

§Discovery, Automatic Reloads, and Engine Customization

As long as one of Template::fairing(), Template::custom(), or Template::try_custom() is attached, any file in the configured template_dir ending with a known engine extension (as described in the usage section) can be rendered. The latter two fairings allow customizations such as registering helpers and templates from strings.

Note: Templates that are registered directly via Template::custom(), use whatever name provided during that registration; no extensions are automatically removed.

In debug mode (without the --release flag passed to cargo), templates are automatically reloaded from disk when changes are made. In release builds, template reloading is disabled to improve performance and cannot be enabled.

§Metadata and Rendering to String

The Metadata request guard allows dynamically querying templating metadata, such as whether a template is known to exist (Metadata::contains_template()), and to render templates to String (Metadata::render()).

Modules§

  • The handlebars templating engine library, reexported.
  • The minijinja templating engine library, reexported.
  • The tera templating engine library, reexported.

Macros§

  • A macro to easily create a template rendering context.

Structs§

  • A structure exposing access to templating engines.
  • Request guard for dynamically querying template metadata.
  • Responder that renders a dynamic template.