jinja2 模版引擎

image-20211021184555569
官方网站
http://docs.jinkan.org/docs/jinja2/
类似于java中thymeleaf,jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全:

  1. <title>{% block title %}{% endblock %}</title>
  2. <ul>
  3. {% for user in users %}
  4. <li><a href="{{ user.url }}">{{ user.username }}</a></li>
  5. {% endfor %}
  6. </ul>

特性:

  • 沙箱中执行
  • 强大的 HTML 自动转义系统保护系统免受 XSS
  • 模板继承
  • 及时编译最优的 python 代码
  • 可选提前编译模板的时间
  • 易于调试。异常的行数直接指向模板中的对应行。
  • 可配置的语法

    模版继承

    base.html ``` <!DOCTYPE html> {% block head %} {% endblock%} {% block body%}

    This is base body!

    {% endblock %}
  1. base2.html

{% extends “base.html” %} {% block title%}Index{% endblock %} {% block head %} {{ super() }} {% endblock head%}

{% block body %} {{super()}}

Hello World

{% endblock body%}

  1. ### 继承base页面写出404

{% extends “user.html” %} {% block title %}

not found

{% endblock title%} {% block page_content %} {{super()}} {% endblock %} {% block content %} Page Not Found{% endblock %}

  1. ## flask-bootstrap

from flask import Flask,render_template from Config import Config from flask_bootstrap import Bootstrap

app = Flask(name) app.config.from_object(Config) bootstrap = Bootstrap(app) # 将应用实例传给构造函数

@app.route(“/“) def index(): return render_template(“user.html”)

app.run()

  1. ```
  2. {% extends "bootstrap/base.html" %}
  3. {% block title %}{% endblock title %}
  4. {% block navbar %}
  5. <div class="navbar navbar-inverse" role="navigation">
  6. <div class="container">
  7. <div class="navbar-header">
  8. <button type="button" class="navbar-toggle"
  9. data-toggle="collapse" data-target=".navbar-collapse">
  10. <span class="sr-only">Toggle navigation</span>
  11. <span class="icon-bar"></span>
  12. </button>
  13. <a class="navbar-brand" href="/">Flask</a>
  14. <div class="navbar-collapse collapse">
  15. <ul class="nav navbar-nav">
  16. <li><a href="/">Home</a></li>
  17. </ul>
  18. </div>
  19. </div>
  20. </div>
  21. </div>
  22. {% endblock navbar%}
  23. {% block content %}
  24. <div class="container">
  25. <div class="page-header">
  26. <h1>Hello bootstrap</h1>
  27. </div>
  28. </div>
  29. {% endblock content %}

Flask-Moment

UTC协调世界时,然后经过js渲染,调用每个用户本地的时区信息就能够转换为用户当地时间。
Flask-Moment是一个Flask扩展,能简化把Moment.js集成到jinja2模版中。
下面是一个简单的应用例子:
  前端页面模板部分代码:

  1. {% block scripts %}
  2. {{ super() }}
  3. {{ moment.include_moment() }}  //在前端中通过方法引用moment.js文件
  4. {{ moment.locale('zh-cn') }}  //将moment.js本地化,否则渲染出来的时间日期都是英文的
  5. {% endblock %}
  6. {% block page_content %}
  7. {{ super() }}
  8. <h3>Time now is {{ moment(current_time).format('LLL') }}</h3><hr>
  9. {% endblock %}

后端部分代码:

  1. m = Moment(app) #和bootstrap一样,不要忘了这一步,否则前端报找不到moment类的错
  2. @app.route('/time',methods=['GET'])
  3. def show_time():
  4. return render_template('time.html',current_time=datetime.datetime.utcnow())

表单校验

  1. {% extends "base.html" %}
  2. {% import "bootstrap/wtf.html" as wtf %}
  3. {% block title %}User{% endblock %}
  4. {% block page_content %}
  5. <div class="page-header">
  6. <h1>Hello, User page!</h1>
  7. <hr>
  8. <!-- <form action="" method="POST">
  9. {{form.hidden_tag() }}
  10. {{form.name.label}} {{form.name}}
  11. {{form.email.label}} {{form.email}}
  12. {{ form.submit() }}
  13. </form> -->
  14. {{wtf.quick_form(form)}}
  15. {% if name %}
  16. <h2>Welcom {{name}} </h2>
  17. {% endif %}
  18. <hr>
  19. <p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
  20. <p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>
  21. </div>
  22. {% endblock %}
  1. from flask import Flask,render_template
  2. from Config import Config
  3. from flask_bootstrap import Bootstrap
  4. from flask_moment import Moment
  5. from datetime import datetime
  6. from flask_wtf import FlaskForm
  7. from wtforms import StringField,SubmitField
  8. from wtforms.validators import DataRequired,Email
  9. app = Flask(__name__)
  10. app.config.from_object(Config)
  11. bootstrap = Bootstrap(app) # 将应用实例传给构造函数
  12. m = Moment(app)
  13. # 定义表单类
  14. class NameForm(FlaskForm):
  15. name = StringField('What is your name?',validators=[DataRequired()])
  16. email = StringField("Enter your email",validators=[Email()])
  17. submit = SubmitField('Submit')
  18. @app.route("/")
  19. def index():
  20. utc = datetime.utcnow()
  21. return render_template("index.html",current_time=utc)
  22. @app.route("/user",methods=['get','post'])
  23. def user():
  24. name = None
  25. email = None
  26. form = NameForm()
  27. if form.validate_on_submit(): # 如果通过验证
  28. name = form.name.data
  29. email = form.email.data
  30. form.name.data = '' # 重制
  31. form.email.data = ''
  32. utc = datetime.utcnow()
  33. return render_template("user.html",current_time=utc,form=form,name=name,email=email)
  34. @app.errorhandler(404)
  35. def errorhandler(e):
  36. return render_template('404.html'),404
  37. @app.errorhandler(500)
  38. def internal_server_error(e):
  39. return render_template('500.html'),500
  40. app.run()

flask-BootStrap

在exts中的init中引入

  1. from flask_sqlalchemy import SQLAlchemy
  2. from flask_bootstrap import Bootstrap
  3. bootstrap = Bootstrap()
  4. db = SQLAlchemy()

apps中的init绑定bootstarp

  1. from flask import Flask,render_template,session,redirect,url_for,flash
  2. from settings import Config
  3. from flask_bootstrap import Bootstrap
  4. from flask_moment import Moment
  5. from datetime import datetime
  6. from flask_wtf import FlaskForm
  7. from wtforms import StringField,SubmitField
  8. from wtforms.validators import DataRequired,Email
  9. from exts import db, bootstrap
  10. from apps.user.model import *
  11. def create_app():
  12. app = Flask(__name__, template_folder='../templates/', static_folder='../static/') # type:Flask
  13. app.config.from_object(Config)
  14. bootstrap.init_app(app=app) # bootstrap
  15. m = Moment(app)
  16. db.init_app(app) # 数据库
  17. app.register_blueprint(user_bp)
  18. # print(app.url_map)
  19. return app

基本语法可以参考下面这篇博文:
http://www.bjhee.com/jinja2-statement.html

自定义过滤器

  1. @index_bp.app_template_filter('summary')
  2. def summary(content):
  3. return content[:50]+'......'
  1. <p class="my-font-description" >{{ arti.content|summary }}</p>