aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askama/src/lib.rs30
-rw-r--r--testing/templates/render_in_place.html6
-rw-r--r--testing/templates/render_in_place_sec1.html2
-rw-r--r--testing/templates/render_in_place_sec2.html2
-rw-r--r--testing/tests/render_in_place.rs39
-rw-r--r--testing/tests/render_with_enums.rs80
6 files changed, 159 insertions, 0 deletions
diff --git a/askama/src/lib.rs b/askama/src/lib.rs
index de25c3e..d1c18c5 100644
--- a/askama/src/lib.rs
+++ b/askama/src/lib.rs
@@ -371,6 +371,36 @@
//! recursion. This is because the `Display` implementation for that expression
//! will in turn evaluate the expression and yield `self` again.
//!
+//! ## Template in template
+//!
+//! Using expressions, it is possible to render a template inside another one. This functionality
+//! allows modularize template sections and inject them in another template. This
+//! facilitates testing, and reusing part of templates.
+//!
+//! ```rust
+//! use askama::Template;
+//! #[derive(Template)]
+//! #[template(source = "Section 1: {{ s1.render().unwrap() }}", ext = "txt")]
+//! struct RenderInPlace<'a> {
+//! s1: SectionOne<'a>
+//! }
+//! #[derive(Template)]
+//! #[template(source = "A={{ a }}\nB={{ b }}", ext = "txt")]
+//! struct SectionOne<'a> {
+//! a: &'a str,
+//! b: &'a str,
+//! }
+//! let t = RenderInPlace{s1: SectionOne{a: "a", b: "b"}};
+//! assert_eq!(t.render().unwrap(), "Section 1: A=a\nB=b")
+//! ```
+//!
+//! See the example
+//! [render in place](https://github.com/djc/askama/blob/master/testing/tests/render_in_place.rs)
+//! using a vector of templates in a for block.
+//!
+//! See the example [using enums](https://github.com/djc/askama/blob/master/testing/tests/render_with_enums.rs)
+//! for another use case. You can use different template parts depending on the context.
+//!
//! ## Comments
//!
//! Askama supports block comments delimited by `{#` and `#}`.
diff --git a/testing/templates/render_in_place.html b/testing/templates/render_in_place.html
new file mode 100644
index 0000000..3dff36c
--- /dev/null
+++ b/testing/templates/render_in_place.html
@@ -0,0 +1,6 @@
+Section 1: {{ s1.render().unwrap() }}
+Section 2: {{ s2.render().unwrap()|safe }}
+Section 3 for:
+{% for s in s3.as_slice() -%}
+* {{ s.render().unwrap() }}
+{% endfor %}
diff --git a/testing/templates/render_in_place_sec1.html b/testing/templates/render_in_place_sec1.html
new file mode 100644
index 0000000..75f9fd6
--- /dev/null
+++ b/testing/templates/render_in_place_sec1.html
@@ -0,0 +1,2 @@
+A={{ a }}
+B={{ b }}
diff --git a/testing/templates/render_in_place_sec2.html b/testing/templates/render_in_place_sec2.html
new file mode 100644
index 0000000..2a0ae21
--- /dev/null
+++ b/testing/templates/render_in_place_sec2.html
@@ -0,0 +1,2 @@
+C={{ c }}
+D={{ d }}
diff --git a/testing/tests/render_in_place.rs b/testing/tests/render_in_place.rs
new file mode 100644
index 0000000..3d1b91e
--- /dev/null
+++ b/testing/tests/render_in_place.rs
@@ -0,0 +1,39 @@
+use askama::Template;
+#[derive(Template)]
+#[template(path = "render_in_place.html")]
+struct RenderInPlace<'a> {
+ s1: SectionOne<'a>,
+ s2: SectionTwo<'a>,
+ s3: &'a Vec<SectionOne<'a>>,
+}
+
+#[derive(Template)]
+#[template(path = "render_in_place_sec1.html")]
+struct SectionOne<'a> {
+ a: &'a str,
+ b: &'a str,
+}
+
+#[derive(Template)]
+#[template(path = "render_in_place_sec2.html")]
+struct SectionTwo<'a> {
+ c: &'a str,
+ d: &'a str,
+}
+
+#[test]
+fn test_render_in_place() {
+ let t = RenderInPlace {
+ s1: SectionOne { a: "A", b: "B" },
+ s2: SectionTwo { c: "C", d: "D" },
+ s3: &vec![
+ SectionOne { a: "1", b: "2" },
+ SectionOne { a: "A", b: "B" },
+ SectionOne { a: "a", b: "b" },
+ ],
+ };
+ assert_eq!(
+ t.render().unwrap(),
+ "Section 1: A=A\nB=B\nSection 2: C=C\nD=D\nSection 3 for:\n* A=1\nB=2\n* A=A\nB=B\n* A=a\nB=b\n"
+ );
+}
diff --git a/testing/tests/render_with_enums.rs b/testing/tests/render_with_enums.rs
new file mode 100644
index 0000000..fb97e54
--- /dev/null
+++ b/testing/tests/render_with_enums.rs
@@ -0,0 +1,80 @@
+use askama::Template;
+
+enum SectionOneType<'a>{
+ Empty(TEmpty),
+ Simple(TSecOneSimple<'a>),
+ Full(TSecOneFull<'a>)
+}
+impl<'a> SectionOneType<'a> {
+ pub fn render(&self) -> askama::Result<String>{
+ match self {
+ SectionOneType::Empty(v) => v.render(),
+ SectionOneType::Simple(v) => v.render(),
+ SectionOneType::Full(v) => v.render(),
+ }
+ }
+}
+enum SectionTwoFormat<'a>{
+ Html(TSecTwoHtml<'a>),
+ Text(TSecTwoText<'a>),
+}
+impl<'a> SectionTwoFormat<'a> {
+ pub fn render(&self) -> askama::Result<String>{
+ match self {
+ SectionTwoFormat::Html(v) => v.render(),
+ SectionTwoFormat::Text(v) => v.render(),
+ }
+ }
+}
+#[derive(Template)]
+#[template(path = "render_in_place.html")]
+struct RenderInPlace<'a> {
+ s1: SectionOneType<'a>,
+ s2: SectionTwoFormat<'a>,
+ s3: &'a Vec<SectionOneType<'a>>
+}
+
+#[derive(Template)]
+#[template(source = "", ext = "txt")]
+struct TEmpty {
+}
+#[derive(Template)]
+#[template(source = "{{ a }}", ext = "txt")]
+struct TSecOneSimple<'a> {
+ a: &'a str
+}
+#[derive(Template)]
+#[template(source = "{{ a }}, {{ b }}", ext = "txt")]
+struct TSecOneFull<'a> {
+ a: &'a str,
+ b: &'a str
+}
+
+#[derive(Template)]
+#[template(source = "<span>{{ c }}</span><p>{{ d }}</p>", ext = "html")]
+struct TSecTwoHtml<'a> {
+ c: &'a str,
+ d: &'a str,
+}
+#[derive(Template)]
+#[template(source = "{{ c }}, {{ d }}", ext = "txt")]
+struct TSecTwoText<'a> {
+ c: &'a str,
+ d: &'a str,
+}
+
+#[test]
+fn test_render_with_enums() {
+ let t = RenderInPlace {
+ s1: SectionOneType::Empty(TEmpty {}),
+ s2: SectionTwoFormat::Html(TSecTwoHtml { c: "C", d: "D" }),
+ s3: &vec![SectionOneType::Empty(TEmpty {}),
+ SectionOneType::Simple(TSecOneSimple { a: "A" }),
+ SectionOneType::Full(TSecOneFull { a: "A", b: "B" }),
+ ]
+ };
+ assert_eq!(
+ t.render().unwrap(),
+ "Section 1: \nSection 2: <span>C</span><p>D</p>\nSection 3 for:\n* \n* A\n* A, B\n"
+ );
+}