Skip to content

Commit

Permalink
Merge changes
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Aug 2, 2017
2 parents 91fe53d + ce84543 commit 8ff2e31
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 30 deletions.
24 changes: 21 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand Down
49 changes: 49 additions & 0 deletions askama/src/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand All @@ -67,4 +95,25 @@ mod tests {
assert_eq!(escape(&"bla&"), "bla&");
assert_eq!(escape(&"<foo"), "&lt;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");
}
}
11 changes: 9 additions & 2 deletions askama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
//!
Expand Down Expand Up @@ -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
//!
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion askama_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ workspace = ".."
proc-macro = true

[dependencies]
nom = "2.1"
nom = "3"
syn = "0.11"
quote = "0.3"
16 changes: 8 additions & 8 deletions askama_derive/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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(),
Expand All @@ -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("}");
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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("}");
Expand Down
33 changes: 21 additions & 12 deletions askama_derive/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down
1 change: 1 addition & 0 deletions testing/templates/nested-attr.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ inner.holder.a }}
19 changes: 19 additions & 0 deletions testing/tests/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down

0 comments on commit 8ff2e31

Please sign in to comment.