Jinja2不渲染块

时间:2015-03-30 15:41:36

标签: python flask jinja2 html-rendering

我正在阅读一个烧瓶教程,并希望使用flask创建一个博客。为此,我从教程中获取了一些代码并自己编写了一些代码。问题是,Jinja2模板引擎似乎只渲染了我在模板中声明的一些块,我不知道为什么。

这是我到目前为止所得到的:

base.html文件:

<html>
<head>
    {% if title %}
    <title>{{ title }} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
</head>
<body>
    {% with messages = get_flashed_messages() %}
        {% if messages %}
        <ul>
        {% for message in messages %}
            <li>{{ message }}</li>
        {% endfor %}
        </ul>
        {% endif %}
    {% endwith %}

    <p>---</p>
    {% block header %}{% endblock %}
    <p>---</p>
    {% block navigation %}{% endblock %}
    <!-- other templates can insert themselves as block -->
    <!-- the following block ist called 'content' -->
    {% block content %}{% endblock %}
</body>

现在有一些块,它们扩展了base.html:

的index.html:

{% extends "base.html" %}
{% block content %}
<h1>Hi, {{ users.nickname }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
{% endblock %}

header.html中:

{% extends "base.html" %}
{% block header %}
<!-- this is the header block -->
<h1>Microblog!</h1>
{% endblock %}

navigation.html(从另一个css下拉菜单教程中复制):

{% extends "base.html" %}
{% block navigation %}
<nav id="nav">
<ul id="navigation">
    <li><a href="#" class="first">Home</a></li>
    <li><a href="#">Services &raquo;</a>
        <ul>
            <li><a href="#">Web Development</a></li>
            <li><a href="#">Logo Design</a></li>
            <li><a href="#">Identity & Branding &raquo;</a>
                <ul>
                    <li><a href="#">Business Cards</a></li>
                    <li><a href="#">Brochures</a></li>
                    <li><a href="#">Envelopes</a></li>
                    <li><a href="#">Flyers</a></li>
                </ul>                   
            </li>                   
            <li><a href="#">Wordpress</a></li>
        </ul>
    </li>
    <li><a href="#">Portfolio &raquo;</a>
        <ul>
            <li><a href="#">Graphic Design</a></li>
            <li><a href="#">Photography</a></li>
            <li><a href="#">Architecture</a></li>
            <li><a href="#">Calligraphy</a></li>
            <li><a href="#">Film &raquo;</a>
                <ul>
                    <li><a href="#">John Carter</a></li>
                    <li><a href="#">The Avengers</a></li>
                    <li><a href="#">The Amazing SpiderMan</a></li>
                    <li><a href="#">Madagascar 3</a></li>
                </ul>                       
            </li>
            <li><a href="#">Graffity </a></li>
        </ul>               
    </li>
    <li><a href="#">Testimonials</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#" class="last">Contact</a></li>
</ul>
</nav>
{% endblock %}

但是,浏览器中生成的源代码是:

<html>
<head>

    <title>Home - microblog</title>

</head>
<body>




    <p>---</p>

    <p>---</p>

    <!-- other templates can insert themselves as block -->
    <!-- the following block ist called 'content' -->


<h1>Hi, Miguel!</h1>

<div><p>John says: <b>Beautiful day in Portland!</b></p></div>

<div><p>Susan says: <b>The Avengers movie was so cool!</b></p></div>

<div><p>Xiaolong says: <b>Crouching Tiger Hidden Dragon, one of my favorites …</b></p></div>


</body>
</html>

我的views.py就是这样:

from flask import render_template, flash, redirect
from app import app
from .forms import LoginForm

@app.route('/')
@app.route('/index')
def index():
users = {'nickname': 'Miguel'}  # fake user

posts = [  # fake array of posts
    { 
        'author': {'nickname': 'John'}, 
        'body': 'Beautiful day in Portland!' 
    },
    { 
        'author': {'nickname': 'Susan'}, 
        'body': 'The Avengers movie was so cool!' 
    },
    {
        'author': {'nickname': 'Xiaolong'},
        'body': 'Crouching Tiger Hidden Dragon, one of my favorites …'
    }
]

# Flask uses the jinja templating engine internally, which fills in the variables into the template.
# 1.arg: name of the template file in the templates folder
# 2. - x. arg: values for the variables we want to see in the rendered page
return render_template(
    'index.html',
    title='Home',
    users=users,
    posts=posts
)

我做错了什么?为什么只有index.html中的content块被渲染?

编辑#1:澄清: 预期的结果是Jinja渲染模板中的所有提到的块和基本模板以及Jinja在模板/块中看到的所有其他块。

编辑#2:将块放入index.html: 即使将块放入index.html,它也不会渲染它们:

{% extends "base.html" %}
{% block content %}
<p>---</p>
{% block header %}{% endblock %}
<p>---</p>
{% block navigation %}{% endblock %}

<h1>Hi, {{ users.nickname }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
{% endblock %}

1 个答案:

答案 0 :(得分:7)

您正在不同的html文件中实现每个块,但您渲染index.html。当Jinja2告诉它呈现index.html时,它会抓取基本模板(base.html)并查看index.html带来的修改 - 在您的情况下,更新content

在这种情况下,Jinja2甚至不会查看其他块实现(换句话说其他html文件)。你想要的是实现标题/导航/等。在base.html本身。模板引擎只查看当前渲染的模板的继承链,它不会为每个渲染操作加载所有现有模板。

编辑:在评论中进行讨论,但如果其他人遇到此问题则更新此处:如果要从不同文件中呈现不同的部分,请使用{%include <template> %}指令,而不是块。< / p>