How are django templates handled?

I'm trying to learn more about the Django template engine, as it always seemed to me like a black box. The documentation gives a good overview of the general steps and indicates that the template is loaded and analyzed, creating a tree of nodes to be processed (in cascade?) With context and attached together to give a result.

What I don’t understand is the approach to parsing and by what criteria are nodes created? What is a particular node after parsing and how does this affect the creation of custom template tags (i.e. is there a better and more efficient way to write template tags that will result in fewer nodes?).

+8
django django-templates
source share
4 answers

One way to understand the process is to start django with the werkzeug debugger and throw an exception in the template. This way you can browse (and interact) with the entire stack to this point.

+3
source share

A node is created from each tag. You can understand how this works by reading how to write custom tags . Everything inside the tag will be its child. Here is an example comment tag from django docs:

def do_comment(parser, token): nodelist = parser.parse(('endcomment',)) parser.delete_first_token() return CommentNode() 

as you can see the comment tag will analyze everything up to "endcomment" and will throw it away. Other tags will pass the nodelist to SometagNode() and will use it for rendering.

Rendering is done recursively. When render () is called in node, it renders on its children, etc.

The analysis is also performed recursively, so you can get nested tags, and parser.parse() can find a suitable matching closing tag, because when it parses and stumbles upon a tag, it calls the do_tag() thing, which in turn will call parser.parse() again parser.parse() to find the closest closing tag, and all of this will turn into node, return node, the higher parser.parse () will put it in the node list and continue searching for the closing tag.

The context object in the nodes is a kind of list of dicts structure. An additional context is pushed over the existing context and passed to the child nodes and issued after the node is displayed so that it does not affect the upper area.

For tags that do not have children, parser.parse() not used, so the node instance is returned without any children.

+3
source share

I think the first thing you should pay attention to is code.djangoproject.com with django / template / base.py - the first one (as Yuji Tomita pointed out earlier). Or download sources and browse through them with your favorite editor or IDE.

+2
source share

I assume they use tokenization and parsing

easy way to write:

Tokenizing: Convert the code to types such as:

 integer foo = "bar" + 15; 

it consists of

 T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + T_STRING + T_PLUS + T_DIGIT + T_SEMI 

after that you can analyze trying to find patterns with a parser

parsing:

find the template:

 T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + {A recursive thing} + T_SEMI 

This way you can execute the command

If you like experimenting with this, I could recommend using ANTLR http://www.antlr.org/ It is available in many different languages ​​such as Java or C #, and even PHP and JS

0
source share

All Articles