在Flask中使用Jinja2进行模板制作:高级

在这个由三部分组成的教程系列的第一部分中,我们了解了如何使用Jinja2在基于Flask的应用程序中布局模板结构。 我们还看到了如何使用块来利用模板中的继承。 在这一部分中,我们将介绍如何编写自定义过滤器,自定义上下文处理器和宏。

入门

我将在本系列第一部分中创建的目录应用程序的基础上进行构建。 首先,我将添加一个自定义的Jinja2上下文处理器,以显示每个产品的描述性名称。 然后,我将创建一个自定义的Jinja2筛选器,以执行与自定义上下文处理器相同的工作。 然后,我将演示如何为常规表单字段创建自定义Jinja2宏。

创建一个自定义的Jinja2上下文处理器

有时,我们可能想直接在模板中计算或处理一个值。 Jinja2坚持认为逻辑处理应该在视图中而不是模板中进行处理,因此可以使模板保持干净。 在这种情况下,上下文处理器将成为一种方便的工具。 我们可以将值传递给方法; 然后将其以Python方法进行处理,并将返回我们的结果值。 因此,我们实际上只是在模板上下文中添加一个函数(这要感谢Python允许我们像传递其他任何对象一样传递函数)。

因此,假设我们要为每个产品添加一个描述性名称,格式为Category / Product-name 。 为此,需要添加一个方法,该方法必须使用@app.context_processor 装饰

@app.context_processor
def some_processor():
    def full_name(product):
        return '{0} / {1}'.format(product['category'], product['name'])
    return {'full_name': full_name}

从技术上讲,上下文只是Python字典,可以对其进行修改以添加和删除值。 具有指定装饰器的任何方法都应返回将更新当前应用程序上下文的字典。

要使用此上下文处理器,只需在模板中添加以下Jinja2标记。

<h4>{{ full_name(product) }}</h4>

如果将其添加到应用程序的flask_app/templates/product.html中,它将类似于:

{% extends 'home.html' %}

{% block container %}
  <div class="top-pad">
    <h4>{{ full_name(product) }}</h4>
    <h1>{{ product['name'] }}
      <small>{{ product['category'] }}</small>
    </h1>
    <h3>$ {{ product['price'] }}</h3>
  </div>
{% endblock %}

生成的产品页面现在看起来像:

单个产品页面示例

创建一个自定义的Jinja2过滤器

看完上面的示例后,有经验的开发人员可能会认为使用上下文处理器来达到目的是愚蠢的。 只需编写一个过滤器即可获得相同的结果。 这将使事情变得更加清洁。 可以编写一个过滤器以显示产品的描述性名称,如下所示。

@app.template_filter('full_name')
def full_name_filter(product):
    return '{0} / {1}'.format(product['category'], product['name'])

可以像使用普通过滤器一样使用此过滤器,即通过添加| (pipe) | (pipe)符号,然后是过滤器名称。

{{ product|full_name }}

上面的过滤器将产生与上下文处理器不久前展示的结果相同的结果。

为了使事情更上一层楼,让我们创建一个过滤器,该过滤器将根据当前浏览器的本地语言来格式化货币。 为此,首先我们需要安装一个名为ccy的Python包。

$ pip install ccy

现在我们需要为货币过滤器添加一个方法。

import ccy
from flask import request

@app.template_filter('format_currency')
def format_currency_filter(amount):
    currency_code = ccy.countryccy(request.accept_languages.best[-2:])
    return '{0} {1}'.format(currency_code, amount)

要使用此过滤器,我们需要在模板中添加以下内容:

<h3>{{ product['price']|format_currency }}</h3>

现在产品页面如下所示:

在单个产品页面上格式化货币

为表单创建自定义Jinja2宏

宏允许我们编写可重用HTML块。 它们类似于常规编程语言中的函数。 我们可以像在Python中对函数进行传递那样将参数传递给宏,然后使用它们来处理HTML块。 宏可以被调用任意次,并且输出将根据它们内部的逻辑而变化。 在Jinja2中使用宏是非常常见的主题,并且有很多用例。 在这里,我们将看到导入后如何创建和使用宏。

HTML中最冗余的代码之一是在表单中定义输入字段。 大多数字段具有类似的代码,但对样式进行了一些修改等等。 下面是一个宏,在调用时会创建输入字段。 最佳做法是在单独的文件中创建宏,以提高重用性,例如_helpers.html

{% macro render_field(name, class='', value='', type='text') -%}
    <input type="{{ type }}" name="{{ name }}" class="{{ class }}" value="{{ value }}"/>
{%- endmacro %}

现在,应将此宏导入要使用的文件中:

{% from '_helpers.jinja' import render_field %}

然后,可以使用以下命令简单地调用它:

<fieldset>
    {{ render_field('username', 'icon-user') }}
    {{ render_field('password', 'icon-key', type='password') }}
</fieldset>

在另一个文件中定义宏始终是一个好习惯,以保持代码干净并提高代码可读性。 如果需要无法从当前文件中访问的专用宏,请在名称前加上下划线来命名该宏。

结论

在本教程中,我们看到了如何为表单编写自定义过滤器,自定义上下文处理器和自定义宏。 在本系列的下一部分中,我们将看到如何使用moment.js在Jinja2中的模板级别实现高级日期和时间格式。

翻译自: https://code.tutsplus.com/tutorials/templating-with-jinja2-in-flask-advanced--cms-25794

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值