Flask知识点串烧(三)--- JInjia2模板

1. 模板简介

  • 把HTML代码存储在单独的文件中,分离程序的业务逻辑和表现逻辑;
  • 借助模板引擎,我们可以在HTML文件中使用特殊的语法标记变量,这类包含固定内容和动态部分的可重用文件称为模板;
  • Flask默认使用的模板引擎是Jinjia2,它是一个功能齐全的python模板引擎,除了设置变量,还允许我们在模板中添加if判断,执行for迭代,调用函数等,以各种方式控制模板的输出。

2. 模板语法

  • {%...%}标识语句,注意在语句结束的地方需要添加结束标签;
  • {{...}}表达式,比如字符串、变量、函数调用等;
  • {#...#}注释

3. 常用的Jinjia2 for循环特殊变量

  • loop.index 当前迭代数,从1开始
  • loop.index0 当前迭代数,从0开始
  • loop.revindex 当前反向迭代数,从1开始
  • loop.revindex0 当前反向迭代数,从0开始
  • loop.first 如果是第一个元素则为True
  • loop.last 如果是最后一个元素则为True
  • loop.previtem 上一个迭代的条目
  • loop.nextitem 下一个迭代的条目
  • loop.length 序列包含的元素数量

4. 模板渲染

       渲染一个模板就是执行模板中的代码,并传入所有在模板中使用的变量,渲染后的结果就是我们要返回给客户端的HTML响应。Flask提供render_template()渲染模板。

5.1 模板辅助工具-上下文

      模板上下文包含了很多变量,包含调用render_template()函数手动传入的变量、Flask默认传入的变量,此外还可以使用set标签在模板中定义变量:

{% set navigation = [('/', 'Home'),('/about', 'About')] %}

也可以将一部分模板数据定义为变量

    {% set navigation %}
        <li><a href="/">Home</li>
        <li><a href="/about">About</li>
    {% endset %}

内置上下文变量

  • config 当前的配置对象
  • request 当前的请求对象,在已激活的请求环境下可用
  • session 当前的会话对象,在已激活的请求环境下可用
  • g 与请求绑定的全局变量,在已激活的请求环境下可用

自定义上下文

  • 如果多个模板都需要使用同一变量,可以设置一个模板全局变量。Flask提供的app.context_processor装饰器,可以用来注册模板上下文处理函数,模板上下文处理函数返回一个包含键值对的字典,可以帮我们完成同一传入变量的工作。
  • 调用render_template()渲染任意一个模板时,所有使用app.context_processor注册的“模板上下文处理函数”都会被执行(含Flask内置的上下文处理函数),这些函数的返回值会被添加到模板中。
  • 除了使用装饰器,也可以直接传入函数到app.context_processor()函数:app.context_processor(lambda: dict(foo='I am foo'))

5.2 模板辅助工具-全局对象

  • Jinjia2内置模板全局函数
    • range(start,stop,step) 和python中的range用法相同;
    • lipsum(n=5, html=True, min=20, max=100)  在测试时生成随机文本,默认生成5段HTML文本,每段包含20~100个单词;
    • dict(**items) 和python中的dict用法相同;
  • Flask内置的模板全局函数
    • url_for() 用于生成url的函数
    • get_flashed_message() 用于获取flash消息的函数
  • Flask除了把g, session, config, request对象注册为模板上下文变量,也将他们设为全局变量;
  • 自定义全局函数
    • 除了使用app.context_processor注册模板上下文处理函数来传入函数,也可以使用app.template_global装饰器将函数注册为模板全局函数。
    • 同理,也可以传入函数到app.add_template_global()

5.3 模板辅助工具-过滤器

  • 过滤器可以用于变量,也可以用于一部分模板数据;
  • 内置过滤器:
    • default()
    • escape()
    • first()
    • last()
    • length()
    • random()
    • safe()
    • trim()
    • max()
    • min()
    • unique()
    • striptags()
    • urlize()
    • wordcount()
    • tojson()
    • truncate()
  • 过滤器可以叠加使用:<h1>Hello, {{ name|default("human")|title }}</h1>
  • 根据Flask的设置,Jinjia2会自动对模板中的变量进行转义,所以我们不用手动使用escape()函数对变量进行转义;
  • 如果想避免转义,将变量作为HTML解析,可以对变量使用safe过滤器;
  • 绝对不要直接对用户输入的内容使用safe过滤器,否则容易被植入恶意代码,导致XSS攻击;
  • 自定义过滤器使用@app.template_filter()装饰器注册过滤器,默认使用函数名称;

5.3 模板辅助工具-测试器

  • 在JInjia2中测试器用来测试变量或表达式,返回布尔值的特殊函数;
  • 内置测试器:
    • callable()
    • defined()
    • undefined()
    • none()
    • number()
    • string()
    • sequence()
    • iterable()
    • mapping()
    • sameas()
  • 使用测试器时,is的左侧是测试器函数的第一个参数,其它参数可以添加括号传入,也可以在右侧使用空格连接;
        {% if foo is sameas(bar) %} 
        {% if foo is sameas bar %}
  • 自定义测试器:Flask提供的@app.template_test()装饰器可以注册一个自定义测试器;

5.4 模板环境对象

  • 模板环境对象:app.jiajia_env
  • 模板环境中的全局函数、过滤器、测试器分别存储在模板环境对象的globals、filters和tests属性中,这三个属性都是字典对象:
    • 添加自定义全局对象:app.jiajia_env.globals['key'] = 任意Python对象
    • 添加自定义过滤器:app.jinjia_env.filters['key'] = 过滤器
    • 添加自定义测试器:app.jiajia_env.tests['key'] = 测试器

5.5 模板结构组织

  • 局部模板
    • 为了和普通模板区分开,局部模板的命名通常以一个下划线开始;
    • 局部模板只包含部分代码,所以不会在视图函数中直接渲染它,而是插入到其它模板中;
    • {% include '_banner.html' %}可以把局部模板的全部内容插在使用include标签的位置。
  • 宏:宏(marco)是Jinjia2提供的一个非常有用的特性,类似Python中的函数。
    • 宏可以把一部分代码封装到宏里,使用传递的参数来构建内容,最后返回构建后的内容;
    • 为了便于管理,我们把宏存储在单独的文件中,这个文件通常命名为macros.html或_macros.html;
    • 在创建宏时,使用macros和endmacros标签声明宏的开始和结束;
    • 使用时使用{% from 'macros.html' import xxx %}导入,然后作为函数调用{{ xxx(key=value) }},传入必要参数;
  • 模板继承:
    • Jinjia2的模板继承允许定义一个基模板,把网页上的导航栏、页脚等通用内容放在基模板中,每个继承基模板的子模板在被渲染时都会自动包含这些部分。
    • 基模板存储了网页的固定部分,通常被称为base.html或layout.html;
    • 块的开始和结束分别使用block和endblock标签声明,块之间可以嵌套;
    • 在编写子模板时,{% extends 'base.html' %}必须是子模板的第一个标签;
    • 如果是向基模板的块中追加内容,需要使用JInjia2提供的super()函数进行声明;

5.6 模板空白控制:使用模板环境对象提供的属性:

  • app.jinjia_env.trim_blocks = True 删除Jinjia2语句后的第一个空行
  • app.jinjia_env.ltrim_blocks 删除Jinjia2语句所在行之前的空格和制表符

6. 加载静态文件

  • Flask内置了用于获取静态文件的视图函数,端点值为static,它的默认URL规则为/static/<path:filename>,URL是相对于static文件夹根目录的文件路径;
  • 如static目录下保存了一个avatar.jpg的图片,则通过url_for('static', filename='avatar.jpg')即可访问这个图片;
  • Favicon:favicon是指收藏夹头像、网站头像;为WEB项目添加Favicon,需要有一个宽高相同的ICO文件,并命名为favicon.con放在static目录下;
  • 使用CSS框架:CSS框架如Bootstrap内置了大量可以直接使用的CSS样式类和JS函数,可以让界面变得美观和易用;我们需要从Bootstrap下载相应的资源文件,然后分类别放在static目录下,并在基模板中引用;
  • 使用宏加载静态资源:方便起见,可以自定义一个专门用来加载各类静态资源的宏,并支持从CDN加载资源;

7. 消息闪现

  • Flask提供的flash()函数可以用来“闪现”需要显示给用户的消息;
  • 使用flash()发送的消息会存储在session中,我们需要在模板中使用全局函数get_flashed_message()获取消息并将其闪现出来;
  • 因为程序的每一个界面都可能需要闪现消息,我们把获取并闪现消息的代码放在基模板中的content块上面,这样就可以在页面主体内容的上面显示消息;
  • 一个页面可能包含多条要显示的消息,因此使用for循环迭代get_flashed_message()返回的消息列表;此外还可以为消息定义CSS规则;

8. 自定义错误界面

    错误处理函数需要附加到app.errorhandler()装饰器,并传入错误代码作为参数。

发布了132 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Geroge_lmx/article/details/104215539