Framework Integrations
Jinja2 Fragments provides seamless integration with popular Python web frameworks. Each framework integration is designed to align with that framework’s specific patterns and idioms for template rendering.
The installation of Jinja2 Fragments for all them is the same:
pip install jinja2-fragments
Flask Integration
Jinja2 Fragments provides a Flask-specific render_block function that works as a drop-in replacement for Flask’s built-in render_template.
To use Jinja2 Fragments with Flask, import render_block from the jinja2_fragments.flask module:
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)
The render_block function has the same signature as Flask’s render_template, with an additional parameter for the block name:
render_block(template_name_or_list, block_name, **context)
You can also use the render_blocks function (plural) to render multiple blocks at once:
from jinja2_fragments.flask import render_blocks
@app.get("/multiple_blocks")
def multiple_blocks():
return render_blocks("page.html.jinja2", ["header", "content"], magic_number=42)
This is useful for htmx out-of-band updates where you need to update multiple elements in a single request.
Quart Integration
The Jinja2 Fragments integration with Quart is very similar to Flask but designed for async usage.
To use Jinja2 Fragments with Quart, import render_block from the jinja2_fragments.quart module:
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)
Note
Note that both functions are asynchronous and need to be awaited, following Quart’s async-first design philosophy.
The render_block function has the same signature as Quart’s render_template, with an additional parameter for the block name:
await render_block(template_name_or_list, block_name, **context)
Multiple blocks can be rendered with the render_blocks function, similar to the Flask integration.
Starlette Integration
Jinja2 Fragments provides native support for Starlette through the Jinja2Blocks class that extends Starlette’s Jinja2Templates. Since FastAPI is built on top of Starlette, this integration works with both pure Starlette applications and FastAPI applications.
To use Jinja2 Fragments with Starlette, import Jinja2Blocks from the jinja2_fragments.starlette module:
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.routing import Route
from jinja2_fragments.starlette import Jinja2Blocks
templates = Jinja2Blocks(directory="path/to/templates")
async def full_page(request: Request):
return templates.TemplateResponse(request, "page.html.jinja2", {"magic_number": 42})
async def only_content(request: Request):
return templates.TemplateResponse(
request, "page.html.jinja2", {"magic_number": 42}, block_name="content"
)
routes = [
Route("/full_page", full_page),
Route("/only_content", only_content),
]
app = Starlette(routes=routes)
The Jinja2Blocks class works exactly like Starlette’s Jinja2Templates, but allows you to include an optional block_name parameter to the TemplateResponse method.
Note
You can also render multiple blocks at once by using the block_names parameter with a list of block names.
FastAPI Integration
Jinja2 Fragments provides seamless FastAPI integration. Since FastAPI uses Starlette under the hood, the FastAPI integration is built on top of the Starlette implementation.
To use Jinja2 Fragments with FastAPI, import Jinja2Blocks from the jinja2_fragments.fastapi module:
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(request, "page.html.jinja2", {"magic_number": 42})
@app.get("/only_content")
async def only_content(request: Request):
return templates.TemplateResponse(
request, "page.html.jinja2", {"magic_number": 42}, block_name="content"
)
The Jinja2Blocks class works exactly like FastAPI’s Jinja2Templates, but allows you to include an optional block_name parameter to the TemplateResponse method.
Important
Remember that FastAPI’s template system requires a request object in the context, as shown in the examples above.
Sanic Integration
Jinja2 Fragments provides a replacement for Sanic’s template rendering function.
To use Jinja2 Fragments with Sanic, import render from the jinja2_fragments.sanic module:
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}
)
The render function is a drop-in replacement for Sanic’s template extension’s render(). Your request context and environment configuration will work the same as before.
Note
By default, the full page is rendered (block=None) unless you provide a block keyword argument.
Litestar Integration
Jinja2 Fragments provides integration with Litestar through the HTMXBlockTemplate class.
To use Jinja2 Fragments with Litestar, import HTMXBlockTemplate from the jinja2_fragments.litestar module:
Important
HTMXBlockTemplate can be used as a drop-in replacement for Litestar’s Template class.
However, passing multiple positional arguments to HTMXBlockTemplate is deprecated and will be
removed in a future version. Use template_name as the only positional argument and pass all
other parameters as keyword arguments.
Recommended usage: HTMXBlockTemplate("template.html", block_name="content", push_url="/url")
Deprecated usage: HTMXBlockTemplate("/url", "innerHTML", "#target", template_name="template.html")
try:
# litestar>=2.13.0
from litestar.plugins.htmx import HTMXRequest
except ImportError:
# litestar<2.13.0
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,
),
)
Note
By default, the full page is rendered unless you provide a block_name keyword argument.