Jinja 模板引擎
Python Jinja2 模板引擎
https://palletsprojects.com/projects/jinja https://jinja.palletsprojects.com/en/stable/
pallets / jinja https://github.com/pallets/jinja
pip install Jinja2 https://pypi.org/project/Jinja2/
中文文档 https://docs.jinkan.org/docs/jinja2/
Jinja2 基础语法
什么是模板? 就是在静态 HTML 加入一些变量标签,然后引擎在渲染这个 HTML 时候会动态的把变量填入内容,生成一个最终的 HTML。
变量输出
Jinja2 模板关键语法
变量输出 {{ var }}
变量属性 {{ post.title }}
或 {{ post['title']}}
字典元素 {{ your_dict['key'] }}
列表 {{ your_list[0] }}
注释 {# This is a comment #}
无转义输出 {{ variable|safe }}
修剪空白
{%-
和 -%}
管道过滤器
{{ text | truncate(50) }}
{{ text | upper }} → 转为大写
{{ list | join(",") }} → 拼接字符串
{{ user.bio | default("No bio", true) }} → 默认值
{{ html_content | safe }} → 禁用HTML转义(谨慎使用)
常用过滤器: trim/striptags:移除空白/HTML标签 length/count:获取长度 round/abs:数值处理 tojson:转为 JSON 格式
条件语句
{% if condition %}
Show this
{% elif other_condition %}
Alternative
{% else %}
Default
{% endif %}
示例:
{% if user.is_admin %}
<p>{{ user.name }} (Admin)</p>
{% else %}
<p>{{ user.name }}</p>
{% endif %}
循环语句
{% for item in items %}
<li>{{ loop.index }}: {{ item }}</li>
{% else %}
<p>No items found.</p>
{% endfor %}
特殊变量: loop.index 计数从1开始 loop.index0 从0开始 loop.first loop.last
extends 继承与覆盖
base.html 中定义可替换 block
1、通常会定义一个基础模板 base.html,包含通用结构的 "骨架" 文件,定义可被覆盖的 block 区域
{% block xxx %}
标记可替换区域(带默认内容){% endblock %}
可替换区域结束标识- 子模板可以覆盖这些块
例如:base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题{% endblock %}</title> <!-- 定义 title 块 -->
</head>
<body>
<header>
{% block header %} <!-- 定义 header 块 -->
<h1>默认头部</h1>
{% endblock %}
</header>
<main>
{% block content %} <!-- 核心内容块 -->
<p>这里是默认内容</p>
{% endblock %}
</main>
<footer>
{% block footer %} <!-- 页脚块 -->
© 2023 默认版权
{% endblock %}
</footer>
</body>
</html>
子模板中覆盖 block
2、子模板继承基础模板并覆盖特定块 例如:home.html
{% extends "base.html" %} <!-- 声明继承关系 -->
{% block title %}首页 - 我的网站{% endblock %} <!-- 覆盖标题 title -->
{% block header %} <!-- 替换头部 header -->
<h1>欢迎访问首页</h1>
<nav>首页 | 产品 | 关于</nav>
{% endblock %}
{% block content %} <!-- 替换主要内容 content -->
<section>
<h2>最新产品</h2>
<ul>
{% for product in products %}
<li>{{ product.name }} - ${{ product.price }}</li>
{% endfor %}
</ul>
</section>
{% endblock %}
{# 未覆盖 footer 块,将显示父模板默认内容 #}
super() 引用父模板内容
在子模板中保留父模板内容并添加新内容:
{% block header %}
{{ super() }} <!-- 插入父模板的 header 内容 -->
<div>新增广告横幅</div>
{% endblock %}
include 导入
{% include %}
允许将一个模板直接嵌入到另一个模板中,实现模块化设计和代码复用。
例如
{% include 'partials/header.html' %}
将 partials/header.html 文件的内容插入到当前位置
覆盖/添加变量 通过 with 关键字传递额外变量或覆盖已有变量:
{% include 'product_card.html' with
product=featured_item,
show_details=True,
discount=0.2
%}
EJS 模板语法
Hexo 默认使用 EJS(Embedded JavaScrip) 作为模板引擎,语法类似 JavaScript,通过 <% %>
标签嵌入逻辑。
变量输出 <%= variable %>
无转义输出 <%- raw_html %>
注释 <%# This is a comment %>
条件语句
<% if (condition) { %>
...
<% } %>
循环
<% for (item of list) { %>
...
<% } %>
示例:
<% if (user.isAdmin) { %>
<p><%= user.name %> (Admin)</p>
<% } else { %>
<p><%= user.name %></p>
<% } %>
模板继承、引入
<%- include('partials/header.ejs') %>