V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
612
V2EX  ›  问与答

jinja2 如何在一个模板引入另一个模板中的 block?

  •  
  •   612 · Apr 18, 2018 · 1470 views
    This topic created in 2938 days ago, the information mentioned may be changed or developed.

    我想用纯 jinja2 (不用框架)做一个输出以文章形式为主体的网页模板,有一个基础的骨架 base.html,有大量的章节,这些章节会自由组合放入骨架中,如果这些章节用 macro 放将会很麻烦,因为章节中有一些重复使用的图片表格元素也需要放在 macro 中,但是这些章节用 block 也很不好办,因为 block 不能用 import 引入骨架并且还不能传参数。 我在网上看到好像可以用 template 的.blocks 属性调用 block,所以有了以下尝试:

    #config.json
    {"templates":[
            {"title":"chapter1",
            "children":[
                    {"title":"chapter1_1","template":"template1.html","block":"block1"},
                    {"title":"chapter1_2","template":"template2.html","block":"block1","parameter":{"note":"hello world"}},
            ]},
            {"title":"chapter2","template":"template1.html","block":"block2","parameter":{"note":"blabla"}}
    ]}
    
    
    #base.html
    {% from "component.html" import common_table as common_table with context %}
    {% from "component.html" import common_img as common_img with context %}
    {%- for chapter in chapter_list %}
            {%- set ch_loop = loop %}
            <h2>{{ ch_loop.index }}&nbsp;{{ chapter.title }}</h2>
            {%- if chapter.children %}
                    {%- for section in chapter.children %}
                            <h3>{{ ch_loop.index }}.{{ loop.index }}&nbsp;{{ section.title }}</h3>
                            {% import section.template as template with context %}
                            {% set parameter=section.parameter %}
                            {{ template.blocks[section.block] }}
                    {%- endfor %}
            {%- else %}
                    {% import chapter.template as template with context %}
                    {% set parameter=chapter.parameter %}
                    {{ template.blocks[chapter.block] }}
            {%- endif %}
    {%- endfor %}
    
    #template1.html 
    {% block block1 %}
            I am block 1
            {{ common_table(id="table1",head="nohead")  }}
            {{ common_img(src="css/icon/icon1.png")  }}
    {% endblock %}
    
    {% block block2 %}
            I am block 2
            {{ common_img(src="css/icon/icon2.png")  }}
            {% if parameter.note=="blabla" %}
                    {{ "blabla~blabla~" }}
            {% endif %}
    {% endblock %}
    
    #component.html
    {% macro common_table(id, name,note, head="onehead") %}
            {% if name %}
                    <b class="tablename">{{ name }}</b>
            {% endif %}
            <table id="{{ id }}" class=" {{ head }}"></table>
            {% if note %}
                     <p class="tablenote">{{ note }}</p>
            {% endif %}
    {% endmacro %}
    
    {% macro common_img(src, alt, name) %}
            <img  src="{{ src }}" alt="{{ alt }}">
            {% if name %}
                    <b class="imgname">{{ name }}</b>
            {% endif %}
    {% endmacro %}
    

    但是 jinja2 报了以下错误:

    jinja2.exceptions.UndefinedError: 'jinja2.environment.TemplateModule object' has no attribute 'blocks'
    

    我查看了 jinja2 的源代码,发现在 python 脚本中好像可以用.blocks 属性调用 Template 对象的 block,但是在模板中不行,因为模板中 import 进来的是 TemplateModule class,这个类没有 blocks 属性,好像也不输出 block。那么请问我该如何在骨架中引入 block 呢,还是需要修改我的构建模板的方法?

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1006 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 18:06 · PVG 02:06 · LAX 11:06 · JFK 14:06
    ♥ Do have faith in what you're doing.