zoukankan      html  css  js  c++  java
  • Flask-宏的相关知识。

    转自ITOYO:XIAOJINGJING

    Jinja2的宏功能有些类似于传统程序语言中的函数,既然是函数就有其声明和调用两个部分。

    首先声明一个宏:

     1 <html lang="en">  
     2 <head>  
     3     <meta charset="UTF-8">  
     4     <title>Title</title>  
     5 </head>  
     6 <body>  
     7 {% macro input(name,type='text',value='') %}  
     8     <input type="{{ type }}" name="{{ name }}" value="{{ value }}">  
     9 {% endmacro %}  
    10 {#代码中,宏的名称就是”input”,它有三个参数分别是”name”, “type”和”value”,后两个参数有默认值。#}  
    11 </body>  
    12 </html>  

    代码中,宏的名称就是”input”,它有三个参数分别是”name”, “type”和”value”,后两个参数有默认值。现在,让我们使用表达式来调用这个宏:

    在上面代码中加入如下代码:

    1 <p>{{ input('username',value='user') }}</p>  
    2 <p>{{ input('password','password') }}</p>  
    3 <p>{{ input('submit','submit','submit') }}</p>  

    定义路由,把页面配置进入路由后,访问在页面上看到一个文本输入框,一个密码输入框及一个提交按钮。

    宏的复用:

    1 {% from "macro.html" import input %} 

    引用需要复用的宏文件macro.html,然后调用宏内容,代码如下:

     1 <html lang="en">  
     2 <head>  
     3     <meta charset="UTF-8">  
     4     <title>Title</title>  
     5 </head>  
     6 <body>  
     7 {% from "macro.html" import input %}  
     8 <p>{{ input('username',value='user') }}</p>  
     9 <p>{{ input('password','password') }}</p>  
    10 <p>{{ input('submit','submit','submit') }}</p>  
    11 </body>  
    12 </html>  

    访问调用者内容

    我们先创建一个macrouser_list.html文件,代码如下:

     1 <html lang="en">  
     2 <head>  
     3     <meta charset="UTF-8">  
     4     <title>Title</title>  
     5 </head>  
     6 <body>  
     7 {% macro user_list(users) %}  
     8     <table>  
     9     <tr><th>Name</th><th>Sex</th><th>Age</th><th>Action</th></tr>  
    10     {% for user in users %}  
    11         <tr><td>{{ user.name  }}</td><td>{{ user.gender }}</td><td>{{ user.age }}</td><td>{{ caller() }}</td></tr>  
    12     {% endfor %}  
    13     </table>  
    14 {% endmacro %}  
    15 </body>  
    16 </html>  

    我们还是在usemacro.html文件中设置调用者内容,代码如下:

     1 {% from "macrouser_list.html" import user_list %}  
     2   
     3 {% set users=[{'name':'Tom','gender':'Boy','age':'26'},  
     4 {'name':'Jim','gender':'Boy','age':'25'},  
     5 {'name':'Lucy','gender':'Girl','age':'23'},  
     6 {'name':'Lida','gender':'Girl','age':'22'}]  
     7         %}  
     8 _______________________________________________________________  
     9 {% call user_list(users) %}  
    10 {% endcall %}  
    11 ________________________________________________________________  
    12 {% call user_list(users) %}  
    13  <input name="delete" type="delete" value="delete">  
    14 {% endcall %}  
    15   
    16   
    17 ____________________________________________________________  
    18 {% for user in users %}  
    19         <tr><td>{{ user.name }}</td><td>{{ user.gender }}</td><td>{{ user.age }}</td><td><input name="delete" type="delete" value="delete"></td></tr>  
    20     {% endfor %}  

    访问:http://127.0.0.1:5000/usemacro,可以看到结果。

    与上例不同,这里我们使用了”{% call %}”语句块来调用宏,语句块中包括了一段生成”Delete”按钮的代码。运行下试试,你会发现每个用户名后面都出现了”Delete”按钮,也就是”{{ caller( ) }}”部分被调用者”{% call %}”语句块内部的内容替代了。不明觉厉吧!其实吧,这个跟函数传个参数进去没啥大区别,个人觉得,主要是有些时候HTML语句太复杂(如上例),不方便写在调用参数上,所以就写在”{% call %}”语句块里了。

    Jinja2的宏不但能访问调用者语句块的内容,还能给调用者传递参数。们来扩展下上面的例子。首先,我们将表格增加一列性别,并在宏里调用”caller()”方法时,传入一个变量”user.gender”:

    1 {% macro list_users(users) -%}  
    2   <table>  
    3     <tr><th>Name</th><th>Gender</th><th>Action</th></tr>  
    4     {%- for user in users %}  
    5       <tr><td>{{ user.name |e }}</td>{{ caller(user.gender) }}</tr>  
    6     {%- endfor %}  
    7   </table>  
    8 {%- endmacro %}  

    然后,我们修改下调用者语句块:

     1 {% call(gender) list_users(users) %}  
     2     <td>  
     3     {% if gender == 'M' %}  
     4     <img src="{{ url_for('static', filename='img/male.png') }}" width="20px">  
     5     {% else %}  
     6     <img src="{{ url_for('static', filename='img/female.png') }}" width="20px">  
     7     {% endif %}  
     8     </td>  
     9     <td><input name="delete" type="button" value="Delete"></td>  
    10 {% endcall %}  

    大家注意到,我们在使用”{% call %}”语句时,将其改为了”{% call(gender) … %}”,这个括号中的”gender”就是用来接受宏里传来的”user.gender”变量。因此我们就可以在”{% call %}”语句中使用这个”gender”变量来判断用户性别。这样宏就成功地向调用者传递了参数。

    宏的内部变量

    上例中,我们看到宏的内部可以使用”caller( )”方法获取调用者的内容。此外宏还提供了两个内部变量:

      • varargs

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

      • kwargs

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

    让我们回到第一个例子input宏,在调用时增加其传入的参数,并在宏内将上述两个变量打印出来:

    1 {% macro input(name, type='text', value='') -%}  
    2     <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">  
    3     <br /> {{ varargs }}  
    4     <br /> {{ kwargs }}  
    5 {%- endmacro %}  
    6 <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”模板文件中,然后将调用的代码改为:

    1 {% import 'form.html' as form %}  
    2 <p>{{ form.input('username', value='user') }}</p>  
    3 <p>{{ form.input('password', 'password') }}</p>  
    4 <p>{{ form.input('submit', 'submit', 'Submit') }}</p>  
    包含 (Include)

    这里我们再介绍一个Jinja2模板中代码重用的功能,就是包含 (Include),使用的方法就是”{% include %}”语句。其功能就是将另一个模板加载到当前模板中,并直接渲染在当前位置上。它同导入”import”不一样,”import”之后你还需要调用宏来渲染你的内容,”include”是直接将目标模板渲染出来。它同block块继承也不一样,它一次渲染整个模板文件内容,不分块。

    我们可以创建一个”footer.html”模板,并在”layout.html”中包含这个模板:

    1 <body>  
    2     ...  
    3     {% include 'footer.html' %}  
    4 </body>  

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

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

    “{% include %}”语句还可以跟一个模板列表:

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

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

  • 相关阅读:
    俞敏洪谈大学爱情:终于在清华说实话了
    人的有两面性
    冯亚丽,打造1500亿帝国的奇女子
    做企业就要有精气神
    当心!“饭桌教育”祸害你的孩子
    为何企业宁可高薪招人,也不给老员工加薪?
    住的离公司有多远,成长就有多难
    物理像素,逻辑像素,解决1px的问题
    移动端布局 + iscroll + 滚动事件
    移动端布局 + iscroll.js
  • 原文地址:https://www.cnblogs.com/guolei2570/p/8723192.html
Copyright © 2011-2022 走看看