diff options
| author | 2017-08-02 20:59:30 +0200 | |
|---|---|---|
| committer | 2017-08-02 20:59:30 +0200 | |
| commit | 8ff2e316c07b4fd4373dd8a0bb5747bef3372a32 (patch) | |
| tree | 5147b0be34fc45641d5e296c3020e91e6fec6f42 | |
| parent | 91fe53d9b5db7ace5f82889a174ef5061a049771 (diff) | |
| parent | ce84543b69b69ab2030ce4daeae3f26d5008b11d (diff) | |
| download | askama-8ff2e316c07b4fd4373dd8a0bb5747bef3372a32.tar.gz askama-8ff2e316c07b4fd4373dd8a0bb5747bef3372a32.tar.bz2 askama-8ff2e316c07b4fd4373dd8a0bb5747bef3372a32.zip | |
Merge changes
Diffstat (limited to '')
| -rw-r--r-- | Cargo.lock | 24 | ||||
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | askama/src/filters.rs | 49 | ||||
| -rw-r--r-- | askama/src/lib.rs | 11 | ||||
| -rw-r--r-- | askama_derive/Cargo.toml | 2 | ||||
| -rw-r--r-- | askama_derive/src/generator.rs | 16 | ||||
| -rw-r--r-- | askama_derive/src/parser.rs | 33 | ||||
| -rw-r--r-- | testing/templates/nested-attr.html | 1 | ||||
| -rw-r--r-- | testing/tests/simple.rs | 19 | 
9 files changed, 132 insertions, 30 deletions
| @@ -16,15 +16,31 @@ dependencies = [  name = "askama_derive"  version = "0.3.3"  dependencies = [ - "nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)",   "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",   "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",  ]  [[package]] +name = "libc" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]]  name = "nom" -version = "2.2.1" +version = "3.2.0"  source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +]  [[package]]  name = "quote" @@ -55,7 +71,9 @@ version = "0.0.4"  source = "registry+https://github.com/rust-lang/crates.io-index"  [metadata] -"checksum nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" +"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264" +"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" +"checksum nom 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06989cbd367e06f787a451f3bc67d8c3e0eaa10b461cc01152ffab24261a31b1"  "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"  "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"  "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" @@ -31,7 +31,7 @@ Many thanks to [David Tolnay][dtolnay] for his support in improving Askama.  ### Supported in templates  * Template inheritance (one level only) -* Basic loops and if/else if/else statements +* Basic loops and if/else statements  * Whitespace suppressing with '-' markers  * Some built-in filters @@ -59,11 +59,10 @@ First, add the following to your crate's `Cargo.toml`:  build = "build.rs"  # in section [dependencies] -askama = "0.1" -askama_derive = "0.1" +askama = "0.3"  # in section [build-dependencies] -askama = "0.1" +askama = "0.3"  ```  Because Askama will generate Rust code from your template files, diff --git a/askama/src/filters.rs b/askama/src/filters.rs index 3f6aede..ccbf1a0 100644 --- a/askama/src/filters.rs +++ b/askama/src/filters.rs @@ -57,6 +57,34 @@ pub fn e(s: &fmt::Display) -> String {  /// the Askama code generator.  pub fn format() { } +/// Converts to lowercase. +pub fn lower(s: &fmt::Display) -> String { +    let s = format!("{}", s); +    s.to_lowercase() +} + +/// Alias for the `lower()` filter. +pub fn lowercase(s: &fmt::Display) -> String { +    lower(s) +} + +/// Converts to uppercase. +pub fn upper(s: &fmt::Display) -> String { +    let s = format!("{}", s); +    s.to_uppercase() +} + +/// Alias for the `upper()` filter. +pub fn uppercase(s: &fmt::Display) -> String { +    upper(s) +} + +/// Strip leading and trailing whitespace. +pub fn trim(s: &fmt::Display) -> String { +    let s = format!("{}", s); +    s.trim().to_owned() +} +  #[cfg(test)]  mod tests {      use super::*; @@ -67,4 +95,25 @@ mod tests {          assert_eq!(escape(&"bla&"), "bla&");          assert_eq!(escape(&"<foo"), "<foo");      } + +    #[test] +    fn test_lower() { +        assert_eq!(lower(&"Foo"), "foo"); +        assert_eq!(lower(&"FOO"), "foo"); +        assert_eq!(lower(&"FooBar"), "foobar"); +        assert_eq!(lower(&"foo"), "foo"); +    } + +    #[test] +    fn test_upper() { +        assert_eq!(upper(&"Foo"), "FOO"); +        assert_eq!(upper(&"FOO"), "FOO"); +        assert_eq!(upper(&"FooBar"), "FOOBAR"); +        assert_eq!(upper(&"foo"), "FOO"); +    } + +    #[test] +    fn test_trim() { +        assert_eq!(trim(&" Hello\tworld\t"), "Hello\tworld"); +    }  } diff --git a/askama/src/lib.rs b/askama/src/lib.rs index 311992f..9126a99 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -51,8 +51,8 @@  //! Reading from variables is subject to the usual borrowing policies.  //! For example, `{{ name }}` will get the ``name`` field from the template  //! context, -//! while `{{ user.name }}` will get the ``name`` field of the `user` -//! ``field`` of the template context. +//! while `{{ user.name }}` will get the ``name`` field of the ``user`` +//! field from the template context.  //!  //! ## Filters  //! @@ -105,6 +105,8 @@  //!  //! The `block` tags define three blocks that can be filled in by child  //! templates. The base template defines a default version of the block. +//! A base template must define one or more blocks in order to be enable +//! inheritance.  //!  //! ### Child template  //! @@ -133,6 +135,11 @@  //! have a field called `_parent` of the type used as the base template  //! context. Blocks can only refer to the context of their own template.  //! +//! Note that, if the base template lives in another module than the child +//! template, the child template's module should import all symbols from the +//! base template's module in order for it to find the trait definition that +//! supports the inheritance mechanism. +//!  //! ## HTML escaping  //!  //! Askama does not yet support automatic escaping. Care must be taken to diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml index 5f65f23..4aad3fb 100644 --- a/askama_derive/Cargo.toml +++ b/askama_derive/Cargo.toml @@ -12,6 +12,6 @@ workspace = ".."  proc-macro = true  [dependencies] -nom = "2.1" +nom = "3"  syn = "0.11"  quote = "0.3" diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index edde3fe..f055cb7 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -129,7 +129,7 @@ impl<'a> Generator<'a> {          if name == "format" {              self.write("format!(");          } else { -            self.write(&format!("askama::filters::{}(&", name)); +            self.write(&format!("::askama::filters::{}(&", name));          }          for (i, arg) in args.iter().enumerate() { @@ -274,7 +274,7 @@ impl<'a> Generator<'a> {                         ws2: &WS) {          self.writeln("#[allow(unused_variables)]");          self.writeln(&format!( -            "fn render_block_{}_to(&self, writer: &mut std::fmt::Write) {{", +            "fn render_block_{}_to(&self, writer: &mut ::std::fmt::Write) {{",              name));          self.prepare_ws(ws1);          self.handle(nodes); @@ -351,7 +351,7 @@ impl<'a> Generator<'a> {          let name = if let Some(suffix) = trait_suffix {              format!("TraitFrom{}", suffix)          } else { -            "askama::Template".to_string() +            "::askama::Template".to_string()          };          self.writeln(&format!("impl{} {} for {}{}{} {{",                                full_anno.as_str(), &name, ast.ident.as_ref(), @@ -360,7 +360,7 @@ impl<'a> Generator<'a> {      fn impl_template(&mut self, ast: &syn::DeriveInput, nodes: &'a [Node]) {          self.write_header(ast, None); -        self.writeln("fn render_to(&self, writer: &mut std::fmt::Write) {"); +        self.writeln("fn render_to(&self, writer: &mut ::std::fmt::Write) {");          self.handle(nodes);          self.flush_ws(&WS(false, false));          self.writeln("}"); @@ -375,7 +375,7 @@ impl<'a> Generator<'a> {          self.writeln("#[allow(unused_variables)]");          let trait_name = format!("TraitFrom{}", path_as_identifier(base));          self.writeln(&format!( -            "fn render_trait_to(&self, timpl: &{}, writer: &mut std::fmt::Write) {{", +            "fn render_trait_to(&self, timpl: &{}, writer: &mut ::std::fmt::Write) {{",              trait_name));          if let Some(nodes) = nodes { @@ -392,7 +392,7 @@ impl<'a> Generator<'a> {      fn impl_template_for_trait(&mut self, ast: &syn::DeriveInput, derived: bool) {          self.write_header(ast, None); -        self.writeln("fn render_to(&self, writer: &mut std::fmt::Write) {"); +        self.writeln("fn render_to(&self, writer: &mut ::std::fmt::Write) {");          if derived {              self.writeln("self._parent.render_trait_to(self, writer);");          } else { @@ -408,11 +408,11 @@ impl<'a> Generator<'a> {          for bname in block_names {              self.writeln(&format!( -                "fn render_block_{}_to(&self, writer: &mut std::fmt::Write);", +                "fn render_block_{}_to(&self, writer: &mut ::std::fmt::Write);",                  bname));          }          self.writeln(&format!( -            "fn render_trait_to(&self, timpl: &{}, writer: &mut std::fmt::Write);", +            "fn render_trait_to(&self, timpl: &{}, writer: &mut ::std::fmt::Write);",              trait_name));          self.writeln("}"); diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs index 74140bf..61ccb09 100644 --- a/askama_derive/src/parser.rs +++ b/askama_derive/src/parser.rs @@ -156,18 +156,27 @@ named!(expr_single<Expr>, alt!(      expr_group  )); -named!(expr_attr<Expr>, alt!( -    do_parse!( -        obj: expr_single >> -        tag_s!(".") >> -        attr: identifier >> -        args: arguments >> -        (if args.is_some() { -            Expr::Call(Box::new(obj), attr, args.unwrap()) -        } else { -            Expr::Attr(Box::new(obj), attr) -        }) -    ) | expr_single +named!(attr<(&str, Option<Vec<Expr>>)>, do_parse!( +    tag_s!(".") >> +    attr: identifier >> +    args: arguments >> +    (attr, args) +)); + +named!(expr_attr<Expr>, do_parse!( +    obj: expr_single >> +    attrs: many0!(attr) >> +    ({ +        let mut res = obj; +        for (aname, args) in attrs { +            res = if args.is_some() { +                Expr::Call(Box::new(res), aname, args.unwrap()) +            } else { +                Expr::Attr(Box::new(res), aname) +            }; +        } +        res +    })  ));  named!(filter<(&str, Option<Vec<Expr>>)>, do_parse!( diff --git a/testing/templates/nested-attr.html b/testing/templates/nested-attr.html new file mode 100644 index 0000000..3bbbbc3 --- /dev/null +++ b/testing/templates/nested-attr.html @@ -0,0 +1 @@ +{{ inner.holder.a }} diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs index 6d8afa3..c924e85 100644 --- a/testing/tests/simple.rs +++ b/testing/tests/simple.rs @@ -93,6 +93,25 @@ fn test_attr() {  } +struct NestedHolder { +    holder: Holder, +} + +#[derive(Template)] +#[template(path = "nested-attr.html")] +struct NestedAttrTemplate { +    inner: NestedHolder, +} + +#[test] +fn test_nested_attr() { +    let t = NestedAttrTemplate { +        inner: NestedHolder { holder: Holder { a: 5 } } +    }; +    assert_eq!(t.render(), "5"); +} + +  #[derive(Template)]  #[template(path = "option.html")]  struct OptionTemplate<'a> { | 
