V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
612
V2EX  ›  问与答

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

  •  
  •   612 · 2018-04-18 10:13:44 +08:00 · 1196 次点击
    这是一个创建于 2266 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想用纯 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 呢,还是需要修改我的构建模板的方法?

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3165 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 00:42 · PVG 08:42 · LAX 17:42 · JFK 20:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.