New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for importing template files with macros #51
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice! Thanks for working on this. Please review my comments and let me know what you think.
askama_shared/src/generator.rs
Outdated
@@ -12,8 +12,8 @@ use std::collections::{HashMap, HashSet}; | |||
use syn; | |||
|
|||
|
|||
pub fn generate(input: &TemplateInput, nodes: &[Node]) -> String { | |||
Generator::default().build(&State::new(input, nodes)) | |||
pub fn generate(input: &TemplateInput, nodes: &[Node], imported_nodes: &[Node]) -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: how do you feel about just calling this imported
? imported_notes
feels a little unwieldy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, but I will also change it to containing the macros directly.
askama_shared/src/input.rs
Outdated
@@ -129,6 +131,34 @@ impl<'a> TemplateMeta<'a> { | |||
} | |||
} | |||
|
|||
pub struct Imports<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the way this is used, and the fact it relies on the parser, I think putting it in input
is probably not quite right. Can you move it to lib.rs
, between build_template()
and the errors
module?
askama_shared/src/input.rs
Outdated
} | ||
|
||
impl <'a> Imports<'a> { | ||
pub fn new(parent_nodes: &'a [Node], parent_path: &'a Path) -> Imports<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we have three stages here:
Imports::new()
finds import statements and gets the template sources for themImports::parse()
turns the sources intoVec<Node>
sgenerator::State::new()
finds theNode::Macro
s and puts them into the macro map
Is there any reason not do all in one place, so something like a get_imported_macros()
that takes parent_nodes
and parent_path
and returns a MacroMap
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon reflection, I guess the template sources have to be preserved, since the AST nodes depend on them. Still, I think we can extract the Macro
nodes earlier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first step is needed for ownership reasons but I think the other two can be combined. Then Imports::parse() would return the macros directly.
@@ -0,0 +1,2 @@ | |||
{% import "macro.html" -%} | |||
{%- call thrice(s) %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: please add a trailing newline here.
testing/tests/import.rs
Outdated
@@ -0,0 +1,16 @@ | |||
#[macro_use] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: please just append this test case to macro.rs
.
I've tried to fix all comments now. I have one thing that needs to be decided on before completing this. |
Looks good! Yes, I don't want to release this without forcing namespacing, but I think it would be nice to merge this into master now so that we can then take the next step separately. Okay? |
That's fine with me. |
Now when I think more about this I don't think this is a place where it's worth it to divert from Jinja. There is still a need to express the same intent so just swapping words seems like a bad idea. |
What about doing the same thing as tera ?
|
Does tera do something magic with extensions? I definitely wouldn't want that. Using |
Yeah, I don't like the magic extension thingy either (I'm not sure if it's even needed anymore), I just copy/pasted it from one of my templates. I like the |
I like |
Looks like we have consensus on the scoped import syntax. I merged the base part already, since it seems to provide a good basis already. |
@larros are you still up for finishing the implementation of the |
I have some time tomorrow so I can make a try. |
Was the "import as" syntax shown above, with the
If I try to build, I get |
@jmafc look at the code from one of the test cases:
In other words, it should be |
@djc Thanks |
This is a try at an implementation of #40.
I've intentionally kept this as limited as possible because I'm not sure what functionality that should be included. Compared to Jinja there's no support for "import as" or "from import", instead all macros are added to the same namespace.
I first tried to implement this in generator.rs as some combination of the include and macro functionality but I couldn't get that past the borrow checker. The macros need to exist for the full generation and because they contain slices of the imported sources the imports need to be parsed before the generation starts. In the end I put the ownership of the imported sources and nodes in lib.rs in the same way as for the parent template.