From 78782783102e069862de005112fe1a2fbb5baea1 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 5 Feb 2017 15:00:26 +0100 Subject: Add parser support for block and extend blocks --- askama/src/generator.rs | 8 ++++++++ askama/src/parser.rs | 25 ++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/askama/src/generator.rs b/askama/src/generator.rs index 22931c7..0f5ec85 100644 --- a/askama/src/generator.rs +++ b/askama/src/generator.rs @@ -159,6 +159,10 @@ impl Generator { } } + fn write_block(&mut self, name: &str) { + self.writeln(&format!("self.render_block_{}_into(writer);", name)); + } + fn handle(&mut self, nodes: &Vec) { for n in nodes { match n { @@ -168,6 +172,10 @@ impl Generator { &Node::Loop(ref var, ref iter, ref body) => { self.write_loop(&var, &iter, &body); }, + &Node::Block(ref name) => { self.write_block(name) }, + &Node::Extends(_) | &Node::BlockDef(_, _) => { + panic!("no extends or block definition allowed in content"); + }, } } } diff --git a/askama/src/parser.rs b/askama/src/parser.rs index 3448330..b642b00 100644 --- a/askama/src/parser.rs +++ b/askama/src/parser.rs @@ -17,6 +17,9 @@ pub enum Node<'a> { Expr(Expr<'a>), Cond(Vec<(Option>, Vec>)>), Loop(Target<'a>, Expr<'a>, Vec>), + Extends(Expr<'a>), + BlockDef(&'a str, Vec>), + Block(&'a str), } pub type Nodes<'a> = Vec>; @@ -133,11 +136,31 @@ named!(block_for, do_parse!( tag_s!("%}") >> (Node::Loop(var, iter, block)))); +named!(block_extends, do_parse!( + tag_s!("{%") >> + ws!(tag_s!("extends")) >> + name: ws!(expr_str_lit) >> + tag_s!("%}") >> + (Node::Extends(name)))); + +named!(block_block, do_parse!( + tag_s!("{%") >> + ws!(tag_s!("block")) >> + name: ws!(nom::alphanumeric) >> + tag_s!("%}") >> + contents: parse_template >> + tag_s!("{%") >> + ws!(tag_s!("endblock")) >> + tag_s!("%}") >> + (Node::BlockDef(str::from_utf8(name).unwrap(), contents)))); + named!(parse_template, many0!(alt!( take_content | expr_node | block_if | - block_for))); + block_for | + block_extends | + block_block))); pub fn parse<'a>(src: &'a str) -> Nodes { match parse_template(src.as_bytes()) { -- cgit