jinja2学习总结

前言

jinja2 为flask 的默认模版语言。我们需要了解一下如何使用。需要一定的基础。

默认将静态文件为 static文件夹下,模版文件位于templates下

将从身为前端页面渲染的一些点来学习这个模版语言。

从值与逻辑的方面进行学习jinja2.

前端无非就是数据进行展示和交互。

渲染是一个重点,jinja2使用双大括号进行值的计算和渲染。

依据一些特点的块进行替换和继承等。

依据一些控制结构使数据的渲染方式进行控制。

基本使用

# 代码块:控制结构等
{% %}
# 值:变量值等
{{}}
# 注释
{# #}

逻辑

if语句

单分支
{% if ok %}
	sth...
{% endif %}


多分支
{% if ok %}
	sth...
{% elif ok %}
	sth...
{% else %}
	sth...
{% endif %}

for循环

{% for item in items %}
	sth...
{% endfor %}

{% for k,v in dict.iteritems() %}
	sth...
{% endfor %}

循环包括内建的特殊变量:loop

loop.length 项目数
loop.first 首次循环 (True or False)
loop.last 末次循环(True or False)

loop.index 当前循环的次数(从1开始)
loop.revindex 循环结束的次数(1开始)
loop.index0
loop.revindex0

宏类似函数

{% macro func_name(param1,...) %}
	<li>{{ param1 }}</li>
	...
{% endmacro %}

那么如何使用呢

<ul>
	{{ funcname(1) }}
	{{ funcname(2) }}
	...
</ul>

可以创建单独的宏模版,再在别的模版中引入

function.html
{% macro func_name(param1,...) %}
	<li>{{ param1 }}</li>
	...
{% endmacro %}

引入,

index.html

{% from 'function.html' import funcname %}

将上下文对象导入到模版里
{% from 'function.html' import funcname with context %}

{{ funcname(index) }}

创建变量

使用set 创建一个变量,页面内均可使用,类似页面全局变量

{% set name = 'sth...' %}
<p>{{ name }}</p>

with 创建后可在部分作用域内有效,但是同时设置了同一个变量名,with内定义的将覆盖全局的

{% with name = 'sth...' %}
	<p>{{ name }}</p>
{% endwith %}

变量

值主要包括:

​ 视图传递给模板的数据。

​ 前面定义出来的数据。

​ 变量不存在,默认忽略。

可以进行变量的操作等,比如算术运算,比较等等。。

尽量不使用操作变量的方式,只进行渲染,减少页面的逻辑。

url_for反向解析

链接使用url_for反转为链接

url_for(endpoint,**values)接受端点和关键字参数即 key=value形式的参数

endpoint:蓝图名.函数名

**values:key=value

可利用这个进行一些url的构造

url_for('index')会请求到 /, 而 url_for('index', _external=True)会请求到绝对地址 http://localhost:5000/ ,因为相对地址比绝对地址更有效率,因此应该尽可能使用相对地址。

如果你传递了一些动态路由上不要的参数,它会被当做查询参数跟在链接地址后面,比如url_for('index', page=2)会返回 /?page=2

一些静态文件的引入等。。

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static',filename='js/custom.js') }}"></script>

过滤器

过滤器主要使用方式

{{ 变量 | 过滤器1 | 过滤器2 |... }}

一些过滤器

safe 保留样式进行渲染
striptags 去掉html标签
trim 去掉前后空格
capitalize 首字母大写
lower 小写
upper 大写
title 每个单词首字母大写
join 拼接多个值为字符串
replace 替换字符串的值
round 默认进行数字的四舍五入
int 转换为整型
default 设置一个默认值
format 格式化字符串
truncate 截取
...
{{ " Hello World" | replace("Hello", "123") }}
    -> 123 World

也可以自己定义一个过滤器

测试器

主要是用于判断一个值是否为某些类型或者是否被定义等

{% if variable is escaped %}
 	{{escaped}}...
{% else %}
	is not ...
{% endif %}
callable(object) 是否被调用
defined() 是否被定义
escaped() 是否被转义
upper() 是否全为大写
lower() 是否全为小写
string() 是否为字符串
sequence() 是否为一个序列
number() 是否为一个数字
odd() 是否为奇数
even() 是否为偶数

继承

<!-- 基准base.html -->

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    
    <!-- head block -->
    {% block head %}{% endblock %}

</head>
<body>

    <!-- header -->
    <header></header>
    
    <!-- main  -->
    {% block content %}{% endblock %}
    
    <!-- footer -->
    <footer></footer>

    <!-- Optional JavaScript -->
    {% block script %}{% endblock %}

</body>
</html>

使用extends 来实现模版的继承

使用super()进行父模版的原来的内容, 表示获取block块中定义的原来的内容。

使用self.blockname()进行当前页面的某个内容的引用

将该模版单独的数据和结构写入在block内容块之中

<!-- extends.html -->
{% extends "layout.html" %}

{% block title %}
	Index
{% endblock %}

{% block head %}
  {{ super() }}
{% endblock %}

{% block content %}
  <h1>Index</h1>
  <p>{{ self.title() }}</p>
{% endblock %}

可将单独的一些要重复使用的模版抽象,然后再引入

比如消息组件flash模版:

{% for message in get_flashed_messages() %}
   <strong>{{ message }}</strong>
{% endfor %}
{% include 'flash.html' %}

总结

jinja2蛮好用的,从继承到宏的抽象渲染。将很多东西都组件化出来。

相对于,节省时间和将页面分割利于维护。不过听说性能好,安全等方面没有深入了解到。



奖励一下