4.2 模板的制作:Jinja2模板中的递归

学习目标

  • 使用jinja2模板的递归方法重构报告生成模板

前期设置

  • 初始化document
  • 定义直接显示jinja2渲染结果的函数render_templ

Recursive Example For Jinja2

首先我们来看一个Jinja2模板的递归例子,需要注意此时的渲染方式有变化,需要提前设置环境。

import jinja2

template = """
{%- set idxs = [0] -%}
{%- for item in sitemap recursive %}
    depth={{idxs|length}}. idx={{loop.index}}. pidx={{idxs[-1]}}. title={{item.title}}
    {%- if item.children -%}
        {%- do idxs.append(loop.index) -%}
        {{ loop(item.children) }}
        {%- do idxs.pop() -%}
    {%- endif %}
{%- endfor %}
"""

class Node():
    def __init__(self, title, children=[]):
        self.title = title
        self.children = children

sitemap = [
    Node('a', [
        Node('a_a', [
            Node('a_a_a'),
            ]),
        Node('a_b', [
            Node('a_b_a', [
                Node('a_b_a_0'),
                ]),
            ]),
        ]),
    Node('b'),
    ]

env = jinja2.Environment(extensions=['jinja2.ext.do'])
print(env.from_string(template).render(sitemap=sitemap))
    depth=1. idx=1. pidx=0. title=a
    depth=2. idx=1. pidx=1. title=a_a
    depth=3. idx=1. pidx=1. title=a_a_a
    depth=2. idx=2. pidx=1. title=a_b
    depth=3. idx=1. pidx=2. title=a_b_a
    depth=4. idx=1. pidx=1. title=a_b_a_0
    depth=1. idx=2. pidx=0. title=b

把之前生成报告的模板改为使用递归的形式

而我们的Docoment类同样是一个树结构,可以进行递归的模板生成。而且每个Chapter和SubChapter都有着类似的结构,可以使用同样的处理方式,所以可以把我们之前的jinja2模板改为:


{{ document.title }}

{{ document.foreword }}

{% for chapter in document.chapters recursive %} {%- if not chapter.title is none %}

{{ chapter.title }}

{%- endif -%} {%- if not chapter.foreword is none %}

{{ chapter.foreword }}

{%- endif -%} {% if not chapter.table is none %} {% set table = chapter.table %} {% for column in table.columns %} {% endfor %} {% for index in table.index %} {% for column in table.columns %} {% endfor %} {% endfor %}
{{column}}
{{ table[column][index] }}
{% endif %} {% if not chapter.image is none %} {% set image = chapter.image %}
{% endif %} {% if not chapter.content is none %}

{{ chapter.content }}

{% endif %} {% if chapter.chapters.__len__() > 0 %} {{ loop(chapter.chapters) }} {% endif %} {% endfor %}

作业

上面的递归会把所有的章标题记录为

,对于更深一层的子章节我们需要使用更小的标签,比如

,这时候就可以使用递归深度来做规定。请自行做出作为练习。
想要直接查看结果可以参照Example_3


你可能感兴趣的:(4.2 模板的制作:Jinja2模板中的递归)