Jinja2 有三种定界符语法:
{{ ... }}
用来标记变量;{% ... %}
用来标记语句;{# ... #}
用来标记注释;
如果你同时使用了 JavaScript 模板引擎,而该 JavaScript 模板引擎也使用相同的语法标记符,那就会产生冲突。一般来说,有下面三种兼容性处理方式:
1. 使用 Jinja2 的 raw 标签标记 JavaScript 模板代码
第一种方式最直观,使用 Jinja2 的 raw 标签声明原生代码块,也就是不需要进行后端渲染的代码块。使用 raw
和 endraw
标签把 JavaScript 模板部分标记出来即可,比如:
{% raw %} <div id="app"> {{ js_var }} </div> {% endraw %}
这种方式的副作用最少,尽管需要多几行代码,但不会影响你写 Jinja2 或其他 JavaScript 库的语法习惯。
2. 修改 Jinja2 的语法定界符号
第二种方式是修改 Jinja2 的语法定界符号,一般只修改变量定界符即可,其他的按需修改。具体通过修改程序实例的下面几个属性来实现:
from flask import Flask app = Flask(__name__) app.jinja_env.block_start_string = '(%' # 修改块开始符号 app.jinja_env.block_end_string = '%)' # 修改块结束符号 app.jinja_env.variable_start_string = '((' # 修改变量开始符号 app.jinja_env.variable_end_string = '))' # 修改变量结束符号 app.jinja_env.comment_start_string = '(#' # 修改注释开始符号 app.jinja_env.comment_end_string = '#)' # 修改注释结束符号
3. 修改 JavaScript 模板的语法定界符号
第三种方式是修改 JavaScript 模板的语法定界符号,具体方法因 JavaScript 模板/框架而异,可以参见相关文档了解。以 Vuejs 为例,下面将模板定界符改为中括号:
var app = new Vue({ el: "#app", delimiters: ["[[", "]]"], data: { message: "Hello Vue!" } })
折中方案
如果你觉得使用 raw
标签太麻烦,而修改语法定界符又不习惯,这里还有一个折中方法:两边都使用双花括号作为定界符,但根据花括号内部是否添加空格来进行区分。
具体来说,对 Jinja2 变量使用 Jinja2 标准语法,也就是使用 {{
作为变量开始符号,注意花括号右侧有一个空格,结束符号类似,需要在花括号左侧加入一个空格,即 }}
。实际示例如下:
{{ jinja_var }}
而 JavaScript 模板使用没有空格的双花括号,即:
{{js_var}}
这是一种更适合心细的懒人的方法,如果是团队项目,可能会对不习惯这种用法的人造成困扰,记得在文档里注明。这种方式只需要修改 Jinja2 定界符:
app.jinja_env.variable_start_string = '{{ ' app.jinja_env.variable_end_string = ' }}'
另外需要注意的是,如果你使用了其他 Flask 扩展的内置 Jinja2 模板或宏,需要确保它们都使用了包含空格的标准 Jinja2 语法。举例来说,用来方便集成 Bootstrap 的 Flask-Bootstrap 就没法使用,需要使用替代的 Bootstrap-Flask。其他扩展,比如 Flask-Admin,Flask-Security 暂未测试,欢迎了解的同学反馈兼容情况。
辉哥,有个问题困扰着我:
{{ res-data }}
上面这个写法不能够正确解析出变量,是因为”-“在jinja2里是特殊关键字的原因吗?如果非要用”-“有什么解决方法吗?
Python 变量命名不允许用横线,你可以用下划线(res_data)。