内置全局函数

dict()函数,方便生成字典型变量

{% set user = dict(name='Mike',age=15) %}
<p>{{ user | tojson | safe }}</p> {# 显示 '{"age": 15, "name": "Mike"}' #}

joiner()函数,神奇的辅助函数。它可以初始化为一个分隔符,然后第一次调用时返回空字符串,以后再调用则返回分隔符。对分隔循环中的内容很有帮助

{% set sep = joiner("|") %}
{% for val in range(5) %}
{{ sep() }} <span>{{ val }}</span>
{% endfor %} {# 显示 "0 | 1 | 2 | 3 | 4" #}

cycler()函数,在给定的序列中轮循,列表项<li>的”class”在”odd”和”even”两个值间轮循

{% set cycle = cycler('odd', 'even') %}
<ul>
{% for num in range(10, 20, 2) %}
<li class="{{ cycle.next() }}">Number is "{{ num }}",
next line is "{{ cycle.current }}" line.</li>
{% endfor %}
</ul>

“cycler()”函数返回的对象可以做如下操作

    • next(),返回当前值,并往下一个值轮循
    • reset(),重置为第一个值
    • current,当前轮循到的值

自定义全局函数

将Flask应用代码中定义的函数,通过”add_template_global”将其传入模板即可

import re
def accept_pattern(pattern_str):
pattern = re.compile(pattern_str, re.S)
def search(content):
return pattern.findall(content) return dict(search=search, current_pattern=pattern_str) app.add_template_global(accept_pattern, 'accept_pattern')

上例中的accept_pattern函数会先预编译一个正则,然后返回的字典中包含一个查询函数”search”,之后调用”search”函数就可以用编译好的正则来搜索内容了。”app.add_template_global”方法的第一个参数是自定义的全局函数,第二个是全局函数名称。现在,让我们在模板中使用”accept_pattern”全局函数:

{% with pattern = accept_pattern("<li>(.*?)</li>") %}
{% set founds = pattern.search("<li>Tom</li><li>Bob</li>") %}
<ul>
{% for item in founds %}
<li>Found: {{ item }}</li>
{% endfor %}
</ul>
<p>Current Pattern: {{ pattern.current_pattern }}</p>
{% endwith %}

“Tom”和”Bob”被抽取出来了

Flask同样提供了添加全局函数的装饰器”template_global”,以方便全局函数的添加。我们来用它将取系统当前时间的函数”current_time”定义为全局函数。

import time
@app.template_global('end_with')
def current_time(timeFormat="%b %d, %Y - %H:%M:%S"):
return time.strftime(timeFormat)
<p>Current Time is: {{ current_time() }}</p>
<p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>

Flask添加全局函数的方法是封装了对Jinja2环境变量的操作。上述添加”current_time”全局函数的方法,等同于下面的代码。

app.jinja_env.globals['current_time'] = current_time

宏 (Macro)

{% macro input(name, type='text', value='') -%}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
{%- endmacro %}
<p>{{ input('username', value='user') }}</p>
<p>{{ input('password', 'password') }}</p>
<p>{{ input('submit', 'submit', 'Submit') }}</p>

访问调用者内容

先来创建个宏”list_users”:

{% macro list_users(users) -%}
<table>
<tr><th>Name</th><th>Action</th></tr>
{%- for user in users %}
<tr><td>{{ user.name |e }}</td>{{ caller() }}</tr>
{%- endfor %}
</table>
{%- endmacro %}

调用者的代码:

{% set users=[{'name':'Tom','gender':'M','age':20},
{'name':'John','gender':'M','age':18},
{'name':'Mary','gender':'F','age':24}]
%} {% call list_users(users) %}
<td><input name="delete" type="button" value="Delete"></td>
{% endcall %}

与上例不同,这里我们使用了”{% 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

这是一个字典。如果调用宏时传入的参数多于宏声明时的参数,多出来的指定了参数名的参数就会保存在这个字典中。

{% 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′}”。

当”include”的模板文件不存在时,程序会抛出异常。你可以加上”ignore missing”关键字,这样如果模板不存在,就会忽略这段”{% include %}”语句。

   {% include 'footer.html' ignore missing %}

   {% include ['footer.html','bottom.html','end.html'] ignore missing %}

上例中,程序会按顺序寻找模板文件,第一个被找到的模板即被加载,而其后的模板都会被忽略。如果都没找到,那整个语句都会被忽略。

Flask jinja2 全局函数,宏的更多相关文章

  1. MFC全局函数开局——AfxGetApp解剖

    MFC中有不少的全局函数,方便在不同对象中获取不同的内容或创建不同的对象.主要全局函数有: AfxWinInit() AfxBeginThread() AfxEndThread() AfxFormat ...

  2. Lua和C++交互 学习记录之六:全局函数交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  3. 初探 Python Flask+Jinja2 SSTI

    初探 Python Flask+Jinja2 SSTI 文章首发安全客:https://www.anquanke.com/post/id/226900 SSTI简介 SSTI主要是因为某些语言的框架中 ...

  4. CI框架源码阅读笔记3 全局函数Common.php

    从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...

  5. jQuery全局函数

    全局函数是对jQuery对象的扩展,其中扩展方法包括: 一,extend扩展: //调用全局函数$(document).ready(function () { $.myFunction(); $.my ...

  6. 部分具有统计功能的TSQL语句(例如DBCC语句,全局函数,系统存储过程)

    部分具有统计功能的TSQL语句(例如DBCC语句,全局函数,系统存储过程) 这些功能也能帮助用户了解和监控SQLSERVER的运行情况 DBCC语句,DBCC语句是SQL2005的数据库控制台命令 D ...

  7. JavaScript基础11——js的全局函数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 在C++工程中设置全局函数

    在头文件中对该函数进行全局函数的声明: extern void Test(); 在cpp文件中进行函数的定义: void Test() { MessageBox(NULL,L"调用了C++的 ...

  9. C++学习27 用全局函数重载运算符

    运算符重载函数既可以声明为类的成员函数,也可以声明为所有类之外的全局函数. 运算符重载函数作为类的成员函数 将运算符重载函数声明为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数.之所以 ...

随机推荐

  1. 第八篇:支持向量机 (Support Vector Machine)

    前言 本文讲解如何使用R语言中e1071包中的SVM函数进行分类操作,并以一个关于鸢尾花分类的实例演示具体分类步骤. 分析总体流程 1. 载入并了解数据集:2. 对数据集进行训练并生成模型:3. 在此 ...

  2. 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)

    [BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...

  3. 【BZOJ4071】八邻旁之桥(线段树)

    [BZOJ4071]八邻旁之桥(线段树) 题面 BZOJ权限题,洛谷链接 题解 既然\(k<=2\) 那么,突破口就在这里 分类讨论 ①\(k=1\) 这...不就是中位数吗.... 直接把所有 ...

  4. [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线:L1:y=x ...

  5. [BZOJ1061] [Noi2008] 志愿者招募 (费用流)

    Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能 ...

  6. Java过滤XSS脚本, 可通过Appscan扫描

    项目中有时会需要把一些报错或者解决方案直接返回给前端, 如果直接返回原字符串, 可能会被恶意传参来实现xss注入. 例如常规业务访问一个页面读取文件&file=sdf.cpt, 如果文件不存在 ...

  7. 关于js高度和宽度的获取 ----2017-03-29

    来源:百度  对错有待实践检验 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: docu ...

  8. Java 常用单词

    1.Object-Oriented ['əbdʒekt'ɔ:rɪəntɪd] 面向对象 adj 2.inheritance  [ɪnˈherɪtəns]  继承;遗传;遗产 n inherit  [ɪ ...

  9. 吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

    事情是这样的,在一个新项目中引入了fastdfs,用这玩意做一些小数据的存储还是很方便的,然后在nuget上就找一个对接FastDFS的sdk,如下图: 一眼就看到了这个top1的sdk,应该会比较靠 ...

  10. Day4----------用户、群组、权限

    一.创建用户 命令:useradd 详细信息: root:x:0:0:root:/root:/bin/bash 总共七位 tom:x:500:500: :/home/tom:/bin/bash 1.r ...