### Clone Repository and Setup Virtual Environment Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/development.md Clone the project repository and set up a Python virtual environment. Activate the environment before proceeding with installations. ```bash git clone https://github.com/sponsfreixes/jinja2-fragments cd jinja2-fragments # Using venv python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate ``` -------------------------------- ### setup_globals Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/core.md Installs `render_block` and `render_blocks` as Jinja2 template globals, allowing direct use within templates after setup. ```APIDOC ## setup_globals ### Description Installs `render_block` and `render_blocks` as Jinja2 template globals. The correct sync or async callable is automatically chosen based on `environment.is_async`. Existing globals with these names are preserved. ### Parameters #### Path Parameters - **environment** (Environment) - Required - Jinja2 Environment instance to modify ### Returns - **None** — Modifies the environment in-place ### Example ```python from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2_fragments import setup_globals environment = Environment( loader=FileSystemLoader("templates"), autoescape=select_autoescape(("html", "jinja2")), ) # Install render_block and render_blocks as template globals setup_globals(environment) # Now templates can call these directly: # {{ render_block("other_template.html", "block_name", key=value) }} # {{ render_blocks("other_template.html", ["block_a", "block_b"]) template = environment.get_template("my_template.html.jinja2") rendered = template.render(some_var="value") ``` ### Template Usage Within a template, after `setup_globals()` is called: ```jinja {# Render a single block from another template #} {{ render_block("other.html", "sidebar") }} {# Render multiple blocks #} {{ render_blocks("other.html", ["header", "nav"]) {# Override context variables #} {{ render_block("other.html", "content", user_id=123) ``` ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Install the pre-commit framework to automatically format code and run linters on commit. ```shell pre-commit install ``` -------------------------------- ### Install jinja2-fragments Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/installation.md Use this command to install the package from PyPI for standard usage. It has minimal dependencies. ```bash pip install jinja2-fragments ``` -------------------------------- ### Setup Template Globals Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/INDEX.md Install Jinja2 template globals using `setup_globals`. This allows you to call `render_block` and `render_blocks` directly within your Jinja2 templates. ```python from jinja2_fragments import setup_globals setup_globals(environment) ``` -------------------------------- ### FastAPI Basic Setup Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Set up jinja2-fragments with FastAPI. Initialize Jinja2Blocks with the path to your template directory. ```python from fastapi import FastAPI from fastapi.requests import Request from jinja2_fragments.fastapi import Jinja2Blocks app = FastAPI() # Initialize Jinja2Blocks with template directory templates = Jinja2Blocks(directory="path/to/templates") @app.get("/") async def homepage(request: Request): return templates.TemplateResponse(request, "page.html", {"title": "Home"}) ``` -------------------------------- ### Setup Jinja2 globals for render_block and render_blocks Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/api/core.md Install `render_block` and `render_blocks` as Jinja2 template globals. This allows direct use within templates. The correct sync or async callable is chosen based on `environment.is_async`. ```python from jinja2_fragments.api import setup_globals setup_globals(environment) ``` ```jinja {{ render_block("other_template.html", "block_name", key=value) }} {{ render_blocks("other_template.html", ["block_a", "block_b"], key=value) }} ``` -------------------------------- ### Minimum Jinja2 Environment Setup Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md This is the most basic setup required to use jinja2-fragments. It initializes a Jinja2 environment with a file system loader. ```python from jinja2 import Environment, FileSystemLoader from jinja2_fragments import render_block # Minimum required setup environment = Environment( loader=FileSystemLoader("path/to/templates"), ) html = render_block(environment, "template.html", "block_name") ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Install the project in editable mode with development dependencies, including tools for code formatting and linting. ```shell pip install -e .[dev] ``` -------------------------------- ### Template Usage Examples Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/core.md Demonstrates how to use `render_block` and `render_blocks` within Jinja2 templates after `setup_globals()` has been called. These examples show rendering single blocks, multiple blocks, and overriding context variables. ```jinja {# Render a single block from another template #} {{ render_block("other.html", "sidebar") }} ``` ```jinja {# Render multiple blocks #} {{ render_blocks("other.html", ["header", "nav"]) }} ``` ```jinja {# Override context variables #} {{ render_block("other.html", "content", user_id=123) }} ``` -------------------------------- ### Quart Basic Setup Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Quart automatically manages the Jinja2 environment. No additional configuration is needed for basic setup. Ensure TEMPLATES_AUTO_RELOAD is set to True for development. ```python from quart import Quart from jinja2_fragments.quart import render_block, render_blocks app = Quart(__name__) # Configure Quart normally app.config['TEMPLATES_AUTO_RELOAD'] = True # render_block and render_blocks are ready to use (as coroutines) @app.get("/content") async def content(): return await render_block("page.html", "content", user_id=1) ``` -------------------------------- ### Install Package in Development Mode Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/development.md Install the package in editable mode along with development, testing, and documentation dependencies. ```bash pip install -e ".[dev,tests,docs]" ``` -------------------------------- ### Setup Jinja2 Globals Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/core.md Installs `render_block` and `render_blocks` as global functions within a Jinja2 environment. This allows templates to call these functions directly without needing to pass them as context variables. The correct sync or async callable is automatically chosen based on `environment.is_async`. Existing globals with these names are preserved. ```python from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2_fragments import setup_globals environment = Environment( loader=FileSystemLoader("templates"), autoescape=select_autoescape(("html", "jinja2")), ) # Install render_block and render_blocks as template globals setup_globals(environment) # Now templates can call these directly: # {{ render_block("other_template.html", "block_name", key=value) }} # {{ render_blocks("other_template.html", ["block_a", "block_b"]) }} template = environment.get_template("my_template.html.jinja2") rendered = template.render(some_var="value") ``` -------------------------------- ### Flask Basic Setup Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Integrate jinja2-fragments with Flask. Ensure TEMPLATES_AUTO_RELOAD is set for development. The render_block and render_blocks functions are then available for use. ```python from flask import Flask from jinja2_fragments.flask import render_block, render_blocks app = Flask(__name__) # Configure Flask normally app.config['TEMPLATES_AUTO_RELOAD'] = True # Auto-reload templates in dev # render_block and render_blocks are ready to use @app.get("/content") def content(): return render_block("page.html", "content", user_id=1) ``` -------------------------------- ### Install Test Dependencies Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Install the project in editable mode with testing dependencies, including pytest. ```shell pip install -e .[tests] ``` -------------------------------- ### Legacy Signal API Example Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/quart.md Example of sending a signal using the legacy Quart signal API (version < 0.19.0). This method requires specifying `_sync_wrapper` to ensure asynchronous execution. ```python CUSTOM_SIGNAL = True await before_render_template_block.send( app, _sync_wrapper=app.ensure_async, template_name=..., block_name=..., context=... ) ``` -------------------------------- ### Setup Jinja2Blocks for Starlette Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/00-START-HERE.md Initialize `Jinja2Blocks` for use with Starlette applications, specifying the directory where templates are located. This setup is required before using `TemplateResponse` with block names. ```python from starlette.applications import Starlette from starlette.requests import Request from starlette.routing import Route from jinja2_fragments.starlette import Jinja2Blocks templates = Jinja2Blocks(directory="templates") async def handler(request: Request): return templates.TemplateResponse( request, "page.html", block_name="content" ) app = Starlette(routes=[Route("/", handler)]) ``` -------------------------------- ### Type Checking Example with Jinja2 Fragments Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/types.md Illustrates how to use Jinja2 Fragments with type hints for static analysis. Ensure your environment and loader are correctly configured. ```python from jinja2 import Environment, FileSystemLoader from jinja2_fragments import render_block environment: Environment = Environment(loader=FileSystemLoader("templates")) result: str = render_block(environment, "template.html", "block_name") ``` -------------------------------- ### HTMXBlockTemplate Modern Signature Example Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/litestar.md Demonstrates the recommended modern signature for instantiating HTMXBlockTemplate using keyword arguments for clarity and maintainability. ```python HTMXBlockTemplate( template_name="page.html.jinja2", context={"user_id": 1}, block_name="content" ) ``` -------------------------------- ### setup_globals Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/api/core.md Installs `render_block` and `render_blocks` as Jinja2 template globals, allowing them to be called directly within templates. It automatically selects the correct sync or async callable based on the environment's async status and preserves existing globals. ```APIDOC ## setup_globals ### Description Install `render_block` and `render_blocks` as Jinja2 template globals. After calling this function, templates rendered with *environment* can use `render_block` and `render_blocks` directly in expressions: ```jinja {{ render_block("other_template.html", "block_name", key=value) }} {{ render_blocks("other_template.html", ["block_a", "block_b"], key=value) }} ``` The current template context is automatically forwarded; extra keyword arguments override individual context variables. The correct sync or async callable is chosen based on `environment.is_async`. Existing globals named `render_block` and `render_blocks` are preserved. ### Signature ```python def setup_globals(environment: Environment) -> None ``` ### Parameters * **environment** (Environment) - The Jinja2 `Environment` to modify. ``` -------------------------------- ### Setup Litestar with Jinja2 Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Configure Litestar to use Jinja2 as its template engine. Specify the template directory and the Jinja2 engine class. ```python from litestar import Litestar, get from litestar.contrib.jinja import JinjaTemplateEngine from litestar.template.config import TemplateConfig from litestar.response import Template from jinja2_fragments.litestar import HTMXBlockTemplate @get("/") def homepage() -> Template: return HTMXBlockTemplate( template_name="page.html", context={"title": "Home"} ) app = Litestar( route_handlers=[homepage], template_config=TemplateConfig( directory="templates", engine=JinjaTemplateEngine, ), ) ``` -------------------------------- ### Modern Signal API Example Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/quart.md Example of sending a signal using the modern Quart signal API (version >= 0.19.0). This method uses the standard `signal.send()` without explicit async wrapping. ```python CUSTOM_SIGNAL = False await before_render_template_block.send(app, template_name=..., block_name=..., context=...) ``` -------------------------------- ### FastAPI: Setup and render profile details block Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/index.md Integrates jinja2-fragments with FastAPI to render a specific Jinja2 block ('details') for a user profile. Requires 'templates' to be initialized with Jinja2Blocks. ```python from fastapi import FastAPI, Request from jinja2_fragments.fastapi import Jinja2Blocks app = FastAPI() templates = Jinja2Blocks(directory="templates") @app.get("/profile/{username}") def profile(request: Request, username: str): return templates.TemplateResponse( request, "profile.html.jinja2", {"username": username} ) @app.get("/profile/{username}/details") def profile_details(request: Request, username: str): return templates.TemplateResponse( request, "profile.html.jinja2", {"username": username}, block_name="details" ) ``` -------------------------------- ### TemplateResponse Examples with FastAPI Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/starlette-fastapi.md Demonstrates using TemplateResponse with FastAPI for rendering full templates, single blocks, and multiple blocks, which is particularly useful for HTMX out-of-band swaps. ```python from fastapi import FastAPI from fastapi.requests import Request from jinja2_fragments.fastapi import Jinja2Blocks app = FastAPI() templates = Jinja2Blocks(directory="templates") @app.get("/") async def homepage(request: Request): return templates.TemplateResponse( request, "page.html.jinja2", {"title": "Home"} ) @app.get("/sidebar") async def sidebar_only(request: Request): return templates.TemplateResponse( request, "page.html.jinja2", {"user_id": 123}, block_name="sidebar" ) @app.get("/fragments") async def htmx_fragments(request: Request): # Useful for HTMX out-of-band swaps return templates.TemplateResponse( request, "components.html.jinja2", block_names=["notification", "user_menu"] ) ``` -------------------------------- ### Core Rendering Functions Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Provides documentation for the core functions used for rendering Jinja2 blocks, including synchronous and asynchronous operations, and global setup. ```APIDOC ## Core API Reference ### `render_block()` #### Description Render a single Jinja2 block. ### `render_blocks()` #### Description Render multiple Jinja2 blocks. ### `render_block_async()` #### Description Asynchronously render a single Jinja2 block. ### `render_blocks_async()` #### Description Asynchronously render multiple Jinja2 blocks. ### `setup_globals()` #### Description Install template globals for jinja2-fragments. ``` -------------------------------- ### Example Usage of render_block_async Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/core.md Demonstrates how to set up a Jinja2 environment with async mode enabled and then use `render_block_async` to render a specific block from a template. This snippet must be awaited within an async function. ```python from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2_fragments import render_block_async environment = Environment( loader=FileSystemLoader("templates"), autoescape=select_autoescape(("html", "jinja2")), enable_async=True ) async def get_content(): rendered = await render_block_async( environment, "page.html.jinja2", "content", magic_number=42 ) return rendered ``` -------------------------------- ### Explicit Jinja2 Environment Setup with Sanic Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/sanic.md Demonstrates how to provide a custom Jinja2 Environment to the render function in Sanic. This is useful for advanced configurations like custom loaders or autoescaping rules. ```python from jinja2 import Environment, FileSystemLoader, select_autoescape 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="templates")) # Provide explicit environment if needed custom_env = Environment( loader=FileSystemLoader("templates"), autoescape=select_autoescape(("html", "jinja2")), ) @app.get("/custom") async def custom_render(request: Request): return await render( "page.html.jinja2", environment=custom_env, block="content", context={"data": "value"} ) ``` -------------------------------- ### Render Block within Template Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/INDEX.md Example of calling `render_block` and `render_blocks` from within a Jinja2 template after `setup_globals` has been used. ```jinja {{ render_block("other.html", "sidebar", user_id=123) }} {{ render_blocks("other.html", ["header", "nav"]) }} ``` -------------------------------- ### Setup Jinja2 Environment for In-Template Block Rendering Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/basic_usage.md Call `setup_globals` on your Jinja2 environment to make `render_block` and `render_blocks` available within templates. This enables templates to compose fragments from other templates. ```python from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2_fragments import setup_globals environment = Environment( loader=FileSystemLoader("my_templates"), autoescape=select_autoescape(("html", "jinja2")), ) setup_globals(environment) ``` -------------------------------- ### Sanic Setup with Jinja2 Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Sanic requires explicit Jinja2 configuration via sanic_ext. Configure the templating path to your templates directory using sanic_ext.Config. ```python from sanic import Sanic import sanic_ext from jinja2_fragments.sanic import render app = Sanic(__name__) # Configure templating with sanic_ext app.extend( config=sanic_ext.Config(templating_path_to_templates="templates") ) @app.get("/") async def handler(request): return await render("page.html", context={"title": "Home"}) ``` -------------------------------- ### Render Full Page with Sanic Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Use this snippet to render an entire Jinja2 template with Sanic. Ensure 'sanic_ext' and 'Jinja2' are installed. ```python 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}) ``` -------------------------------- ### Setup Jinja2Blocks for FastAPI Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/00-START-HERE.md Configure `Jinja2Blocks` for a FastAPI application, pointing to the template directory. This allows rendering specific blocks within templates using `TemplateResponse`. ```python from fastapi import FastAPI from fastapi.requests import Request from jinja2_fragments.fastapi import Jinja2Blocks app = FastAPI() templates = Jinja2Blocks(directory="templates") @app.get("/content") async def content(request: Request): return templates.TemplateResponse( request, "page.html", block_name="content" ) ``` -------------------------------- ### Auto-Detect Sanic App in render Function Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/sanic.md Shows how the `render` function can automatically detect the current Sanic application if the `app` parameter is omitted. This is useful for simple setups. ```python from sanic import Sanic, Request from jinja2_fragments.sanic import render app = Sanic(__name__) @app.get("/") async def handler(request: Request): # app is auto-detected return await render("page.html.jinja2", context={}) ``` -------------------------------- ### Starlette: Setup and render profile details block Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/index.md Integrates jinja2-fragments with Starlette to render a specific Jinja2 block ('details') for a user profile. Requires 'templates' to be initialized with Jinja2Blocks. ```python from starlette.applications import Starlette from starlette.requests import Request from starlette.routing import Route from jinja2_fragments.starlette import Jinja2Blocks templates = Jinja2Blocks(directory="templates") async def profile(request: Request): username = request.path_params["username"] return templates.TemplateResponse( request, "profile.html.jinja2", {"username": username} ) async def profile_details(request: Request): username = request.path_params["username"] return templates.TemplateResponse( request, "profile.html.jinja2", {"username": username}, block_name="details" ) routes = [ Route("/profile/{username}", profile), Route("/profile/{username}/details", profile_details), ] app = Starlette(routes=routes) ``` -------------------------------- ### Render Full Page with Litestar Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Use this snippet to render an entire Jinja2 template with Litestar using HTMXBlockTemplate. Ensure 'litestar' and 'jinja2_fragments' are installed. ```python 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, ), ) ``` -------------------------------- ### Handle Jinja2 ExtensionNotFound in Sanic Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/errors.md Use when `render()` fails because Jinja2 is not configured or installed. This exception indicates that the Jinja2 template engine is unavailable. Configure Jinja2 using `sanic_ext.Config` to resolve this. ```python from sanic import Sanic from jinja2_fragments.sanic import render from sanic_ext.exceptions import ExtensionNotFound app = Sanic(__name__) # Note: Jinja2 not configured @app.get("/") async def handler(request): try: return await render("page.html", context={}) except ExtensionNotFound as e: print(f"Error: Jinja2 not configured: {e}") ``` ```python import sanic_ext from sanic import Sanic app = Sanic(__name__) app.extend( config=sanic_ext.Config(templating_path_to_templates="templates") ) # Jinja2 now enabled ``` -------------------------------- ### Catching TemplateNotFound Error Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/errors.md Handle cases where a requested template file cannot be found by the Jinja2 environment. This example shows how to catch the `TemplateNotFound` exception and provide fallback content. ```python from jinja2 import Environment, FileSystemLoader, TemplateNotFound from jinja2_fragments import render_block environment = Environment(loader=FileSystemLoader("templates")) try: html = render_block(environment, "missing.html", "block", data=42) except TemplateNotFound as e: print(f"Template not found: {e.name}") # Handle gracefully: return default content or error page html = "
Template not found
" ``` -------------------------------- ### Litestar: Render profile details block with HTMXBlockTemplate Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/index.md Demonstrates using HTMXBlockTemplate in Litestar to render a specific Jinja2 block ('details') for a user profile. This example includes conditional import for different Litestar versions. ```python 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("/profile/{username:str}") def profile(request: HTMXRequest, username: str) -> Template: return HTMXBlockTemplate( template_name="profile.html.jinja2", context={"username": username} ) @get("/profile/{username:str}/details") def profile_details(request: HTMXRequest, username: str) -> Template: return HTMXBlockTemplate( template_name="profile.html.jinja2", block_name="details", context={"username": username}, ) app = Litestar( route_handlers=[profile, profile_details], request_class=HTMXRequest, template_config=TemplateConfig( directory="path/to/templates", engine=JinjaTemplateEngine, ), ) ``` -------------------------------- ### Litestar Jinja2 Block Rendering Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Render Jinja2 blocks in a Litestar application using jinja2-fragments. This example defines a GET route and configures Litestar's template engine. ```python from litestar import Litestar, get from litestar.contrib.jinja import JinjaTemplateEngine from litestar.template.config import TemplateConfig from litestar.response import Template from jinja2_fragments.litestar import HTMXBlockTemplate @get("/content") def content() -> Template: return HTMXBlockTemplate( template_name="page.html", block_name="content", context={"magic_number": 42} ) app = Litestar( route_handlers=[content], template_config=TemplateConfig( directory="templates", engine=JinjaTemplateEngine, ), ) ``` -------------------------------- ### Sanic Jinja2 Block Rendering Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Use jinja2-fragments to render Jinja2 blocks within a Sanic application. This example configures sanic-ext for templating and defines an async GET endpoint. ```python 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="templates")) @app.get("/content") async def content(request: Request): return await render("page.html", block="content", context={"magic_number": 42}) ``` -------------------------------- ### Build Documentation with Sphinx Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/development.md Build the project documentation locally using Sphinx. The output will be in the docs/build/html directory. ```bash cd docs sphinx-build source/ build/ # Or using Make: make html ``` -------------------------------- ### Handle ValueError with HTMXBlockTemplate Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/errors.md Instantiate HTMXBlockTemplate with either block_name or block_names, but not both. This example shows how to catch the ValueError that occurs when both are provided. ```python from litestar import get from jinja2_fragments.litestar import HTMXBlockTemplate @get("/") def handler() -> HTMXBlockTemplate: try: return HTMXBlockTemplate( template_name="page.html", block_name="content", block_names=["header", "footer"], # Error: cannot specify both ) except ValueError as e: print(f"Error: {e}") # Output: "Set only the block_name or the block_names input argument, but not both." ``` -------------------------------- ### Recommended Jinja2 Environment Configuration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md This configuration includes recommended settings for autoescaping and optionally sets up global functions for convenience. It also shows how to pass context variables to render_block. ```python from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2_fragments import render_block, setup_globals environment = Environment( loader=FileSystemLoader("path/to/templates"), autoescape=select_autoescape( enabled_extensions=("html", "jinja2"), default_for_string=True, default=True ), enable_async=False, # Set to True for async rendering ) # Optional: Install render_block and render_blocks as globals setup_globals(environment) html = render_block(environment, "template.html", "block_name", key="value") ``` -------------------------------- ### Catching BlockNotFoundError Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/errors.md Demonstrates how to catch and handle a BlockNotFoundError when a requested block does not exist in the template. This example shows how to access the error attributes for more context. ```python from jinja2 import Environment, FileSystemLoader from jinja2_fragments import render_block, BlockNotFoundError environment = Environment(loader=FileSystemLoader("templates")) try: html = render_block(environment, "page.html", "nonexistent_block", data=42) except BlockNotFoundError as e: print(f"Missing block '{e.block_name}' in '{e.template_name}'") # Handle gracefully: use a fallback block or return empty string html = "" ``` -------------------------------- ### HTMXBlockTemplate Legacy Signature Example Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/litestar.md Illustrates the legacy signature for HTMXBlockTemplate, which uses multiple positional arguments. This signature is deprecated and will issue a DeprecationWarning. ```python # Passing multiple positional arguments is deprecated HTMXBlockTemplate( "page.html.jinja2", push_url="/page", re_swap="outerHTML", block_name="content" ) ``` -------------------------------- ### Quart Integration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Documentation for Quart async integration, covering rendering functions, async signal handling, and application context integration. ```APIDOC ## Quart Integration ### Quart async `render_block()` and `render_blocks()` #### Description Provides Quart-specific asynchronous implementations for rendering single and multiple Jinja2 blocks. ### Async Signal Handling (Quart 0.19.0+ and legacy) #### Description Covers asynchronous signal handling for Quart, supporting both newer versions (0.19.0+) and legacy implementations. ### Integration with Quart Application Context #### Description Details on how to integrate jinja2-fragments with Quart application contexts. ``` -------------------------------- ### Configure FileSystemLoader with Multiple Directories Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Load templates from multiple directories by providing a list of paths to FileSystemLoader. Jinja2 will search these directories in order. ```python # Multiple directories environment = Environment( loader=FileSystemLoader(["templates", "emails"]) ) ``` -------------------------------- ### Configure FileSystemLoader with a Single Directory Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Use FileSystemLoader to load templates from a single directory. This is the recommended approach for most projects. ```python from jinja2 import Environment, FileSystemLoader environment = Environment( loader=FileSystemLoader("templates") # Single directory ) ``` -------------------------------- ### Handle Litestar BlockNotFoundError Exception Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/types.md Provides an example of an exception handler for BlockNotFoundError in a Litestar application. This handler returns a JSON response with a 404 status code. ```python from litestar import Litestar, get from litestar.exceptions import HTTPException from jinja2_fragments.litestar import HTMXBlockTemplate, BlockNotFoundError @app.exception_handler(BlockNotFoundError) def handle_missing_block(request, exc: BlockNotFoundError): return JSONResponse( status_code=404, content={ "error": f"Block '{exc.block_name}' not found in '{exc.template_name}'" } ) ``` -------------------------------- ### Quart: Render full profile template Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/index.md Use this to render a complete HTML template for a user profile in a Quart application. Note the use of 'async' and 'await'. ```python from quart import Quart, render_template from jinja2_fragments.quart import render_block app = Quart(__name__) @app.route("/profile/