### 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/") async def profile(username): return await render_template("profile.html.jinja2", username=username) ``` -------------------------------- ### Starlette: Initialize Jinja2Blocks Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/framework_integrations.md Initialize `Jinja2Blocks` for use with Starlette or FastAPI applications. Specify the directory containing your templates. ```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="path/to/templates") ``` -------------------------------- ### Use HTMXBlockTemplate in Litestar Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/00-START-HERE.md Utilize `HTMXBlockTemplate` for rendering specific blocks within templates in a Litestar application. Configure the template engine and directory in the `Litestar` app setup. ```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" ) app = Litestar( route_handlers=[content], template_config=TemplateConfig( directory="templates", engine=JinjaTemplateEngine, ), ) ``` -------------------------------- ### Async Jinja2 Environment Configuration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md This snippet demonstrates how to configure the Jinja2 environment for asynchronous rendering by setting `enable_async=True`. It also shows how to conditionally use async or sync rendering functions based on the environment's async status. ```python # For async rendering with render_block_async() or render_blocks_async() environment = Environment( loader=FileSystemLoader("templates"), enable_async=True, autoescape=select_autoescape(("html", "jinja2")), ) # Check if async is enabled if environment.is_async: html = await render_block_async(environment, "template.html", "block") else: html = render_block(environment, "template.html", "block") ``` -------------------------------- ### Run Pre-commit Hooks Manually Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/docs/source/development.md Manually run all configured pre-commit hooks across all project files. ```bash pre-commit run --all-files ``` -------------------------------- ### Handle BlockNotFoundError Exception in Litestar Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/litestar.md An example exception handler for Litestar to gracefully manage BlockNotFoundError exceptions during template rendering. It returns a JSON response indicating the error. ```python from jinja2_fragments.litestar import BlockNotFoundError, HTMXBlockTemplate @app.exception_handler(BlockNotFoundError) def handle_block_not_found(request, exc: BlockNotFoundError): return JSONResponse( status_code=404, content={ "error": "Block not found", "block": exc.block_name, "template": exc.template_name } ) ``` -------------------------------- ### Explicitly Provide Sanic App to render Function Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/sanic.md Illustrates how to explicitly pass the Sanic application instance to the `render` function. This is recommended when multiple Sanic apps are running or auto-detection might be ambiguous. ```python # This raises SanicException if multiple apps exist await render("page.html.jinja2", context={}) # Solution: provide app explicitly await render("page.html.jinja2", app=app, context={}) ``` -------------------------------- ### Handle Jinja2 Rendering Signals in Quart Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/quart.md Connect to `before_render_template_block` and `template_block_rendered` signals to execute custom logic before and after rendering a Jinja2 block in Quart. Import the necessary signals and connect them using `connect_via`. ```python from quart import Quart from jinja2_fragments.quart import ( render_block, before_render_template_block, template_block_rendered, ) app = Quart(__name__) @before_render_template_block.connect_via(app) async def before_render(sender, template_name, block_name, context, **kwargs): print(f"About to render block {block_name} from {template_name}") @template_block_rendered.connect_via(app) async def after_render(sender, template_name, block_name, context, **kwargs): print(f"Finished rendering block {block_name}") @app.get("/content") async def content(): return await render_block("page.html.jinja2", "content", user_id=1) ``` -------------------------------- ### Import Quart Signals Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/quart.md Import necessary signals from the jinja2_fragments.quart module to interact with template rendering events. ```python from jinja2_fragments.quart import ( before_render_template_block, template_block_rendered, before_render_template_blocks, template_blocks_rendered, ) ``` -------------------------------- ### Flask Integration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Documentation for Flask-specific functions and integration points, including rendering functions, signal definitions, and context integration. ```APIDOC ## Flask Integration ### Flask-specific `render_block()` and `render_blocks()` #### Description Provides Flask-specific implementations for rendering single and multiple Jinja2 blocks. ### Signal Definitions and Examples #### Description Details on signal definitions and usage examples within a Flask context. ### Context Integration with Flask Apps #### Description Information on integrating jinja2-fragments with Flask application contexts. ``` -------------------------------- ### Render Blocks with Sequence of Strings Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/types.md Demonstrates how to use the render_blocks function with different sequence types for block names. Accepts lists, tuples, or any Sequence[str] implementation. ```python from jinja2_fragments import render_blocks # All of these are valid rendered = render_blocks(env, "template.html", ["block1", "block2"]) rendered = render_blocks(env, "template.html", ("block1", "block2")) ``` -------------------------------- ### Handle BlockNotFoundError in Litestar Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/errors.md Register an exception handler for BlockNotFoundError to gracefully manage cases where a specified block does not exist in the template during ASGI response generation. This example shows how to define a handler and trigger the error. ```python from litestar import Litestar, get, exception_handler from litestar.response import Template from jinja2_fragments.litestar import HTMXBlockTemplate, BlockNotFoundError @exception_handler(BlockNotFoundError) def handle_block_not_found(request, exc: BlockNotFoundError): return {"error": f"Block '{exc.block_name}' not found"}, 404 @get("/") def handler() -> Template: return HTMXBlockTemplate( template_name="page.html", block_name="nonexistent" # Will raise BlockNotFoundError if not found ) ``` -------------------------------- ### Sanic Integration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Documentation for Sanic integration, including the `render()` function, block rendering, and automatic async detection. ```APIDOC ## Sanic Integration ### Sanic `render()` function #### Description Documentation for the `render()` function provided for Sanic applications. ### Single and multiple block rendering #### Description Covers the capability to render both single and multiple Jinja2 blocks within Sanic. ### Automatic async detection via `TEMPLATING_ENABLE_ASYNC` #### Description Explains how asynchronous rendering is automatically detected based on the `TEMPLATING_ENABLE_ASYNC` setting. ### Request context integration #### Description Information on integrating jinja2-fragments with Sanic request contexts. ``` -------------------------------- ### Render Jinja2 Block in Quart Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/api-reference/quart.md Use `render_block` to asynchronously render a specific block from a Jinja2 template within a Quart application. This function automatically handles Quart's app context and signals. Ensure Quart is installed and imported. ```python from quart import Quart, render_template from jinja2_fragments.quart import render_block app = Quart(__name__) @app.get("/content") async def get_content(): # Render just the content block from page.html.jinja2 html = await render_block("page.html.jinja2", "content", magic_number=42) return html @app.get("/page") async def full_page(): # Render the full template return await render_template("page.html.jinja2", magic_number=42) @app.get("/sidebar") async def sidebar(): # Render just the sidebar block with context html = await render_block("page.html.jinja2", "sidebar", user_name="Alice") return html ``` -------------------------------- ### Core API (Vanilla Jinja2) Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/00-START-HERE.md Functions for rendering Jinja2 blocks directly using a Jinja2 environment. ```APIDOC ## Core API (Vanilla Jinja2) ### `render_block(env, template, block)` Renders a specific block from a Jinja2 template. ### `render_blocks(env, template, blocks)` Renders multiple blocks from a Jinja2 template. ### `render_block_async()` Asynchronously renders a specific block from a Jinja2 template. ### `setup_globals()` Sets up global functions for use within Jinja2 templates. ``` -------------------------------- ### Run Test Suite Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/README.md Execute the project's test suite using pytest. ```shell pytest ``` -------------------------------- ### Flask: 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 Flask application. ```python from flask import Flask, render_template from jinja2_fragments.flask import render_block app = Flask(__name__) @app.route("/profile/") def profile(username): return render_template("profile.html.jinja2", username=username) ``` -------------------------------- ### Litestar Integration Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/README.md Documentation for Litestar integration, including the `HTMXBlockTemplate` class and `to_asgi_response()` method. ```APIDOC ## Litestar Integration ### `HTMXBlockTemplate` class #### Description Documentation for the `HTMXBlockTemplate` class, tailored for Litestar applications and HTMX. ### `to_asgi_response()` method #### Description Details on using the `to_asgi_response()` method for generating ASGI responses. ### HTMX response header support #### Description Information regarding support for HTMX-specific response headers. ### Litestar-specific `BlockNotFoundError` #### Description Details on the Litestar-specific `BlockNotFoundError` exception. ``` -------------------------------- ### Jinja2 Template Engine Options Source: https://github.com/sponsfreixes/jinja2-fragments/blob/main/_autodocs/configuration.md Configure additional Jinja2 options, such as a post-configuration hook using engine_callback. ```python from litestar.template.config import TemplateConfig from litestar.contrib.jinja import JinjaTemplateEngine config = TemplateConfig( directory="templates", engine=JinjaTemplateEngine, # Additional Jinja2 options engine_callback=lambda engine: engine, # Post-configuration hook ) ```