Repository: djc/askama
Pull request #402 (2020-12-15 07:15:09)

Added set alias for let
Related to #329

Added a `set` alias for `let` to be more in line with Jinja.



Patch:
diff --git a/askama/Cargo.toml b/askama/Cargo.toml
index 0b3a897..da53a98 100644
--- a/askama/Cargo.toml
+++ b/askama/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "askama"
-version = "0.10.3"
+version = "0.10.5"
 authors = ["Dirkjan Ochtman <dirkjan@ochtman.nl>"]
 description = "Type-safe, compiled Jinja-like templates for Rust"
 documentation = "https://docs.rs/askama"
@@ -33,9 +33,9 @@ with-tide = ["askama_derive/tide"]
 with-warp = ["askama_derive/warp"]
 
 [dependencies]
-askama_derive = { version = "0.10.3", path = "../askama_derive" }
+askama_derive = { version = "0.10.5", path = "../askama_derive" }
 askama_escape = { version = "0.10", path = "../askama_escape" }
-askama_shared = { version = "0.10.4", path = "../askama_shared", default-features = false }
+askama_shared = { version = "0.11", path = "../askama_shared", default-features = false }
 mime = { version = "0.3", optional = true }
 mime_guess = { version = "2.0.0-alpha", optional = true }
 
diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml
index 63d08bd..f3df891 100644
--- a/askama_derive/Cargo.toml
+++ b/askama_derive/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "askama_derive"
-version = "0.10.3"
+version = "0.10.5"
 authors = ["Dirkjan Ochtman <dirkjan@ochtman.nl>"]
 description = "Procedural macro package for Askama"
 homepage = "https://github.com/djc/askama"
@@ -23,6 +23,6 @@ tide = []
 warp = []
 
 [dependencies]
-askama_shared = { version = "0.10.4", path = "../askama_shared", default-features = false }
+askama_shared = { version = "0.11", path = "../askama_shared", default-features = false }
 proc-macro2 = "1"
 syn = "1"
diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml
index 19946e7..fdc5a4c 100644
--- a/askama_shared/Cargo.toml
+++ b/askama_shared/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "askama_shared"
-version = "0.10.5"
+version = "0.11.1"
 authors = ["Dirkjan Ochtman <dirkjan@ochtman.nl>"]
 description = "Shared code for Askama"
 homepage = "https://github.com/djc/askama"
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs
index 320e55e..0053b38 100644
--- a/askama_shared/src/generator.rs
+++ b/askama_shared/src/generator.rs
@@ -308,12 +308,12 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
         )?;
 
         buf.writeln(
-            "fn into_response(self, app: &A) \
+            "fn into_response(self, app: &A, req: &::mendes::http::request::Parts) \
              -> ::mendes::http::Response<A::ResponseBody> {",
         )?;
 
         buf.writeln(&format!(
-            "::mendes::askama::into_response(app, &self, {:?})",
+            "::mendes::askama::into_response(app, req, &self, {:?})",
             self.input.path.extension()
         ))?;
         buf.writeln("}")?;
@@ -667,8 +667,26 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
                 ", _loop_item) in ::askama::helpers::TemplateLoop::new({}) {{",
                 expr_code
             )),
+            Expr::Array(..) => buf.writeln(&format!(
+                ", _loop_item) in ::askama::helpers::TemplateLoop::new({}.iter()) {{",
+                expr_code
+            )),
+            // If `iter` is a call then we assume it's something that returns
+            // an iterator. If not then the user can explicitly add the needed
+            // call without issues.
+            Expr::MethodCall(..) | Expr::PathCall(..) | Expr::Index(..) => buf.writeln(&format!(
+                ", _loop_item) in ::askama::helpers::TemplateLoop::new(({}).into_iter()) {{",
+                expr_code
+            )),
+            // If accessing `self` then it most likely needs to be
+            // borrowed, to prevent an attempt of moving.
+            _ if expr_code.starts_with("self.") => buf.writeln(&format!(
+                ", _loop_item) in ::askama::helpers::TemplateLoop::new(((&{}).into_iter())) {{",
+                expr_code
+            )),
+            // Otherwise, we borrow `iter` assuming that it implements `IntoIterator`.
             _ => buf.writeln(&format!(
-                ", _loop_item) in ::askama::helpers::TemplateLoop::new((&{}).into_iter()) {{",
+                ", _loop_item) in ::askama::helpers::TemplateLoop::new(({}).into_iter()) {{",
                 expr_code
             )),
         }?;
diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs
index a40e967..a03952d 100644
--- a/askama_shared/src/parser.rs
+++ b/askama_shared/src/parser.rs
@@ -802,7 +802,7 @@ fn block_match<'a>(i: &'a [u8], s: &'a Syntax<'a>) -> IResult<&'a [u8], Node<'a>
 fn block_let(i: &[u8]) -> IResult<&[u8], Node> {
     let mut p = tuple((
         opt(tag("-")),
-        ws(tag("let")),
+        ws(alt((tag("let"), tag("set")))),
         ws(alt((target_single, target_tuple))),
         opt(tuple((ws(tag("=")), ws(expr_any)))),
         opt(tag("-")),
diff --git a/book/src/template_syntax.md b/book/src/template_syntax.md
index 3f89213..befde8f 100644
--- a/book/src/template_syntax.md
+++ b/book/src/template_syntax.md
@@ -16,7 +16,7 @@ Inside code blocks, you can also declare variables or assign values
 to variables.
 Assignments can't be imported by other templates.
 
-Assignments use the let tag:
+Assignments use the `let` tag:
 
 ```text
 {% let name = user.name %}
@@ -31,6 +31,8 @@ Assignments use the let tag:
 {{ val }}
 ```
 
+For compatibility with Jinja, `set` can be used in place of `let`.
+
 ## Filters
 
 Values such as those obtained from variables can be post-processed


Test patch:
diff --git a/testing/tests/loops.rs b/testing/tests/loops.rs
index 3ce6185..4345b4f 100644
--- a/testing/tests/loops.rs
+++ b/testing/tests/loops.rs
@@ -67,3 +67,39 @@ fn test_for_range() {
         "foo (first)\nfoo (last)\nbar\nbar\nfoo\nbar\nbar\n"
     );
 }
+
+#[derive(Template)]
+#[template(source = "{% for i in [1, 2, 3] %}{{ i }}{% endfor %}", ext = "txt")]
+struct ForArrayTemplate {}
+
+#[test]
+fn test_for_array() {
+    let t = ForArrayTemplate {};
+    assert_eq!(t.render().unwrap(), "123");
+}
+
+#[derive(Template)]
+#[template(
+    source = "{% for i in [1, 2, 3].iter() %}{{ i }}{% endfor %}",
+    ext = "txt"
+)]
+struct ForMethodCallTemplate {}
+
+#[test]
+fn test_for_method_call() {
+    let t = ForMethodCallTemplate {};
+    assert_eq!(t.render().unwrap(), "123");
+}
+
+#[derive(Template)]
+#[template(
+    source = "{% for i in [1, 2, 3, 4, 5][3..] %}{{ i }}{% endfor %}",
+    ext = "txt"
+)]
+struct ForIndexTemplate {}
+
+#[test]
+fn test_for_index() {
+    let t = ForIndexTemplate {};
+    assert_eq!(t.render().unwrap(), "45");
+}