Template Rendering (Jinja2)
In Lila, you can use Jinja2 to render HTML with server data
Jinja2 is the default for rendering HTML templates. You can pass
data like translations, values, lists, or dictionaries using the
context
parameter.
Basic Usage in Routes
from lila.core.templates import render
from lila.core.responses import Response
from lila.core.routing import Router
from lila.core.request import Request
router = Router()
@router.get("/")
async def home(request: Request):
"""Home page"""
context = {
"title": "Lila Framework",
"message": "Hello from Lila!"
}
response = render(
request,
"index.html", # HTML template name in resources/html/
context=context
)
# Renders the 'index' template
return response
routes=router.get_routes()
The render Function
The
render
function is located in
lila.core.templates:
def render(request: Request, template: str, context: dict = None, files_translate: list[str] = None, lang_default: str = None):
Parameter Description
-
request:
The
Requestobject. -
template (str):
Template name (without the
.htmlextension). -
context (dict):
Data to pass to the template (dictionaries, lists, etc.).
-
files_translate (list):
List of additional translation files.
-
lang_default (str):
Forced default language (ideal for SEO in routes like
/es,/en, etc.).
In Lila, you can also use
translate
to pass translations to Jinja2, and parameters like
title
or
version
(ideal for structuring APIs: "v1", "v2").
Base Context Injection
All optimization features work thanks to the base context automatically injected into Jinja2 templates:
def get_base_context(request, files_translate=[], lang_default=None):
context = {
"title": TITLE_PROJECT,
"version": VERSION_PROJECT,
"lang": lang_default if lang_default else lang(request),
"translate": t("translations", request, lang_default=lang_default),
"description": DESCRIPTION_DEFAULT,
"keywords": KEYWORDS_DEFAULT,
"author": AUTHOR_DEFAULT,
}
for file_name in files_translate:
context["translate"].update(
t(file_name, request, lang_default=lang_default)
)
return context
Jinja2 Helpers
Lila provides several helpers to make your templates more powerful:
-
hot_reload():
Injects Vite's Hot Module Replacement (HMR) scripts. Only active when DEBUG=True. Place it in the
<head>of your main layout. -
public(path):
Resolves paths to static assets under the
public/directory. In addition, it automatically checks the system assets manifest in RAM to swap files for their optimized, compressed, or minified versions (e.g., swapping.cssfor.min.css, or images for their highly optimized.webpversions) in production seamlessly. -
asset(path):
Resolves and returns the full HTML tag (e.g.
<link rel="stylesheet">or<script>) for CSS/JS assets, supporting both Vite live HMR development and zero-dependency fallbacks:
• Single Source of Truth: You write code exclusively in theresources/folder (e.g.resources/js/utils.js,resources/js/spa.js,resources/css/tailwind.css).
• Development Mode (HMR): In development (DEBUG=True), the assets are served hot from Vite's development server (http://localhost:5173) with instant browser updates upon file edits.
• Production & Fallbacks: When you runnpm run build, Vite compiles, minifies, and bundles these assets directly into their standard physical locations inpublic/(e.g.public/js/utils.js). In production (DEBUG=False), or if Node.js/Vite is not active, Lila serves these pre-compiled and optimized static assets directly with zero performance overhead.
• Smart Play CDN Fallback: If Node.js/Vite is not installed yet, callingasset('css/tailwind.css')automatically loads the official Tailwind CSS Play CDN to keep your styles fully functional out-of-the-box!
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<!-- Load Tailwind CSS v4 dynamically with CDN fallback and HMR support -->
{{ asset('css/tailwind.css') | safe }}
</head>
<body>
<h1>Welcome to Lila!</h1>
<!-- Load javascript -->
<script src="{{ public('js/main.js') }}"></script>
<!-- Inject Vite hot-reload script in development mode -->
{{ hot_reload() | safe }}
</body>
</html>
Single Page Application (SPA) Engine
Lila includes a built-in SPA navigation engine. It seamlessly converts your standard server-rendered templates into a blazing fast Single Page Application.
How it works
When you click a link, the spa.js script intercepts the request. The backend detects this via the
source=frontend query parameter and the X-Lila-SPA header. Instead of sending the full
HTML document, Lila only renders and returns a JSON payload containing the {% block content %},
updated title, meta tags, and any new CSS/JS.
Lifecycle Events
Since SPA navigation doesn't trigger a full page reload, the standard DOMContentLoaded event only
fires once. Lila provides custom events to handle content updates:
-
lila:content-loaded:
Fires every time the content is updated via SPA. Use this to initialize scripts or mount components.
document.addEventListener('lila:content-loaded', (e) => {
console.log('New page loaded:', e.detail.url);
// Initialize your components here
});
Script Re-execution
Lila automatically re-executes scripts found in the partial content. For external scripts that must be re-loaded
every time, you can use the data-spa-reload attribute.
Opting out or Disabling
The SPA behavior is enabled by default. If you don't want to use it, you have two options:
-
Disable globally:
Comment out or remove the
<script src="{{ public('js/spa.js') }}"></script>tag from yourbase.html. -
Disable per link:
Add the
data-no-spaattribute to any<a>tag.
<a href="/logout" data-no-spa>Logout</a>
Development Hot Reload (Vite)
Lila comes integrated with a super-fast development hot reload (HMR) system powered by Vite. When active, saving
any .html, .jinja, or .md file in your resources/ folder
triggers an instant full page reload in the browser.
Setup Instructions
-
Install Node.js & npm: Make sure you have Node.js and
npminstalled on your system. -
Install Dependencies: Run the following command in your project root to install the Vite and
Tailwind CSS dev tools:
npm install -
Restart Python Server: Stop and restart your python backend (e.g.
python main.py). This allows Lila to scan the project directory, automatically detect thepackage-lock.jsonfile, and confirm the environment is set up. -
Enable Debug Mode: Ensure
DEBUG=Trueis set in your.envfile. -
Run Vite Dev Server: In a separate terminal tab, run the dev server:
npm run dev
Integrating the Hot Reload Script
To include the live-reloader in your pages, Lila provides the hot_reload() global helper. Make sure
your base HTML template (typically located at resources/html/lila/base.html) includes the following
line inside its <body> tag:
<body>
<!-- Your layout content here -->
<!-- Inject Vite hot-reload script in development mode -->
{{ hot_reload() | safe }}
</body>
Note: In production (when DEBUG=False in .env), the
hot_reload() helper returns an empty string "" automatically, introducing zero
overhead to your application.
Lila Premium CSS Utility Components
To accelerate your UI development and enable rapid, professional prototyping, Lila packages a set of pre-configured, high-performance Tailwind CSS utility classes inside resources/css/tailwind.css. All of them natively support Dark Mode:
-
.cardA beautiful, fully-responsive Material Design container card with light/dark border coloring, rounded-2xl padding, and smooth transition shadows.
-
.text-lilaA premium, high-impact gradient title class styling using Lila's custom primary/secondary colors. Ideal for hero headers!
-
.input-lilaA state-of-the-art interactive input class with elegant borders, dynamic focus ring effects, light/dark text support, and a smooth cursor placeholder transition.
-
.link-lilaA gorgeous navigational anchor link styling with custom primary color transitions and sleek animated underlines.
-
.btn-primary/.btn-secondary/.btn-outlinePre-configured button styles featuring smooth translate-y hover elevations, beautiful color variations, and integrated loading/icon layout alignment.
Performance Optimizations
Lila is designed for high performance. Templates are optimized through several mechanisms:
- Request State Caching: Core data like the current language and SEO metadata are cached in the request object to avoid redundant processing or cryptographic operations.
- Translation Caching: Processed translation dictionaries are cached in memory per language.
- Template Minification: In production, HTML templates are automatically minified to reduce payload size.