{{ var1 }} {%...">

Is there a python template library that can do "partial rendering"?

Let's say I have the following template:

<!DOCTYPE html> <html> {{ var1 }} {% if var1 and var2 %} <span>some text</span> {% endif %} {{ var2 }} </html> 

When I draw it with var1=3 as a context, it produces this output:

 <!DOCTYPE html> <html> 3 {% if 3 and var2 %} <span>some text</span> {% endif %} {{ var2 }} </html> 

When I again output the result of the first rendering using var2=5 as the context, the output is as follows:

 <!DOCTYPE html> <html> 3 <span>some text</span> 5 </html> 

The problem is that most template engines will evaluate variables that are missing in the context as an empty string. All of them are built on the assumption that there will be only one render.

I know jinja2 can do this with this method: Multiple jinja2 template templates?

But it does not work through an if , it only works for individual variables.

Is there a rendering mode in any of the popular template libraries, for example, as I describe? Mako? Genshi? Something other? Maybe this is a non-python template engine?

+4
source share
1 answer

TL DR

This function does not exist in any template language that I know of. Your best options:

Writing Your Own Template Tag

I think you have a couple of options here, some of which I got from here , although none of them are related to the built-in capabilities of template systems. Basically, the goal here would be to visualize the output, which again includes template tags.

As I see it, the easiest way would be to use the templatetag templatetag tag or write your own, which does something similar and takes care of the escape.

If you have reliably rendered var1 and var2 second:

 <!DOCTYPE html> <html> {{ var1 }} {% templatetag openblock %} if {{ var1 }} and var2 {% templatetag closeblock %} <span>some text</span> {% templatetag openblock %} endif {% templatetag closeblock %} {% templatetag openvariable %} var2 {% templatetag closevariable %} </html> 

When you first render, you will get:

 <!DOCTYPE html> <html> {{ 3 }} {% if 3 and var2 %} <span>some text</span> {% endif %} {{ var2 }} </html> 

Which in the second rendering will lead to the desired result.

Obviously, constantly writing multiple layers {% templatetag %} will be a huge pain, so I would suggest writing your own recursive template tag that will take care of this for you, perhaps with an argument that determines how many layers of nesting you need, and then , obviously, an argument for the entry itself. The best part is, if you need only one nesting layer, since the template tag simply displays the input, it will work,

Basically, because this custom template tag displays itself recursively, you can achieve as many nesting layers as you need quite easily. Assuming the tag was implemented as {% t <layers of nesting> <input> %} :

  Initial template: {% t 2 "{{var2}}"%}
     First rendering: {% t 1 "{{var2}}"%}
     Second rendering: {{var2}}
     Final rendering: 5

Now it will be harder for some more complex tags, such as {% if %} , for sure, especially if in your example you have several rendering levels needed in a single if statement. You might be better off separating your if statements so that you have a clear separation of rendering. The following example assumes the implementation of the {% t %} tag, which uses the combination {% t %} / {% endt %} :

Initial HTML:

 {% if var1 %} {% t 1 %} {% if var2 %} <span>some text</span> {% endif %} {% endt %} {% endif %} 

First render:

 {# Note that the first if statement has been evaluated and is gone #} {% if var2 %} <span>some text</span> {% endif %} 

Final Rendering:

 <span>some text</span> 
+4
source

All Articles