跳转到主要内容

在Python Web框架中将Jinja2模板块渲染为HTML页面片段。

项目描述

Jinja2片段

Jinja2 Fragments 允许渲染来自 Jinja2模板 的单个块。这个库是为了启用与Jinja2一起使用的 模板片段模式而创建的。如果您使用的是 HTMX 或其他利用获取部分HTML的库,这是一个非常好的模式。

使用Jinja2,如果您有一个想要单独渲染并作为其他页面一部分的模板块,您被迫将该块放在一个单独的文件中,然后在包装模板中使用 include标签(或 Jinja Partials)。

使用Jinja2 Fragments,遵循 行为局部性设计原则,您只需一个文件即可完成这两种情况。下面是示例。

安装

只需 pip install jinja2-fragments,然后您就设置好了。这是一个纯Python包,只需要 jinja2(显然!)。

用法

这是使用纯Jinja2库的示例。给定模板 page.html.jinja2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>This is the title</title>
</head>
<body>
    <h1>This is a header</h1>
    {% block content %}
    <p>This is the magic number: {{ magic_number }}.</p>
    {% endblock %}
</body>
</html>

如果您只想渲染 content 块,则

from jinja2 import Environment, FileSystemLoader, select_autoescape
from jinja2_fragments import render_block

environment = Environment(
    loader=FileSystemLoader("my_templates"),
    autoescape=select_autoescape(("html", "jinja2"))
)
rendered_html = render_block(
    environment, "page.html.jinja2", "content", magic_number=42
)

这将只渲染

<p>This is the magic number: 42.</p>

渲染多个块

使用变体 render_blocks(注意复数形式),也可以从同一个模板渲染多个块并将它们全部连接起来返回,从而实现使用HTMX时的更易于进行的离线更新

与Flask的用法

如果您想在Flask中使用Jinja2片段,假设与上面的示例相同的模板,则

from flask import Flask, render_template
from jinja2_fragments.flask import render_block

app = Flask(__name__)

@app.get("/full_page")
def full_page():
    return render_template("page.html.jinja2", magic_number=42)


@app.get("/only_content")
def only_content():
    return render_block("page.html.jinja2", "content", magic_number=42)

与Quart的用法

如果您想在Quart中使用Jinja2片段,假设与上面的示例相同的模板,则

from quart import Quart, render_template
from jinja2_fragments.quart import render_block

app = Quart(__name__)

@app.get("/full_page")
async def full_page():
    return await render_template("page.html.jinja2", magic_number=42)


@app.get("/only_content")
async def only_content():
    return await render_block("page.html.jinja2", "content", magic_number=42)

与FastAPI的用法

您还可以在FastAPI中使用Jinja2片段。在这种情况下,Jinja2片段有一个围绕FastAPI Jinja2Templates 对象的包装器,称为 Jinja2Blocks

它功能完全相同,但允许您向 TemplateResponse 包含一个可选参数,该参数包含要渲染的 block_name

假设与上面的示例相同的模板

from fastapi import FastAPI
from fastapi.requests import Request
from jinja2_fragments.fastapi import Jinja2Blocks

app = FastAPI()

templates = Jinja2Blocks(directory="path/to/templates")

@app.get("/full_page")
async def full_page(request: Request):
    return templates.TemplateResponse(
        "page.html.jinja2",
        {"request": request, "magic_number": 42}
    )

@app.get("/only_content")
async def only_content(request: Request):
    return templates.TemplateResponse(
        "page.html.jinja2",
        {"request": request, "magic_number": 42},
        block_name="content"
    )

与Sanic的用法

您可以使用jinja2-fragments的 render() 作为Sanic模板扩展的 render() 的替代品。您的请求上下文和环境配置将与以前一样工作。您必须安装 sanic_extJinja2

默认情况下,渲染整个页面(block=None),除非您提供 block 关键字参数。

from sanic import Sanic, Request
import sanic_ext
from jinja2_fragments.sanic import render

app = Sanic(__name__)
app.extend(config=sanic_ext.Config(templating_path_to_templates='path/to/templates'))

@app.get('/full_page')
async def full_page(request: Request):
    return await render(
        'page.html.jinja2', 
        context={"magic_number": 42}
    )

@app.get("/only_content")
async def only_content(request: Request):
    return await render(
        'page.html.jinja2',
        block='content',
        context={"magic_number": 42}
    )

与Litestar的用法

您可以使用 LitestarHTMXTemplate 类使用Jinja2 Fragments与Litestar。这使您在渲染模板时可以访问 block_name 参数。

默认情况下,渲染整个页面,除非您提供 block_name 关键字参数。

from litestar.contrib.htmx.request import HTMXRequest
from litestar import get, Litestar
from litestar.response import Template

from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.template.config import TemplateConfig
from jinja2_fragments.litestar import HTMXBlockTemplate


@get('/full_page')
def full_page(request: HTMXRequest) -> Template:
    return HTMXBlockTemplate(
        template_name='page.html.jinja2',
        context={"magic_number": 42}
    )

@get('/only_content')
def only_content(request: HTMXRequest) -> Template:
    return HTMXBlockTemplate(
        template_name='page.html.jinja2',
        block_name='content',
        context={"magic_number": 42}
    )

app = Litestar(
    route_handlers=[full_page, only_content],
    request_class=HTMXRequest,
    template_config=TemplateConfig(
        directory="path/to/templates",
        engine=JinjaTemplateEngine,
    )
)

如何协作

此项目使用预提交钩子在每个提交上运行black、isort、pyupgrade和flake8。要使它们在您的环境中自动运行,请使用以下命令安装项目:

pip install -e .[dev]

然后运行一次

pre-commit install

从现在起,每次您在此项目上提交文件时,它们都将自动由上面列出的工具处理。

如何运行测试

您可以使用以下命令安装pytest和其他所需依赖项:

pip install -e .[tests]

然后运行测试套件:

pytest

项目详情


下载文件

下载您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

jinja2_fragments-1.6.0.tar.gz (14.7 kB 查看散列

上传时间

构建分发

jinja2_fragments-1.6.0-py3-none-any.whl (11.1 kB 查看散列

上传时间 Python 3

由以下支持