diff options
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | askama/Cargo.toml | 1 | ||||
-rw-r--r-- | askama_derive/Cargo.toml | 1 | ||||
-rw-r--r-- | askama_derive/src/lib.rs | 1 | ||||
-rw-r--r-- | askama_shared/src/generator.rs | 29 | ||||
-rw-r--r-- | askama_shared/src/lib.rs | 1 | ||||
-rw-r--r-- | askama_tide/Cargo.toml | 18 | ||||
l--------- | askama_tide/LICENSE-APACHE | 1 | ||||
l--------- | askama_tide/LICENSE-MIT | 1 | ||||
-rw-r--r-- | askama_tide/README.md | 9 | ||||
-rw-r--r-- | askama_tide/src/lib.rs | 32 | ||||
-rw-r--r-- | askama_tide/templates/hello.html | 1 | ||||
-rw-r--r-- | askama_tide/tests/tide.rs | 29 | ||||
-rw-r--r-- | book/src/integrations.md | 9 |
15 files changed, 135 insertions, 1 deletions
@@ -8,6 +8,7 @@ members = [ "askama_iron", "askama_rocket", "askama_shared", + "askama_tide", "askama_warp", "testing", ] @@ -30,7 +30,7 @@ in a for-profit context, please consider supporting my open source work on * Construct templates using a familiar, easy-to-use syntax * Template code is compiled into your crate for [optimal performance][benchmarks] * Benefit from the safety provided by Rust's type system -* Optional built-in support for Actix, Gotham, Iron, Rocket and warp web frameworks +* Optional built-in support for Actix, Gotham, Iron, Rocket, warp, and tide web frameworks * Debugging features to assist you in template development * Templates must be valid UTF-8 and produce UTF-8 when rendered * Works on stable Rust diff --git a/askama/Cargo.toml b/askama/Cargo.toml index 21ad6e2..c23f05b 100644 --- a/askama/Cargo.toml +++ b/askama/Cargo.toml @@ -29,6 +29,7 @@ with-rocket = ["askama_derive/rocket"] with-actix-web = ["askama_derive/actix-web"] with-gotham = ["askama_derive/gotham"] with-warp = ["askama_derive/warp"] +with-tide = ["askama_derive/tide"] [dependencies] askama_derive = { version = "0.10", path = "../askama_derive" } diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml index 8612146..99695dd 100644 --- a/askama_derive/Cargo.toml +++ b/askama_derive/Cargo.toml @@ -19,6 +19,7 @@ rocket = [] actix-web = [] gotham = [] warp = [] +tide = [] [dependencies] askama_shared = { version = "0.10", path = "../askama_shared", default-features = false } diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index fcd857d..2a629d8 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -90,4 +90,5 @@ const INTEGRATIONS: Integrations = Integrations { iron: cfg!(feature = "iron"), rocket: cfg!(feature = "rocket"), warp: cfg!(feature = "warp"), + tide: cfg!(feature = "tide"), }; diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 180a356..fda56e2 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -109,6 +109,9 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { if self.integrations.warp { self.impl_warp_reply(&mut buf); } + if self.integrations.tide { + self.impl_tide_integrations(&mut buf); + } buf.buf } @@ -298,6 +301,32 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { buf.writeln("}"); } + fn impl_tide_integrations(&mut self, buf: &mut Buffer) { + let ext = self + .input + .path + .extension() + .and_then(|s| s.to_str()) + .unwrap_or("txt"); + + self.write_header( + buf, + "std::convert::TryInto<::askama_tide::tide::Body>", + None, + ); + buf.writeln( + "type Error = ::askama_tide::askama::Error;\n\ + fn try_into(self) -> ::askama_tide::askama::Result<::askama_tide::tide::Body> {", + ); + buf.writeln(&format!("::askama_tide::try_into_body(&self, {:?})", &ext)); + buf.writeln("}"); + buf.writeln("}"); + self.write_header(buf, "Into<::askama_tide::tide::Response>", None); + buf.writeln("fn into(self) -> ::askama_tide::tide::Response {"); + buf.writeln(&format!("::askama_tide::into_response(&self, {:?})", ext)); + buf.writeln("}\n}"); + } + // Writes header for the `impl` for `TraitFromPathName` or `Template` // for the given context struct. fn write_header( diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs index e405439..f11b129 100644 --- a/askama_shared/src/lib.rs +++ b/askama_shared/src/lib.rs @@ -267,6 +267,7 @@ pub struct Integrations { pub iron: bool, pub rocket: bool, pub warp: bool, + pub tide: bool, } static CONFIG_FILE_NAME: &str = "askama.toml"; diff --git a/askama_tide/Cargo.toml b/askama_tide/Cargo.toml new file mode 100644 index 0000000..46179a5 --- /dev/null +++ b/askama_tide/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "askama_tide" +version = "0.1.0" +authors = ["Jacob Rothstein <hi@jbr.me>"] +edition = "2018" +description = "Tide integration for Askama templates" +keywords = ["markup", "template", "jinja2", "html", "tide", "http-types"] +homepage = "https://github.com/djc/askama" +repository = "https://github.com/djc/askama" +documentation = "https://docs.rs/askama" +license = "MIT OR Apache-2.0" +workspace = ".." +readme = "README.md" + +[dependencies] +askama = { version = "0.10", path = "../askama", features = ["with-tide"] } +tide = "0.11" +async-std = { version = "1.6.0", features = ["unstable", "attributes"] } diff --git a/askama_tide/LICENSE-APACHE b/askama_tide/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/askama_tide/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE
\ No newline at end of file diff --git a/askama_tide/LICENSE-MIT b/askama_tide/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/askama_tide/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT
\ No newline at end of file diff --git a/askama_tide/README.md b/askama_tide/README.md new file mode 100644 index 0000000..05aa275 --- /dev/null +++ b/askama_tide/README.md @@ -0,0 +1,9 @@ +# askama_tide: Askama integration with tide + +[![Documentation](https://docs.rs/askama_tide/badge.svg)](https://docs.rs/askama_tide/) +[![Latest version](https://img.shields.io/crates/v/askama_tide.svg)](https://crates.io/crates/askama_tide) +[![Build Status](https://github.com/djc/askama/workflows/CI/badge.svg)](https://github.com/djc/askama/actions?query=workflow%3ACI) +[![Chat](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/djc/askama) + +Integration of the [Askama](https://github.com/djc/askama) templating engine in +code building on the tide web framework. diff --git a/askama_tide/src/lib.rs b/askama_tide/src/lib.rs new file mode 100644 index 0000000..0458348 --- /dev/null +++ b/askama_tide/src/lib.rs @@ -0,0 +1,32 @@ +pub use askama; +pub use tide; + +use askama::*; +use tide::{http::Mime, Body, Response}; + +pub fn try_into_body<T: Template>(t: &T, ext: &str) -> Result<Body> { + let string = t.render()?; + let mut body = Body::from_string(string); + + if let Some(mime) = Mime::from_extension(ext) { + body.set_mime(mime); + } + + Ok(body) +} + +pub fn into_response<T: Template>(t: &T, ext: &str) -> Response { + match try_into_body(t, ext) { + Ok(body) => { + let mut response = Response::new(200); + response.set_body(body); + response + } + + Err(e) => { + let mut response = Response::new(500); + response.set_body(e.to_string()); + response + } + } +} diff --git a/askama_tide/templates/hello.html b/askama_tide/templates/hello.html new file mode 100644 index 0000000..8149be7 --- /dev/null +++ b/askama_tide/templates/hello.html @@ -0,0 +1 @@ +Hello, {{ name }}! diff --git a/askama_tide/tests/tide.rs b/askama_tide/tests/tide.rs new file mode 100644 index 0000000..6fa1418 --- /dev/null +++ b/askama_tide/tests/tide.rs @@ -0,0 +1,29 @@ +use askama::Template; +use async_std::prelude::*; +use std::convert::TryInto; +use tide::{http::mime::HTML, Body, Response}; + +#[derive(Template)] +#[template(path = "hello.html")] +struct HelloTemplate<'a> { + name: &'a str, +} + +#[async_std::test] +async fn template_to_response() { + let mut res: Response = HelloTemplate { name: "world" }.into(); + assert_eq!(res.status(), 200); + assert_eq!(res.content_type(), Some(HTML)); + + let res: &mut tide::http::Response = res.as_mut(); + assert_eq!(res.body_string().await.unwrap(), "Hello, world!"); +} + +#[async_std::test] +async fn template_to_body() { + let mut body: Body = HelloTemplate { name: "world" }.try_into().unwrap(); + assert_eq!(body.mime(), &HTML); + let mut body_string = String::new(); + body.read_to_string(&mut body_string).await.unwrap(); + assert_eq!(body_string, "Hello, world!"); +} diff --git a/book/src/integrations.md b/book/src/integrations.md index 25bcc18..2d016c7 100644 --- a/book/src/integrations.md +++ b/book/src/integrations.md @@ -50,3 +50,12 @@ Enabling the `with-warp` feature appends an implementation of Warp's `Reply` trait for each template type. This makes it simple to return a template from a Warp filter. See [the example](https://github.com/djc/askama/blob/master/askama_warp/tests/warp.rs) from the Askama test suite for more on how to integrate. + +## Tide integration + +Enabling the `with-tide` feature appends `Into<tide::Response>` and +`TryInto<tide::Body>` implementations for each template type. This +provides the ability for tide apps to build a response directly from +a template, or to append a templated body to an existing +`Response`. See [the example](https://github.com/djc/askama/blob/master/askama_tide/tests/tide.rs) +from the Askama test suite for more on how to integrate. |