Flaxon 0.3.0 and Teloce-Py 0.3.0 are available on PyPI. Release instructions are maintained on this site; source links identify the framework snapshot. Check version and upgrade guidance.

Framework source · Markdown

Jinax Templates

Overview

Jinax is Flaxon's optional server-side template engine powered by Jinja2.

It provides modern HTML rendering while integrating seamlessly with Flaxon's async-first architecture.

Features

  • Server-side HTML rendering
  • Template inheritance
  • Automatic HTML escaping
  • Async rendering
  • Custom filters
  • Custom global functions
  • Template caching
  • Hot reloading during development
  • Macros
  • Includes
  • Layouts
  • Jinja2 template caching and configurable reload behavior

Installation

Install Flaxon with template support:

pip install flaxon[templates]

Setup

Configure Jinax with your application.

from flaxon import Flaxon
from flaxon.jinax import Jinax


app = Flaxon("website")


app.use_templates(

    Jinax(
        "templates",
        auto_reload=True
    )

)

Project Structure

A typical project looks like:

project/

├── app.py
├── templates/
│   ├── base.html
│   ├── home.html
│   ├── about.html
│   ├── contact.html
│   ├── macros.html
│   └── partials/
│       ├── navbar.html
│       └── footer.html
└── static/
    ├── css/
    ├── js/
    └── images/

Rendering Templates

Templates are rendered using the request object.

@app.get("/")
async def home(request):

    return await request.render(

        "home.html",

        {
            "title": "Home",

            "name": "World",

            "items": [
                "Routing",
                "Templates",
                "Validation"
            ]
        }

    )

Your First Template

Create:

templates/home.html
<!DOCTYPE html>

<html>

<head>

    <title>{{ title }}</title>

</head>

<body>

    <h1>
        Welcome {{ name }}!
    </h1>

    <ul>

        {% for item in items %}

            <li>{{ item }}</li>

        {% endfor %}

    </ul>

</body>

</html>

Complete copy-paste application

Create app.py:

from flaxon import Flaxon
from flaxon.jinax import Jinax

app = Flaxon("jinax-example", debug=True)
app.use_templates(Jinax("templates", auto_reload=True))

@app.get("/")
async def home(request):
    return await request.render("home.html", {
        "title": "Jinax",
        "items": ["Routing", "Validation", "Templates"],
    })

Create templates/home.html:

<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>{{ title }}</title></head>
<body><h1>{{ title }}</h1>
<ul>
    {% for item in items %}
    <li>{{ item }}</li>
    {% endfor %}
    </ul>
</body>
</html>

Run pip install "flaxon[templates]" and then flaxon run app:app --reload. Jinax uses Jinja2 autoescaping for HTML templates. Keep database queries and permission decisions in routes/services and pass prepared view data to templates.


Template Inheritance

Inheritance allows pages to share a common layout.

Base Template

templates/base.html
<!DOCTYPE html>

<html>

<head>

    <title>

        {% block title %}
            Flaxon
        {% endblock %}

    </title>

</head>

<body>

<header>

    {% block header %}

        Default Header

    {% endblock %}

</header>

<main>

    {% block content %}

    {% endblock %}

</main>

<footer>

    {% block footer %}

        Copyright © 2026

    {% endblock %}

</footer>

</body>

</html>

Child Template

templates/home.html
{% extends "base.html" %}

{% block title %}

Home

{% endblock %}


{% block header %}

Welcome

{% endblock %}


{% block content %}

<h1>{{ heading }}</h1>

<p>{{ description }}</p>

{% endblock %}

Including Templates

Reusable components can be included.

{% include "partials/navbar.html" %}

<h1>Home</h1>

{% include "partials/footer.html" %}

Built-in Filters

Jinax includes many commonly used filters.

Filter Description
capitalize Capitalize text
lower Convert to lowercase
upper Convert to uppercase
title Title case
trim Remove whitespace
escape Escape HTML
safe Mark content as safe
json Convert to JSON
length Count items
reverse Reverse a sequence
join Join list items
replace Replace text
default Default value
first First item
last Last item
truncate Shorten text
date Format dates
datetime Format date and time
currency Format currency

Filter Examples

{{ name|capitalize }}

{{ username|lower }}

{{ price|currency("USD") }}

{{ description|truncate(100) }}

{{ tags|join(", ") }}

{{ created_at|datetime("%Y-%m-%d %H:%M") }}

Custom Filters

Create your own filters.

jinax = Jinax(
    "templates"
)


def currency_filter(
    value,
    symbol="$"
):

    return f"{symbol}{value:,.2f}"


jinax.add_filter(

    "currency",

    currency_filter

)

Using the filter:

<p>

Price:

{{ product.price|currency("$") }}

</p>

Global Functions

Global functions can be registered and used directly inside templates.

jinax = Jinax(
    "templates"
)


def get_user(username):

    return {
        "name": username,
        "email": f"{username}@example.com"
    }


jinax.add_global(
    "get_user",
    get_user
)

Using the function:

{% set user = get_user("alice") %}

<h2>{{ user.name }}</h2>

<p>{{ user.email }}</p>

Global Variables

Global variables are available in every template.

jinax.add_global(
    "site_name",
    "Flaxon"
)

jinax.add_global(
    "version",
    "0.1.0"
)

Template:

<footer>

{{ site_name }}

Version {{ version }}

</footer>

Macros

Macros allow reusable template components.

Create:

templates/macros.html
{% macro render_card(title, content, color="blue") %}

<div class="card card-{{ color }}">

    <h3>{{ title }}</h3>

    <p>{{ content }}</p>

</div>

{% endmacro %}

Using the macro:

{% import "macros.html" as macros %}

{{ macros.render_card(

    "Welcome",

    "Hello from Jinax",

    "green"

) }}

Control Statements

Jinax supports standard template control statements.

Loop:

<ul>

{% for product in products %}

    <li>

        {{ product.name }}

    </li>

{% endfor %}

</ul>

Conditional:

{% if user %}

    <h2>

        Welcome {{ user.name }}

    </h2>

{% else %}

    <h2>

        Welcome Guest

    </h2>

{% endif %}

Async Rendering

Jinax fully supports asynchronous rendering.

@app.get("/dashboard")
async def dashboard(request):

    users = await database.get_users()

    return await request.render(

        "dashboard.html",

        {

            "users": users

        }

    )

Hot Reloading

During development templates can automatically reload.

app.use_templates(

    Jinax(

        "templates",

        auto_reload=True

    )

)

Hot reloading should normally be disabled in production.


Template Caching

Enable template caching for production deployments.

jinax = Jinax(

    "templates",

    cache_size=100

)

Larger applications may increase the cache size.


Autoescaping

Jinax automatically escapes HTML output to reduce XSS risks.

Example:

{{ username }}

Output:

<script>alert("XSS")</script>

becomes

&lt;script&gt;alert("XSS")&lt;/script&gt;

Safe HTML

Only mark trusted HTML as safe.

{{ article.body|safe }}

Avoid using safe with untrusted user input.


Static Files

Reference static assets inside templates.

<link
    rel="stylesheet"
    href="/static/css/style.css"
>

<script
    src="/static/js/app.js"
></script>

Complete Example

from datetime import datetime

from flaxon import Flaxon

from flaxon.jinax import Jinax


app = Flaxon(
    "website-demo"
)


app.use_templates(

    Jinax(

        "templates",

        auto_reload=True

    )

)


jinax = app.jinax


def currency(
    value,
    symbol="$"
):

    return f"{symbol}{value:,.2f}"


jinax.add_filter(
    "currency",
    currency
)


def now():

    return datetime.now().strftime(
        "%Y-%m-%d %H:%M:%S"
    )


jinax.add_global(
    "now",
    now
)


@app.get("/")
async def home(request):

    products = [

        {
            "name": "Laptop",
            "price": 999.99
        },

        {
            "name": "Keyboard",
            "price": 49.99
        },

        {
            "name": "Mouse",
            "price": 19.99
        }

    ]


    return await request.render(

        "home.html",

        {

            "title": "Store",

            "products": products

        }

    )

Example template:

templates/home.html
{% extends "base.html" %}

{% block title %}

{{ title }}

{% endblock %}


{% block content %}

<h1>

Welcome to our Store

</h1>

<div class="products">

{% for product in products %}

<div class="product">

    <h3>

        {{ product.name }}

    </h3>

    <p>

        {{ product.price|currency("$") }}

    </p>

</div>

{% endfor %}

</div>

<p>

Generated:

{{ now() }}

</p>

{% endblock %}

Security

Jinax enables HTML autoescaping by default.

Recommended practices:

  • Keep autoescaping enabled.
  • Never trust user-generated HTML.
  • Only use the safe filter with trusted content.
  • Validate all user input.
  • Use Content Security Policy (CSP) where appropriate.
  • Sanitize uploaded HTML before rendering.

Performance Tips

For production deployments:

  • Enable template caching.
  • Disable hot reloading.
  • Reuse template environments.
  • Cache expensive database queries.
  • Minimize complex template logic.
  • Perform heavy processing inside Python instead of templates.

Debugging

When Flaxon runs in debug mode, template errors appear in the Debug Dashboard.

Open:

http://localhost:8000/__debug__

The debugger records:

  • Template syntax errors
  • Missing templates
  • Undefined variables
  • Rendering exceptions
  • Stack traces
  • Request information
  • Error history

Sensitive information is automatically redacted.


Best Practices

  • Keep business logic inside Python.
  • Keep templates focused on presentation.
  • Use template inheritance.
  • Reuse components with macros and includes.
  • Organize templates into folders.
  • Prefer descriptive template names.
  • Enable caching in production.
  • Use async rendering when loading data.

project/

├── app.py
├── templates/
│   ├── base.html
│   ├── home.html
│   ├── about.html
│   ├── contact.html
│   ├── macros.html
│   ├── layouts/
│   ├── partials/
│   │   ├── navbar.html
│   │   ├── sidebar.html
│   │   └── footer.html
│   ├── auth/
│   ├── admin/
│   ├── errors/
│   └── emails/
└── static/
    ├── css/
    ├── js/
    ├── fonts/
    └── images/

API Reference

See the Jinax API Reference for complete documentation of:

  • Jinax
  • Template rendering
  • Filters
  • Globals
  • Macros
  • Async rendering
  • Template caching
  • Autoescaping

Next Steps

Continue with:

  • Authentication
  • Databases
  • Security
  • Performance
  • Debugging
  • GraphQL
  • Deployment
  • Architecture

Use this capability in a full-stack app

Flaxon serves Python APIs and Teloce interfaces in one project. Keep validation, authorization and privileged operations on the server; components call those endpoints and present their results. Follow the full-stack lessons and Teloce integration reference to connect this capability to pages, components and application modules.