From fb4b63040595077f83039cf00c73275c8283ab2d Mon Sep 17 00:00:00 2001 From: Vadim Anufriev Date: Wed, 26 Jun 2024 10:27:44 +0400 Subject: [PATCH] Add MiniJinja for templating example (#2799) Update guide to mention MiniJinja. Adds MiniJinja to the templating example. --- contrib/dyn_templates/README.md | 6 +- docs/guide/06-responses.md | 4 +- examples/templating/Cargo.toml | 2 +- examples/templating/src/main.rs | 19 +++++- examples/templating/src/minijinja.rs | 61 +++++++++++++++++++ examples/templating/src/tests.rs | 13 +++- .../templates/minijinja/error/404.html.j2 | 11 ++++ .../templates/minijinja/footer.html.j2 | 3 + .../templates/minijinja/index.html.j2 | 17 ++++++ .../templates/minijinja/layout.html.j2 | 11 ++++ .../templates/minijinja/nav.html.j2 | 1 + 11 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 examples/templating/src/minijinja.rs create mode 100644 examples/templating/templates/minijinja/error/404.html.j2 create mode 100644 examples/templating/templates/minijinja/footer.html.j2 create mode 100644 examples/templating/templates/minijinja/index.html.j2 create mode 100644 examples/templating/templates/minijinja/layout.html.j2 create mode 100644 examples/templating/templates/minijinja/nav.html.j2 diff --git a/contrib/dyn_templates/README.md b/contrib/dyn_templates/README.md index 317ce0e69e..29143724a9 100644 --- a/contrib/dyn_templates/README.md +++ b/contrib/dyn_templates/README.md @@ -9,11 +9,11 @@ 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]. +and automatically reloads templates when compiled in debug mode. It supports [Handlebars], [Tera] and [MiniJinja]. [Tera]: https://docs.rs/crate/tera/1 [Handlebars]: https://docs.rs/crate/handlebars/5 +[MiniJinja]: https://docs.rs/crate/minijinja/2.0.1 # Usage @@ -23,7 +23,7 @@ supports [Handlebars] and [Tera]. ```toml [dependencies.rocket_dyn_templates] version = "0.1.0" - features = ["handlebars", "tera"] + features = ["handlebars", "tera", "minijinja"] ``` 1. Write your template files in Handlebars (`.hbs`) and/or Tera (`.tera`) in diff --git a/docs/guide/06-responses.md b/docs/guide/06-responses.md index 9343b5964e..31a10d323c 100644 --- a/docs/guide/06-responses.md +++ b/docs/guide/06-responses.md @@ -354,7 +354,7 @@ are: * [`Flash`] - Sets a "flash" cookie that is removed when accessed. * [`Json`] - Automatically serializes values into JSON. * [`MsgPack`] - Automatically serializes values into MessagePack. - * [`Template`] - Renders a dynamic template using handlebars or Tera. + * [`Template`] - Renders a dynamic template using Handlebars, Tera or MiniJinja. [`status`]: @api/master/rocket/response/status/ [`content`]: @api/master/rocket/response/content/ @@ -589,7 +589,7 @@ reloading is disabled. The [`Template`] API documentation contains more information about templates, including how to customize a template engine to add custom helpers and filters. -The [templating example](@git/master/examples/templating) uses both Tera and Handlebars +The [templating example](@git/master/examples/templating) uses Tera, Handlebars and MiniJinja templating to implement the same application. [configurable]: ../configuration/ diff --git a/examples/templating/Cargo.toml b/examples/templating/Cargo.toml index 1fcee3c365..e2379c2a45 100644 --- a/examples/templating/Cargo.toml +++ b/examples/templating/Cargo.toml @@ -11,4 +11,4 @@ rocket = { path = "../../core/lib" } # in your application, you should enable only the template engine(s) used [dependencies.rocket_dyn_templates] path = "../../contrib/dyn_templates" -features = ["tera", "handlebars"] +features = ["tera", "handlebars", "minijinja"] diff --git a/examples/templating/src/main.rs b/examples/templating/src/main.rs index e849f427b7..4eae318192 100644 --- a/examples/templating/src/main.rs +++ b/examples/templating/src/main.rs @@ -1,16 +1,23 @@ -#[macro_use] extern crate rocket; +#[macro_use] +extern crate rocket; mod hbs; +mod minijinja; mod tera; -#[cfg(test)] mod tests; +#[cfg(test)] +mod tests; use rocket::response::content::RawHtml; use rocket_dyn_templates::Template; #[get("/")] fn index() -> RawHtml<&'static str> { - RawHtml(r#"See Tera or Handlebars."#) + RawHtml( + r#"See Tera, + Handlebars, + or MiniJinja."#, + ) } #[launch] @@ -19,10 +26,16 @@ fn rocket() -> _ { .mount("/", routes![index]) .mount("/tera", routes![tera::index, tera::hello, tera::about]) .mount("/hbs", routes![hbs::index, hbs::hello, hbs::about]) + .mount( + "/minijinja", + routes![minijinja::index, minijinja::hello, minijinja::about], + ) .register("/hbs", catchers![hbs::not_found]) .register("/tera", catchers![tera::not_found]) + .register("/minijinja", catchers![minijinja::not_found]) .attach(Template::custom(|engines| { hbs::customize(&mut engines.handlebars); tera::customize(&mut engines.tera); + minijinja::customize(&mut engines.minijinja); })) } diff --git a/examples/templating/src/minijinja.rs b/examples/templating/src/minijinja.rs new file mode 100644 index 0000000000..799a1a9c50 --- /dev/null +++ b/examples/templating/src/minijinja.rs @@ -0,0 +1,61 @@ +use rocket::response::Redirect; +use rocket::Request; + +use rocket_dyn_templates::{context, minijinja::Environment, Template}; + +// use self::minijinja::; + +#[get("/")] +pub fn index() -> Redirect { + Redirect::to(uri!("/minijinja", hello(name = "Your Name"))) +} + +#[get("/hello/")] +pub fn hello(name: &str) -> Template { + Template::render( + "minijinja/index", + context! { + title: "Hello", + name: Some(name), + items: vec!["One", "Two", "Three"], + }, + ) +} + +#[get("/about")] +pub fn about() -> Template { + Template::render( + "minijinja/about.html", + context! { + title: "About", + }, + ) +} + +#[catch(404)] +pub fn not_found(req: &Request<'_>) -> Template { + println!("Handling 404 for URI: {}", req.uri()); + + Template::render( + "minijinja/error/404", + context! { + uri: req.uri() + }, + ) +} + +pub fn customize(env: &mut Environment) { + env.add_template( + "minijinja/about.html", + r#" + {% extends "minijinja/layout" %} + + {% block page %} +
+

About - Here's another page!

+
+ {% endblock %} + "#, + ) + .expect("valid Jinja2 template"); +} diff --git a/examples/templating/src/tests.rs b/examples/templating/src/tests.rs index afdbc0450c..449840386c 100644 --- a/examples/templating/src/tests.rs +++ b/examples/templating/src/tests.rs @@ -40,11 +40,11 @@ fn test_404(base: &str) { let client = Client::tracked(rocket()).unwrap(); for bad_path in &["/hello", "/foo/bar", "/404"] { let path = format!("/{}{}", base, bad_path); - let escaped_path = RawStr::new(&path).html_escape(); + let escaped_path = RawStr::new(&path).html_escape().to_lowercase(); let response = client.get(&path).dispatch(); assert_eq!(response.status(), Status::NotFound); - let response = response.into_string().unwrap(); + let response = response.into_string().unwrap().to_lowercase(); assert!(response.contains(base)); assert! { @@ -66,6 +66,7 @@ fn test_index() { let response = client.get("/").dispatch().into_string().unwrap(); assert!(response.contains("Tera")); assert!(response.contains("Handlebars")); + assert!(response.contains("MiniJinja")); } #[test] @@ -83,3 +84,11 @@ fn tera() { test_404("tera"); test_about("tera"); } + +#[test] +fn minijinja() { + test_root("minijinja"); + test_name("minijinja"); + test_404("minijinja"); + test_about("minijinja"); +} \ No newline at end of file diff --git a/examples/templating/templates/minijinja/error/404.html.j2 b/examples/templating/templates/minijinja/error/404.html.j2 new file mode 100644 index 0000000000..b04eb553f7 --- /dev/null +++ b/examples/templating/templates/minijinja/error/404.html.j2 @@ -0,0 +1,11 @@ + + + + + 404 - minijinja + + +

404: Hey! There's nothing here.

+ The page at {{ uri }} does not exist! + + diff --git a/examples/templating/templates/minijinja/footer.html.j2 b/examples/templating/templates/minijinja/footer.html.j2 new file mode 100644 index 0000000000..98266dbe77 --- /dev/null +++ b/examples/templating/templates/minijinja/footer.html.j2 @@ -0,0 +1,3 @@ + diff --git a/examples/templating/templates/minijinja/index.html.j2 b/examples/templating/templates/minijinja/index.html.j2 new file mode 100644 index 0000000000..55b6ba7ea0 --- /dev/null +++ b/examples/templating/templates/minijinja/index.html.j2 @@ -0,0 +1,17 @@ +{% extends "minijinja/layout" %} + +{% block page %} +
+

Hi {{ name }}!

+

Here are your items:

+
    + {% for item in items %} +
  • {{ item }}
  • + {% endfor %} +
+
+ +
+

Try going to /minijinja/hello/Your Name.

+
+{% endblock %} diff --git a/examples/templating/templates/minijinja/layout.html.j2 b/examples/templating/templates/minijinja/layout.html.j2 new file mode 100644 index 0000000000..b3c2ff844b --- /dev/null +++ b/examples/templating/templates/minijinja/layout.html.j2 @@ -0,0 +1,11 @@ + + + + Rocket Example - {{ title }} + + + {% include "minijinja/nav" %} + {% block page %}{% endblock %} + {% include "minijinja/footer" %} + + diff --git a/examples/templating/templates/minijinja/nav.html.j2 b/examples/templating/templates/minijinja/nav.html.j2 new file mode 100644 index 0000000000..67dcde4348 --- /dev/null +++ b/examples/templating/templates/minijinja/nav.html.j2 @@ -0,0 +1 @@ +Hello | About