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') %>