• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

在Flask中使用Jinja2进行模板化:要点

jinja2是一个用纯 python 编写的模板引擎。它提供受 Django启发的非 XML 语法,但支持内联表达式和可选的沙盒 环境。除了是一个易于使用的独立模板引擎之外,它体积小但速度快。 flask 是一个基于 Python 的微型 Web框架,可让您快速高效地编写 Web 应用程序

在这个由三部分组成的系列中,我将从Flask 的角度介绍jinja2模板的基础知识。在本系列的后续部分中,我将介绍高级模板主题,同时学习如何在基于 Flask 的应用程序中以模块化和可扩展的设计布局模板。

我假设您对 Flask 和使用 virtualenv的环境设置最佳实践有基本的了解, 在开发 Python 应用程序时要遵循。

安装包

Flask 与 Jinja2 一起打包,因此我们只需要安装 Flask。对于本系列,我建议使用 Flask 的开发版本,它包括更稳定的命令行支持以及许多其他功能和对 Flask 的总体改进。

pip install https://github.com/mitsuhiko/flask/tarball/master

需要模板引擎?

在 Flask 中,我们可以编写一个完整的 Web 应用程序,而不需要任何第三方模板引擎。让我们看一下Hello World下面的一个小应用程序:

from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
@app.route('/hello')
@app.route('/hello/<user>')
def hello_world(user=None):
    user = user or 'Shalabh'
    return '''
    <html>
        <head>
            <title>Templating in Flask</title>
        </head>
        <body>
            <h1>Hello %s!</h1>
            <p>Welcome to the world of Flask!</p>
        </body>
    </html>''' % user
        
if __name__ == '__main__':
    app.run()

很明显,上述编写应用程序的模式在 HTML、 css和 JS 代码在数千行代码范围内的真实 Web 应用程序中是不可行的。在这里,模板可以节省我们的时间,因为我们可以通过将模板分开来构造我们的视图代码。Flask 默认提供对 Jinja2 的支持,但任何其他模板引擎也可以根据需要使用。

布置模板

默认情况下,Flask期望将模板放置在以templates应用程序根级别命名的文件夹中。然后,Flask 通过使该文件夹可用于该render_template()方法来自动读取内容。我将通过重新构建上面显示的琐碎应用Hello World程序来证明这一点。

应用程序结构如下所示。

flask_app/
    my_app.py    
    templates/
        - index.html

应用程序本身

烧瓶应用程序/my_app.py

from flask import Flask, render_template, request
 
app = Flask(__name__)
 
@app.route('/')
@app.route('/hello')
@app.route('/hello/<user>')
def hello_world(user=None):
    user = user or 'Shalabh'
    return render_template('index.html', user=user)

flask_app/templates/index.html

<html>
  <head>
    <title>Templating in Flask</title>
  </head>
  <body>
    <h1>Hello {{ user }}!</h1>
    <p>Welcome to the world of Flask!</p>
  </body>
</html>

要运行应用程序,只需在命令行上执行以下命令:

flask --app=my_app run

在浏览器中打开 http://127.0.0.1:5000/ 以查看正在运行的应用程序。在http://127.0.0.1:5000/hello的情况下,结果也是一样的  。

在Flask中使用Jinja2进行模板化:要点  第1张尝试以您的姓名作为最后一部分打开 URL。因此,如果您的名字是 John,那么 URL 将是 http://127.0.0.1:5000/hello/John。现在页面看起来像这样:

在Flask中使用Jinja2进行模板化:要点  第2张很简单,在该方法hello_world 中,URL after 的最后一部分hello 是从请求中获取的,并传递给正在渲染的模板的上下文render_template()。然后使用 Jinja2 占位符从模板上下文中解析该值{{ user }}。此占位符根据模板上下文评估放置在其中的所有表达式。

了解模板中的块和继承

通常,任何 Web 应用程序都会有许多彼此不同的网页。页眉和页脚等代码块在整个站点的几乎所有页面中都是相同的。同样,菜单也保持不变。事实上,通常只有中心容器块发生变化,其余部分通常保持不变。为此,Jinja2 提供了一种很好的模板间继承方式。拥有一个基本模板是一个很好的做法,我们可以在其中构建网站的基本布局以及页眉和页脚。

我将创建一个小应用程序来展示不同类别下的产品列表。对于样式,我将使用 Bootstrap框架为模板提供基本设计。应用程序结构现在如下图所示。

flask_app/
    my_app.py    
    templates/
        - base.html
        - home.html
        - product.html
    static/
        css/
            - bootstrap.min.css
            - main.css
        js/
            - bootstrap.min.js

在这里 static/css/bootstrap.min.css,static/js/bootstrap.min.js可以从上面提到的引导网站下载。其余的应用程序代码如下所示。

烧瓶应用程序/my_app.py

from flask import Flask, render_template, abort
 
app = Flask(__name__)
 
PRODUCTS = {
    'iphone': {
        'name': 'iPhone 5S',
        'category': 'Phones',
        'price': 699,
    },
    'galaxy': {
        'name': 'Samsung Galaxy 5',
        'category': 'Phones',
        'price': 649,
    },
    'ipad-air': {
        'name': 'iPad Air',
        'category': 'Tablets',
        'price': 649,
    },
    'ipad-mini': {
        'name': 'iPad Mini',
        'category': 'Tablets',
        'price': 549
    }
}
 
@app.route('/')
@app.route('/home')
def home():
    return render_template('home.html', products=PRODUCTS)
 
@app.route('/product/<key>')
def product(key):
    product = PRODUCTS.get(key)
    if not product:
        abort(404)
    return render_template('product.html', product=product)

在这个文件中,我对产品列表进行了硬编码,以使应用程序更简单,并且只关注模板部分。我创建了两个端点, home和 product,前者用于列出所有产品,后者打开单个页面。

flask_app/static/css/main.css

body {
  padding-top: 50px;
}
.top-pad {
  padding: 40px 15px;
  text-align: center;
}

这个文件包含一些我添加的自定义 CSS 以使模板更清晰。现在让我们看看模板。

flask_app/templates/base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Jinja2 Tutorial - Tutsplus</title>
    <link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
    <link href="{{ url_for('static', filename='css/main.css') }}" rel="stylesheet">
  </head>
  <body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="{{ url_for('home')}}">Tutsplus - Jinja2 Tutorial</a>
        </div>
      </div>
    </div>
    <div class="container">
      {% block container %}{% endblock %}
    </div>
    <!-- jquery (necessary for Bootstrap's javascript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
  </body>
</html>

请注意 url_for()用于为静态文件和其他链接创建 URL。它是 Flask 提供的一个非常方便的工具。在文档中阅读有关此内容的更多信息 。这里要注意的另一个重点是 的使用 {% block container %}{% endblock %},这是 Jinja2 致力于使模板模块化和可继承的非常重要的组件。接下来的几个文件将使这一点更清楚。

flask_app/templates/home.html

{% extends 'base.html' %}
 
{% block container %}
  <div class="top-pad">
    {% for id, product in products.iteritems() %}
      <div class="well">
        <h2>
          <a href="{{ url_for('product', key=id) }}">{{product['name'] }}</a>
          <small>$ {{ product['price'] }}</small>
        </h2>
      </div>
    {% endfor %}
  </div>
{% endblock %}

查看此模板如何扩展base.html 并提供 {% block container %}. {% for %}行为就像我们在这里用来创建产品列表的任何语言中的普通 for 循环一样。

flask_app/templates/product.html

{% extends 'home.html' %}
 
{% block container %}
  <div class="top-pad">
    <h1>{{ product['name'] }}
      <small>{{ product['category'] }}</small>
    </h1>
    <h3>$ {{ product['price'] }}</h3>
  </div>
{% endblock %}

上面的模板实现了单个产品页面。

现在通过执行以下命令运行应用程序。

flask --app=my_app run

正在运行的应用程序将如下面的屏幕截图所示。只需  在浏览器中打开http://127.0.0.1:5000/home即可。

在Flask中使用Jinja2进行模板化:要点  第3张

单击任何产品以查看单个产品页面。

在Flask中使用Jinja2进行模板化:要点  第4张

结论

在本教程中,我们了解了如何使用 Jinja2 在基于 Flask 的应用程序中布局模板结构。我们还看到了如何使用块来利用模板中的继承。 


文章目录
  • 安装包
  • 需要模板引擎?
  • 布置模板
  • 应用程序本身
    • 烧瓶应用程序/my_app.py
    • flask_app/templates/index.html
  • 了解模板中的块和继承
    • 烧瓶应用程序/my_app.py
    • flask_app/static/css/main.css
    • flask_app/templates/base.html
    • flask_app/templates/home.html
    • flask_app/templates/product.html
  • 结论