Matyas
Matyas

Reputation: 13702

Is it possible to load jinja2 templates without having variables replaced?

Suppose we have the following structure

templates/modal.html

<div class="title">
   {% block title %}
   {% endblock %}
</div>
<div class="content">
   {% block content %}
   {% endblock %}
</div>

templates/usermodal.html

{% extends "modal.html" %}
{% block title %}
     Hello {{ user }}
{% endblock %}
{% block content %}
     Some content
     {% include "table.html" %}
{% endblock %}

template/table.html

<table>
   <tr>
      <td>
         {{ data }}
      </td>
   </tr>
</table>

I'd like to return to the client side the following content, to populate it with js/client side templating

<div class="title">
     Hello {{ user }}
</div>
<div class="content">
     Some content
    <table>
      <tr>
        <td>
          {{ data }}
       </td>
      </tr>
    </table>
</div>

So basically what I'm looking for is a method similar to render_template in flask, but which only assembles the template, but doesn't populate/render it with data.

Looking around in the sources, I couldn't find such method.

Do you have any ideas how I could accomplish this?

Upvotes: 1

Views: 2228

Answers (2)

Lord Cloud
Lord Cloud

Reputation: 23

Very late to this question, but I was looking for a solution for this exact problem and couldn't find any.

Originally this answer presented 3 "solutions" for the problem described in the question. But after I played with them some more I've realised that there is something I missed about what we're actually trying to achieve:

According to the original question, we only want to render {% block %} and {% include %} (and maybe {% macro %}) expressions. We can't resolve {% if %} or {% for %} expressions because they require the value of a variable (unless we're using a const, but that is a whole other story).

The "solutions" I presented were trying to render the template completely, including if/for/set/call expressions (and Jinja2 filters), using Jinja2's configurations and internal code. This was not successful because as I mentioned, it makes no sense to resolve {% if A %} when we don't know the value of the variable A.

This leads me to believe that the simplest way to solve this is not by using Jinja2, but by resolving the include and extends blocks using regex:

  1. Find whether this template extends another. If it does, read the original template (this can be done either with open(file_path, 'r') or with Jinja2 get_source() function).

  2. Find all blocks in the original template and replace them in the "parent" template. Repeat steps 1+2 until we reach a template that does not extend another.

  3. Find all {% include %} tags, read the contents of the included files and insert them into the template.

The result: a template where all include and extends were resolved... which as I understand, is what we're after.

Upvotes: 1

reclosedev
reclosedev

Reputation: 9502

You can mark block with raw

{% raw %}
    <div class="title">
         Hello {{ user }}
    </div>
    <div class="content">
         Some content
        <table>
          <tr>
            <td>
              {{ data }}
           </td>
          </tr>
        </table>
    </div>
{% endraw %}

http://jinja.pocoo.org/docs/templates/#escaping

Upvotes: 3

Related Questions