Jinja2的宏功能有些类似于传统程序语言中的函数,既然是函数就有其声明和调用两个部分。
先声明一个宏:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% macro input(name,type='text',value='') %} <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> {% endmacro %} {#代码中,宏的名称就是”input”,它有三个参数分别是”name”, “type”和”value”,后两个参数有默认值。#} </body> </html>
代码中,宏的名称就是”input”,它有三个参数分别是”name”, “type”和”value”,后两个参数有默认值。现在,让我们使用表达式来调用这个宏:
在上面代码中加入如下代码:
<p>{{ input('username',value='user') }}</p> <p>{{ input('password','password') }}</p> <p>{{ input('submit','submit','submit') }}</p>
定义路由,把页面配置进入路由后,访问在页面上看到一个文本输入框,一个密码输入框及一个提交按钮。
宏的复用
{% from "macro.html" import input %}
引用需要复用的宏文件macro.html,然后调用宏内容,代码如下:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% from "macro.html" import input %} <p>{{ input('username',value='user') }}</p> <p>{{ input('password','password') }}</p> <p>{{ input('submit','submit','submit') }}</p> </body> </html>
访问调用者内容
我们先创建一个macrouser_list.html文件,代码如下:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% macro user_list(users) %} <table> <tr><th>Name</th><th>Sex</th><th>Age</th><th>Action</th></tr> {% for user in users %} <tr><td>{{ user.name }}</td><td>{{ user.gender }}</td><td>{{ user.age }}</td><td>{{ caller() }}</td></tr> {% endfor %} </table> {% endmacro %} </body> </html>
我们还是在usemacro.html文件中设置调用者内容,代码如下:
{% from "macrouser_list.html" import user_list %} {% set users=[{'name':'Tom','gender':'Boy','age':'26'}, {'name':'Jim','gender':'Boy','age':'25'}, {'name':'Lucy','gender':'Girl','age':'23'}, {'name':'Lida','gender':'Girl','age':'22'}] %} _______________________________________________________________ {% call user_list(users) %} {% endcall %} ________________________________________________________________ {% call user_list(users) %} <input name="delete" type="delete" value="delete"> {% endcall %} ____________________________________________________________ {% for user in users %} <tr><td>{{ user.name }}</td><td>{{ user.gender }}</td><td>{{ user.age }}</td><td><input name="delete" type="delete" value="delete"></td></tr> {% endfor %}
访问:http://127.0.0.1:5000/usemacro,可以看到结果。
与上例不同,这里我们使用了”{% call %}”语句块来调用宏,语句块中包括了一段生成”Delete”按钮的代码。运行下试试,你会发现每个用户名后面都出现了”Delete”按钮,也就是”{{ caller( ) }}”部分被调用者”{% call %}”语句块内部的内容替代了。不明觉厉吧!其实吧,这个跟函数传个参数进去没啥大区别,个人觉得,主要是有些时候HTML语句太复杂(如上例),不方便写在调用参数上,所以就写在”{% call %}”语句块里了。
Jinja2的宏不但能访问调用者语句块的内容,还能给调用者传递参数。们来扩展下上面的例子。首先,我们将表格增加一列性别,并在宏里调用”caller()”方法时,传入一个变量”user.gender”:
{% macro list_users(users) -%} <table> <tr><th>Name</th><th>Gender</th><th>Action</th></tr> {%- for user in users %} <tr><td>{{ user.name |e }}</td>{{ caller(user.gender) }}</tr> {%- endfor %} </table> {%- endmacro %}
然后,我们修改下调用者语句块:
{% call(gender) list_users(users) %} <td> {% if gender == 'M' %} <img src="{{ url_for('static', filename='img/male.png') }}" width="20px"> {% else %} <img src="{{ url_for('static', filename='img/female.png') }}" width="20px"> {% endif %} </td> <td><input name="delete" type="button" value="Delete"></td> {% endcall %}
大家注意到,我们在使用”{% call %}”语句时,将其改为了”{% call(gender) … %}”,这个括号中的”gender”就是用来接受宏里传来的”user.gender”变量。因此我们就可以在”{% call %}”语句中使用这个”gender”变量来判断用户性别。这样宏就成功地向调用者传递了参数。
宏的内部变量
上例中,我们看到宏的内部可以使用”caller( )”方法获取调用者的内容。此外宏还提供了两个内部变量:
- varargs
这是一个列表。如果调用宏时传入的参数多于宏声明时的参数,多出来的没指定参数名的参数就会保存在这个列表中。
- kwargs
这是一个字典。如果调用宏时传入的参数多于宏声明时的参数,多出来的指定了参数名的参数就会保存在这个字典中。
让我们回到第一个例子input宏,在调用时增加其传入的参数,并在宏内将上述两个变量打印出来:
{% macro input(name, type='text', value='') -%} <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}"> <br /> {{ varargs }} <br /> {{ kwargs }} {%- endmacro %} <p>{{ input('submit', 'submit', 'Submit', 'more arg1', 'more arg2', ext='more arg3') }}</p>
可以看到,varargs变量存了参数列表”[‘more arg1’, ‘more arg2’]”,而kwargs字典存了参数”{‘ext’:’more arg3′}”。
宏的导入
一个宏可以被不同的模板使用,所以我们建议将其声明在一个单独的模板文件中。需要使用时导入进来即可,而导入的方法也非常类似于Python中的”import”。让我们将第一个例子中”input”宏的声明放到一个”form.html”模板文件中,然后将调用的代码改为:
{% import 'form.html' as form %} <p>{{ form.input('username', value='user') }}</p> <p>{{ form.input('password', 'password') }}</p> <p>{{ form.input('submit', 'submit', 'Submit') }}</p>
包含 (Include)
这里我们再介绍一个Jinja2模板中代码重用的功能,就是包含 (Include),使用的方法就是”{% include %}”语句。其功能就是将另一个模板加载到当前模板中,并直接渲染在当前位置上。它同导入”import”不一样,”import”之后你还需要调用宏来渲染你的内容,”include”是直接将目标模板渲染出来。它同block块继承也不一样,它一次渲染整个模板文件内容,不分块。
我们可以创建一个”footer.html”模板,并在”layout.html”中包含这个模板:
<body> ... {% include 'footer.html' %} </body>
当”include”的模板文件不存在时,程序会抛出异常。你可以加上”ignore missing”关键字,这样如果模板不存在,就会忽略这段”{% include %}”语句。
{% include 'footer.html' ignore missing %}
“{% include %}”语句还可以跟一个模板列表:
{% include ['footer.html','bottom.html','end.html'] ignore missing %}
上例中,程序会按顺序寻找模板文件,第一个被找到的模板即被加载,而其后的模板都会被忽略。如果都没找到,那整个语句都会被忽略。
相关推荐
**FLask学习笔记源(1)源码 demo1.rar** 这个压缩包文件是关于Python Flask框架的学习资源,其中包含了创建一个简单的个人博客系统的源代码。`demo1`是压缩包内的主要子文件,通常它会包含一系列的Python文件,如...
**FLask学习笔记(2)源码分析** 在Python Web开发领域,Flask是一个轻量级、灵活且强大的Web框架。本笔记将深入探讨在Flask框架中进行开发的一些核心概念和技术,通过分析"demo2"这个源码实例,帮助读者更深入地...
在本篇Flask学习笔记(10)中,我们将深入探讨Python Web开发框架Flask的高级用法和核心概念。Flask是一个轻量级、灵活的框架,它以简洁的API和可扩展性赢得了开发者们的喜爱。让我们一起探索Flask的魅力。 首先,`...
**Flask学习笔记(5)源码** 在深入探讨Flask框架的源码之前,我们先来了解一下Flask的基本概念。Flask是一个轻量级的Web服务器网关接口(WSGI)微框架,由Armin Ronacher开发。它以其简单易用、高度可扩展性而受到...
**Flask学习笔记8源码解析** 在Python的Web开发领域,Flask是一个轻量级且灵活的框架,因其简洁的API和强大的扩展性而受到开发者喜爱。本篇笔记将深入探讨Flask的核心概念和常见用法,通过分析"demo8"这个压缩包中...
在本篇Flask学习笔记(9)中,我们将深入探讨Flask框架的源码,重点关注其核心概念和组件,特别是与Python蓝图(Blueprint)相关的部分。Flask是Python中的一个轻量级Web服务程序,它以其简洁、灵活的特性深受开发者...
在本篇Flask学习笔记(6)中,我们将深入探讨Flask这个轻量级的Python Web框架。Flask以其简洁的API和高度可扩展性深受开发者喜爱,它允许开发者用少量代码实现功能丰富的Web应用。以下是对源码的详细解析。 首先,...
在本篇Flask学习笔记(3)中,我们将深入探讨Flask框架的源码,以增强我们对这个轻量级Python Web服务器网关接口(WSGI)应用框架的理解。Flask以其简洁、易于上手的特性深受开发者喜爱,是构建小型到中型Web应用的...
在本篇Flask学习笔记(4)中,我们将深入探讨Python的微框架——Flask,它以其轻量级、灵活性和强大的扩展性深受开发者喜爱。Flask是构建Web应用的理想选择,尤其适合初学者和小型项目。以下是笔记的主要内容: 1. ...
Flask 使用 Jinja2 作为其默认的模板引擎。模板允许你在 HTML 文件中嵌入 Python 代码,从而动态生成内容。例如: ```html <!-- templates/index.html --> <h1>{{ message }} {% for item in items %} <li>{...
1. Jinja2模板引擎:Flask默认集成Jinja2,用于动态生成HTML。 2. 模板文件结构:在项目目录下创建`templates`文件夹存放模板。 3. 变量传递:在视图函数中,通过`return render_template("模板名", var1=value1, ...
Jinja2提供了诸如变量、控制流、过滤器、宏等强大的功能。学习笔记会涵盖如何在模板中使用这些元素,以及如何组织和继承模板。 3. **表单处理与验证**:Flask-WTF扩展允许开发者方便地处理Web表单,包括表单的创建...
3. 模板引擎Jinja2的使用,涉及模板变量、过滤器、选择结构、循环、宏、消息闪现和静态文件加载。 4. 数据库操作,包括模型定义、数据的CRUD操作。 通过深入学习和实践,学生将具备使用Flask框架独立开发Web应用的...
3. **模板引擎 Jinja2**: Flask 默认集成 Jinja2,这是一个强大的 HTML 模板引擎,允许开发者在后端代码中插入动态内容。例如,我们可以创建一个 `templates` 文件夹,其中包含一个 `index.html` 文件,用于渲染视图...
Flask自身并不内置模板引擎或ORM(对象关系映射),而是依赖于社区提供的扩展来实现这些功能,如Jinja2用于模板渲染,SQLAlchemy用于数据库操作。 Flask的核心概念包括: 1. **应用程序上下文(Application Context...
6. **模板引擎**:Flask使用Jinja2作为默认的模板引擎,用于生成HTML页面。开发者可以在模板中插入动态内容,如用户信息和笔记列表。 7. **错误处理**:为了提供良好的用户体验,我们需要处理可能出现的错误,如...
Flask由Armin Ronacher开发,基于Werkzeug WSGI工具箱和Jinja2模板引擎。它的核心理念是“微”,强调轻量级和模块化,使得开发者能够快速搭建自己的Web应用。Flask不包含数据库、表单处理等复杂功能,但可以通过扩展...
3. **模板(Template)**:Flask支持Jinja2模板引擎,允许开发者使用模板语言编写HTML,动态生成网页内容。模板可以包含变量、控制结构(如循环和条件判断)以及继承和宏等高级特性。 4. **请求对象(Request ...
本篇学习笔记将深入探讨Jinja2模板的使用,包括模板调用、模板继承以及如何在模板中实现逻辑控制。 1. **模板调用**: Flask通过`render_template`函数调用模板。例如,在`index`视图函数中,我们返回渲染后的`...
这个书单笔记分享系统是一个典型的Web应用案例,涵盖了Python Web开发的基本流程和技术栈,对于学习Flask框架和Web开发实践有着极大的帮助。通过分析和理解源代码,开发者不仅可以提升Python编程技能,还能了解到Web...