Crate iron_tera

source ·
Expand description

Please contact me on github and file any issues if you find some, I’m also open to PRs or other suggestions.

Updated to Tera 0.11 / Serde 1.0 / Iron 0.5 ! Serde 1.0 to_value returns a Result, this means you need to handle the possiblity of a serialization failure. If you just want to unwrap() there is an implementation of From for TemplateMode so Template::new(path, value) works also. This is the implementation that’s on ‘stable’.

You can try the unstable crate feature which uses TryFrom/TryInto to make Template::new polymorphic over Context and Value.

update iron-tera-0.5.0: If you build this crate with feature = “unstable” on the nightly compiler, I’ve included a TryFrom impl to improve API ergonomics.

Examples

Full examples ON GITHUB for both stable and unstable.

  [dependencies]
  iron-tera = { version = "0.5.0" }  # optional:  features = [ "unstable" ]

Using iron-tera stable.

    extern crate tera;
    extern crate iron;
    extern crate router;
    #[macro_use] extern crate serde_json;
    #[macro_use] extern crate serde_derive;
    extern crate iron_tera;

fn main() {
    use iron::prelude::*;
    use iron::status;
    use router::Router;
    use tera::Context;

    use iron_tera::{Template, TeraEngine};

    let mut router = Router::new();
    router.get("/context", context_handler, "context");
    router.get("/json", json_handler, "json");

    let mut chain = Chain::new(router);
    let teng = TeraEngine::new("src/examples/templates/**/*");
    chain.link_after(teng);

    Iron::new(chain).http("localhost:5000").unwrap();


    fn context_handler(_: &mut Request) -> IronResult<Response> {
        let mut resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Bob");
        context.add("my_var", &"Thing"); // comment out to see alternate thing
        context.add("numbers", &vec![1, 2, 3]);
        context.add("bio", &"<script>alert('pwnd');</script>");

        // can use Template::new(path, TemplateMode::from_context(context)) or TemplateMode::from(context) also
        resp.set_mut(Template::new("users/profile.html", context))
            .set_mut(status::Ok);
        Ok(resp)
    }
    fn json_handler(_: &mut Request) -> IronResult<Response> {
        let mut resp = Response::new();

        let blob = json!({
            "username": "John Doe",
            "my_var": "Thing",
            "numbers": [
                "1",
                "+44 2345678",
                "3"
            ],
            "bio": "<script>alert('pwnd');</script>"
         });
        // you can use blob.try_into() and handle the `Result` explicitly (not shown here)
        // on the `unstable` feature of `iron-tera`
        resp.set_mut(Template::new("users/profile.html", blob))
            .set_mut(status::Ok);
        Ok(resp)
    }
}

Creating a template from a struct

// The following uses serde's Serialize
#[derive(Serialize)]
struct Product {
    name: String,
    value: i32,
}
// Rendering from a struct that implements Serialize
fn produce_handler(_: &mut Request) -> IronResult<Response> {
    let mut resp = Response::new();

    // Using serialized values
    let product = Product {
        name: "Foo".into(),
        value: 42,
    };
    // You can use TemplateMode::from()
    resp.set_mut(Template::new("product.html", product))
        .set_mut(status::Ok);
    Ok(resp)
}

Structs

Our template holds a name (path to template) and a mode (constructed with from_context or from_serial)
TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing

Enums

There are 2 main ways to pass data to generate a template.