Question

In Jinja2, is it possible to have a Node from the AST render after all include statements have completed?

This is a key piece of a solution to a bigger puzzle.

Example code:

x.py

from jinja2 import nodes, Environment, FileSystemLoader
from jinja2.ext import Extension

class XExtension(Extension):
    tags = set(['x', 'get_x'])

    def __init__(self, environment):
        super(XExtension, self).__init__(environment)
        environment.extend(
            x = 0,
        )

    def parse(self, parser):
        tag = parser.stream.next()
        return getattr(self, "_%s" % str(tag))(parser, tag)

   def _get_x(self, parser, tag):
        """ Return the output """
        return nodes.Const(self.environment.x)

   def _x(self, parser, tag):
        """ Add an x """
        self.environment.x += 1
        return nodes.Const('<!-- Adding an X -->')

env = Environment(
    loader      = FileSystemLoader('.'),
    extensions  = [XExtension],
    )

template = env.get_template('x.html')
print template.render()

x.html

Xx {% x %} Xx {% x %}
{% include "y.html" %}
Xs xes: {% get_x %}

y.html

Yx {% x %}
Ys xes: {% get_x %}

The output is

Xx <!-- Adding an X --> Xx <!-- Adding an X -->
Yx <!-- Adding an X -->
Ys xes:3
Xs xes 2

How may it be possible to have Xs xes count the X's in y.html, which is the behaviour I desire and expect?

In other words, is there a way to delay the parsing or flattening to text returned from the _get_x() in x.html?

Thank you very much for reading.

Kind regards,

Brian

Was it helpful?

Solution

Jinja2 does streaming of template data. The template is evaluated instruction for instruction into a stream of smaller strings that gets concatenated into an actual unicode string by the render() method. However you can also get hold of the stream by calling into generate() instead of render().

With some in-band signalling and postprocessing of the stream one might probably be able to implement something like that, but it's against the way of how Jinja2 was designed so it might break horribly and is totally unsupported.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top