mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 23:35:07 +00:00
Add support for include blocks (see #25)
This commit is contained in:
parent
02e0f783f9
commit
51eee57b84
@ -1,4 +1,4 @@
|
|||||||
use parser::{Cond, Expr, Node, Target, WS};
|
use parser::{self, Cond, Expr, Node, Target, WS};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use syn;
|
use syn;
|
||||||
@ -27,17 +27,25 @@ struct Generator<'a> {
|
|||||||
|
|
||||||
impl<'a> Generator<'a> {
|
impl<'a> Generator<'a> {
|
||||||
|
|
||||||
fn new() -> Generator<'a> {
|
fn new(locals: HashSet<String>, indent: u8) -> Generator<'a> {
|
||||||
Generator {
|
Generator {
|
||||||
buf: String::new(),
|
buf: String::new(),
|
||||||
indent: 0,
|
indent: indent,
|
||||||
start: true,
|
start: true,
|
||||||
locals: HashSet::new(),
|
locals: locals,
|
||||||
next_ws: None,
|
next_ws: None,
|
||||||
skip_ws: false,
|
skip_ws: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default() -> Generator<'a> {
|
||||||
|
Self::new(HashSet::new(), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child(&self) -> Generator<'a> {
|
||||||
|
Self::new(self.locals.clone(), self.indent)
|
||||||
|
}
|
||||||
|
|
||||||
fn indent(&mut self) {
|
fn indent(&mut self) {
|
||||||
self.indent += 1;
|
self.indent += 1;
|
||||||
}
|
}
|
||||||
@ -282,6 +290,15 @@ impl<'a> Generator<'a> {
|
|||||||
self.writeln("}");
|
self.writeln("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_include(&mut self, ws: &WS, src: &str) {
|
||||||
|
self.prepare_ws(ws);
|
||||||
|
let nodes = parser::parse(&src);
|
||||||
|
let mut gen = self.child();
|
||||||
|
gen.handle(&nodes);
|
||||||
|
self.buf.push_str(&gen.result());
|
||||||
|
self.flush_ws(ws);
|
||||||
|
}
|
||||||
|
|
||||||
fn handle(&mut self, nodes: &'a [Node]) {
|
fn handle(&mut self, nodes: &'a [Node]) {
|
||||||
for n in nodes {
|
for n in nodes {
|
||||||
match *n {
|
match *n {
|
||||||
@ -300,6 +317,9 @@ impl<'a> Generator<'a> {
|
|||||||
Node::BlockDef(ref ws1, name, ref block_nodes, ref ws2) => {
|
Node::BlockDef(ref ws1, name, ref block_nodes, ref ws2) => {
|
||||||
self.write_block_def(ws1, name, block_nodes, ws2);
|
self.write_block_def(ws1, name, block_nodes, ws2);
|
||||||
}
|
}
|
||||||
|
Node::Include(ref ws, ref src) => {
|
||||||
|
self.handle_include(ws, src);
|
||||||
|
},
|
||||||
Node::Extends(_) => {
|
Node::Extends(_) => {
|
||||||
panic!("no extends or block definition allowed in content");
|
panic!("no extends or block definition allowed in content");
|
||||||
},
|
},
|
||||||
@ -446,7 +466,7 @@ pub fn generate(ast: &syn::DeriveInput, path: &str, mut nodes: Vec<Node>) -> Str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut gen = Generator::new();
|
let mut gen = Generator::default();
|
||||||
if !blocks.is_empty() {
|
if !blocks.is_empty() {
|
||||||
if base.is_none() {
|
if base.is_none() {
|
||||||
gen.define_trait(path, &block_names);
|
gen.define_trait(path, &block_names);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nom::{self, IResult};
|
use nom::{self, IResult};
|
||||||
|
use path;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -31,6 +32,7 @@ pub enum Node<'a> {
|
|||||||
Extends(Expr<'a>),
|
Extends(Expr<'a>),
|
||||||
BlockDef(WS, &'a str, Vec<Node<'a>>, WS),
|
BlockDef(WS, &'a str, Vec<Node<'a>>, WS),
|
||||||
Block(WS, &'a str, WS),
|
Block(WS, &'a str, WS),
|
||||||
|
Include(WS, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Cond<'a> = (WS, Option<Expr<'a>>, Vec<Node<'a>>);
|
pub type Cond<'a> = (WS, Option<Expr<'a>>, Vec<Node<'a>>);
|
||||||
@ -324,6 +326,25 @@ named!(block_block<Node>, do_parse!(
|
|||||||
WS(pws2.is_some(), pws2.is_some())))
|
WS(pws2.is_some(), pws2.is_some())))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
named!(block_include<Node>, do_parse!(
|
||||||
|
tag_s!("{%") >>
|
||||||
|
pws: opt!(tag_s!("-")) >>
|
||||||
|
ws!(tag_s!("include")) >>
|
||||||
|
name: ws!(expr_str_lit) >>
|
||||||
|
nws: opt!(tag_s!("-")) >>
|
||||||
|
tag_s!("%}") >>
|
||||||
|
({
|
||||||
|
let mut src = match name {
|
||||||
|
Expr::StrLit(s) => path::get_template_source(s),
|
||||||
|
_ => panic!("include path must be a string literal"),
|
||||||
|
};
|
||||||
|
if src.ends_with('\n') {
|
||||||
|
let _ = src.pop();
|
||||||
|
}
|
||||||
|
Node::Include(WS(pws.is_some(), nws.is_some()), src)
|
||||||
|
})
|
||||||
|
));
|
||||||
|
|
||||||
named!(block_comment<Node>, do_parse!(
|
named!(block_comment<Node>, do_parse!(
|
||||||
tag_s!("{#") >>
|
tag_s!("{#") >>
|
||||||
take_until_s!("#}") >>
|
take_until_s!("#}") >>
|
||||||
@ -338,6 +359,7 @@ named!(parse_template<Vec<Node<'a>>>, many0!(alt!(
|
|||||||
block_if |
|
block_if |
|
||||||
block_for |
|
block_for |
|
||||||
block_extends |
|
block_extends |
|
||||||
|
block_include |
|
||||||
block_block
|
block_block
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user