Skip to main content

Template Overview

Framefox uses Jinja2 as its templating engine, providing a powerful and familiar way to create dynamic HTML views. The template system is integrated directly into the framework’s MVC architecture, making it easy to render views from your controllers.

Jinja2 Templating Engine

Jinja2 is a modern and designer-friendly templating language for Python. It provides:
  • Template inheritance with {% extends %} and {% block %}
  • Control structures like loops and conditionals
  • Filters for data transformation
  • Template inclusion for reusable components
  • Auto-escaping for XSS prevention

The render() Method

Controllers inherit from AbstractController and use the render() method to return HTML responses:
from framefox.core.controller.abstract_controller import AbstractController
from framefox.core.routing.decorator.route import Route

class UserController(AbstractController):
    
    @Route("/users", "user.index", methods=["GET"])
    async def index(self):
        users = await self.user_repository.find_all()
        return self.render("user/index.html", {"users": users})
    
    @Route("/users/{id}", "user.show", methods=["GET"])
    async def show(self, id: int):
        user = await self.user_repository.find(id)
        return self.render("user/show.html", {"user": user})

Method Signature

def render(self, template_path: str, context: dict = None) -> HTMLResponse:
    """
    Renders a template file with optional context data.
    
    Args:
        template_path: Path to the template file (relative to templates directory)
        context: Dictionary of variables to pass to the template
    
    Returns:
        HTMLResponse: The rendered template as an HTML response
    """

Template Locations

Framefox looks for templates in multiple directories:

1. User Template Directory

Your application templates are stored in the templates/ directory (configurable via settings):
my-project/
├── templates/
│   ├── base.html
│   ├── user/
│   │   ├── index.html
│   │   └── show.html
│   └── products/
│       ├── list.html
│       └── detail.html

2. Framework Template Directory

Framefox includes built-in templates for error pages and debug views located in framefox/core/templates/views/.

Template Resolution

The template loader searches directories in order:
  1. User templates directory (your application)
  2. Framework templates directory (built-in views)
This allows you to override framework templates by creating files with the same path in your templates directory.

Basic Template Example

<!-- templates/user/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Users</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <h1>Users</h1>
    
    {% for user in users %}
        <div class="user-card">
            <h3>{{ user.name }}</h3>
            <p>{{ user.email }}</p>
            <a href="{{ url_for('user.show', id=user.id) }}">View Profile</a>
        </div>
    {% endfor %}
</body>
</html>

Context Variables

The context dictionary passed to render() becomes available as variables in your template:
# In controller
return self.render("products/list.html", {
    "products": products,
    "category": category,
    "page_title": "Product Catalog"
})
<!-- In template -->
<h1>{{ page_title }}</h1>
<p>Category: {{ category }}</p>

{% for product in products %}
    <div>{{ product.name }}</div>
{% endfor %}

Auto-Injected Variables

Framefox automatically injects certain variables into all templates:
  • request - The current HTTP request object
  • current_user - The authenticated user (if any)
You can access these without explicitly passing them in the context:
{% if current_user %}
    <p>Welcome, {{ current_user.name }}!</p>
{% endif %}

<p>Request path: {{ request.url.path }}</p>

Template Configuration

Configure template settings in your config/settings.yaml:
template_dir: "templates"
base_url: "http://localhost:8000"

Performance

Framefox’s template system includes:
  • Automatic template caching in Jinja2
  • Built-in profiling to measure render times
  • Memory tracking for template rendering
  • Strict undefined variables to catch errors early

Next Steps

Build docs developers (and LLMs) love