显示组合但未渲染的Jinja模板

时间:2019-11-11 21:00:27

标签: python jinja2

我想将所有模板(不确定是否合适)编译为“原始”或未解析/渲染的模板进行显示。

我尝试使用更改variable_start_stringvariable_end_string的方法部分起作用,但是呈现了其他类型的块(例如{% for %}

例如,给定两个模板:

模板parent.j2

some text
{% for x in y %}
 {{ x }}
{% endfor %}
{% include 'child.j2' %}

模板child.j2

{% set things to [0,1,2] %}
{% for thing in things %}
 {{ thing }}
{% endfor %}

我想将它们输出为:

some text
{% for x in y %}
 {{ x }}
{% endfor %}
{% set things to [0,1,2] %}
{% for thing in things %}
 {{ thing }}
{% endfor %}

充其量,我可以使用类似的东西:

def combine_without_render(self, template):
        env = Environment(
            loader=FileSystemLoader(self.template_dir),
            variable_start_string='{[(*&',
            variable_end_string='&*)]}'
        )
        template = env.get_template(template)
            return template.render()

得到类似的东西

 {{ x }}
 {{ thing }}

2 个答案:

答案 0 :(得分:1)

我认为您可以使用{%raw%}。

{% raw %}

some text 
{% for x in y %} 
{{ x }} 
{% endfor %} 
{% endraw %}
{% include 'child.j2' %}

编辑: 如我所见,它有效:

parent.j2:

{% raw -%}
some text
{% for x in y %}
 {{ x }}
{% endfor %}
{% endraw -%}
{% include 'child.j2' %}

child.j2:

{% raw -%}
{% set things to [0,1,2] %}
{% for thing in things %}
 {{ thing }}
{% endfor %}
{% endraw -%}

Python:

import jinja2

templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "parent.j2"
template = templateEnv.get_template(TEMPLATE_FILE)
print(template.render())

输出:

some text
{% for x in y %}
 {{ x }}
{% endfor %}
{% set things to [0,1,2] %}
{% for thing in things %}
 {{ thing }}
{% endfor %}


答案 1 :(得分:0)

用另一种方法回答我自己的问题。这似乎运作良好,但类似于先前的答案,仅限于包含。对于环境,这确实需要relative imports,并且要在所有包含内容及其相对于基本环境的路径之前加上前缀:

parent.j2

some text
{% include "/sub_dir/child.j2" %}

在每个文件上递归调用它,直到到达末尾,然后输出一个字符串:

def _build_stream(self, base_template):
        """
        Recursive method to build an unrendered single template from all
        sub templates included.
        """

        parent = False

        if self._stream_out is None:
            self._stream_out = [] # The final output stream
            parent = True  #When recursion is finished, we can post-process the output


        # This match would need to be changed if you want to include something other
        # than {% include "x" %}
        include_re = re.compile('^.*\{\%\s+include\s+\"/(.*)\".*$', re.IGNORECASE)


        # Open the base template and then recurse through any includes
        # If one is found, call the same method
        # If a line doesnt' match the regex, put it in the stream output

        with open(os.path.join(self.template_dir,base_template), 
                                'r') as base_fh:
            base_template = base_fh.readlines()

        for b_line in base_template:
            b_line.rstrip()
            matches = include_re.match(b_line)
            if matches is not None:
                self._build_stream(os.path.join(
                    self.template_dir, matches.group(1)
                ))
            else:
                self._stream_out.append(b_line)

        if parent is True:
            # If this is the top-level, join the lines for printing

            output =  '\n'.join(self._stream_out)
            self._stream_out = None
            return output

超级hacky,但是可以。