1、宏({% macro %} {% endmacro %})

注意点:宏只能写在模板中,也就是html文件中,并且宏没有返回值(不能嵌套)
宏与python中函数相类似,能够传递参数,但是没有返回值。可以将一些常用的代码块放在宏中,将一些需要改变的值抽取出来作为参数
1、定义一个input标签的宏
代码部分:

  1. from flask import Flask, render_template
  2. # 这里可以设置相关的文件名,模板的修改为template_folder,静态文件修改static_folder
  3. app = Flask(__name__)
  4. @app.route("/")
  5. def home():
  6. return "首页"
  7. @app.route("/macro/")
  8. def myself():
  9. return render_template("macro.html")
  10. if __name__ == "__main__":
  11. app.run(debug=True)

模板部分:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>macro</title>
  6. </head>
  7. <body>
  8. <!--定义宏-->
  9. {% macro input(name, value="", type="text") %}
  10. <input name="{{ name }}", value="{{ value }}", type="{{ type }}">
  11. {% endmacro %}
  12. <!--使用宏,不要忘记{{ xxx }}-->
  13. <table>
  14. <tr>
  15. <td>用户名:</td>
  16. <td>{{ input('username') }}</td>
  17. </tr>
  18. <tr>
  19. <td>密码:</td>
  20. <td>{{ input('password', type='password') }}</td>
  21. </tr>
  22. <tr>
  23. <td>确定:</td>
  24. <td>{{ input(value='提交', type='submit') }}</td>
  25. </tr>
  26. </table>
  27. </body>
  28. </html>

网页显示:
image.png
第二个例子:
模板代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>macro</title>
  6. </head>
  7. <body>
  8. {% macro tab(txt, name, value="", type="text") %}
  9. <tr>
  10. <td>{{ txt }}</td>
  11. <td>
  12. <input name="{{ name }}", value="{{ value}}", type="{{ type }}">
  13. </td>
  14. </tr>
  15. {% endmacro %}
  16. <table>
  17. {{ tab("用户名称:", name="username") }}
  18. {{ tab("密码:", name="username", type="password") }}
  19. {{ tab("确认:", value="提交", type="submit") }}
  20. </table>
  21. </body>
  22. </html>

网页显示:
image.png

2、import导入宏

在正式的开发中,会将宏单独放在一个html文件中,在需要使用时,在从这个文件中进行导入。导入语法与python相似有:

  • import…as…
  • from…import…
  • from…import…as…

定义一个专门存放宏的html文件forms.html:

  1. <!--定义一个input标签-->
  2. {% macro input(name, value="", type="text") %}
  3. <input name="{{ name }}", value="{{ value }}", type="{{ type }}">
  4. {% endmacro %}
  5. <!--定义一个textarea标签-->
  6. {% macro textarea(name, value="", rows=10, cols=40) %}
  7. <textarea name="{{ name }}", value="{{ value }}", rows="{{ rows }}", cols="{{ cols }}">
  8. {{ value|e }}</textarea>>
  9. {% endmacro %}

在其他的模板中进行导入

  1. {# {% from "forms.html" import input %} #}
  2. {# {% from "forms.html" import input as ipt %} #}
  3. <!--不要忘记as,因为导入的forms带有html标签所以在使用时会出现问题,因此需要重命名-->
  4. {% import "forms.html" as forms %}
  5. <!DOCTYPE html>
  6. <html lang="en">
  7. <head>
  8. <meta charset="UTF-8">
  9. <title>macro</title>
  10. </head>
  11. <body>
  12. <table>
  13. <tr>
  14. <td>用户名:</td>
  15. <td>{{ forms.input("username") }}</td>
  16. </tr>
  17. <tr>
  18. <td>密码:</td>
  19. <td>{{ forms.input("password", type="password") }}</td>
  20. </tr>
  21. </table>
  22. </body>
  23. </html>

网页显示:
image.png
注意点:

  • 只要当前文件中有定义宏,那么在其他文件中就可以对其进行导入,当然一般将宏单独放在一个文件中
  • {% import “macro.html” as macro %}在import html文件时不要忘了通过as进行重命名
  • {{ macro.input(xxx) }}具体使用方式

    3、给模板中传参(with context)

    由于导入模板并不会将上下文中的变量(如set定义的变量或者从py文件中传入的变量)一起导入到当前的模板中来。因此如果需要上下文变量有两种导入方式:

  • 显示的传入请求或者请求对象的属性作为宏的参数

  • 通过上下文传参(with context)导入的方式
    1. <!--with context-->
    2. <!--其他两种导入方式也适用-->
    3. {% import "macro.html" as macro with context %}
    模块代码: ```python from flask import Flask, render_template

app = Flask(name) app.config[“TEMPLATES_AUTO_RELOAD”] = True

dic = { “value_py”: “我是py中的参数”, “type_py”: “text” } }

@app.route(“/“) def home(): return render_template(“context.html”, **dic)

if name == “main“:

  1. # app.config.from_pyfile('settings.py',silent=True)
  2. app.run(debug=True)
  1. **模板代码1:forms1.html**
  2. ```html
  3. {% macro input(name) %}
  4. <!--传入context.py中的value_py与type_py参数-->
  5. <input name="{{ name }}", value="{{ value_py }}", type="{{ type_py }}">
  6. {% endmacro %}

模板代码2:context.html

  1. {% from "forms1.html" import input with context %}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>context</title>
  7. </head>
  8. <body>
  9. <table>
  10. <tr>
  11. <td>用户名:</td>
  12. <td>{{ input("username") }}</td>
  13. </tr>
  14. </table>
  15. </body>
  16. </html>

页面显示:
image.png

4、补充说明,模板传参

如果现在在macro.html文件、index.html文件,app.py文件中分别定义了同一个变量,那么在使用with context的情况下宏文件如何调用呢?
1、首先如果在macro.html中存在该变量,则先从macro.html中进行寻找。如果没有就从app.py文件中寻找
2、同名变量的搜索优先度为:macro.html > app.py,就与定义函数优先局部变量在找全局变量是一个道理
3、即使在index.html文件中定义了变量,也不会被引用
**