Skip to content

Templates

bluefox-core sets up a Jinja2 environment with an extensible template loader. This lets extension packages (like bluefox-components) register their own template directories alongside your app's templates.

How it works

create_bluefox_app() calls setup_templates() which:

  1. Creates a jinja2.Environment with a FileSystemLoader
  2. If a templates/ directory exists in the working directory, adds it as the first search path
  3. Stores the environment at app.state.templates

Templates are autoescaped for .html and .xml files.

Using templates

Render templates in your routes:

from fastapi import APIRouter, Request
from starlette.responses import HTMLResponse

router = APIRouter()

@router.get("/", response_class=HTMLResponse)
async def home(request: Request):
    env = request.app.state.templates
    template = env.get_template("home.html")
    return HTMLResponse(template.render(title="My App"))

Adding template directories

Extension packages can register additional template search directories:

from pathlib import Path
from bluefox_core import add_template_directory

def setup_components(app):
    """Register bluefox-components templates."""
    pkg_templates = Path(__file__).parent / "templates"
    add_template_directory(app, pkg_templates)

This enables templates like:

{% extends "bfx/base.html" %}
{% from "bfx/button.html" import button %}

Search order

Template directories are searched in order:

  1. App templates (templates/ in working directory) — highest priority
  2. Package templates — added via add_template_directory(), in order of registration

This means your app can override any package template by creating a file with the same path in your own templates/ directory.