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:
-
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">) for CSS/JS assets, loading the zero-dependency Google Fonts, Tailwind Play CDN, theme variables, and custom Lila styles dynamically.
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<!-- Load Tailwind CSS v4 browser runtime and theme variables -->
{{ asset('js/tailwind.js') | safe }}
</head>
<body>
<h1>Welcome to Lila!</h1>
<!-- Load javascript -->
<script src="{{ public('js/main.js') }}"></script>
</body>
</html>
CSRF Protection in Templates
When rendering a form that requires CSRF protection, pass csrf=True to the render() function. This generates a signed token, sets the _csrf cookie, and injects csrf_token into the template context.
-
render(request, template, csrf=True):
Generates a CSRF token, injects it as
csrf_tokenin the context, and sets the signed_csrfcookie on the response. -
csrf_input:
Jinja2 context variable injected by
render(csrf=True). Renders<input type="hidden" name="csrf" id="csrf" value="TOKEN" />. Use with the| safefilter. Therequestobject is never exposed to the template.
from lila.core.templates import render
from lila.core.middleware import csrf
@router.get('/contact')
async def contact_page(request: Request):
return render(request, 'contact', csrf=True)
@router.post('/contact')
@csrf
async def contact_submit(request: Request):
return JSONResponse({"success": True})
<form method="POST" action="/contact">
{{ csrf_input | safe }}
<input type="text" name="name" />
<button type="submit">Send</button>
</form>
The Http() helper in public/js/utils.js automatically reads document.getElementById('csrf') and sends the value as the X-CSRF-Token header on every fetch. No additional client-side code is needed.
Lila Premium CSS Utility Components
To accelerate your UI development and enable rapid, professional prototyping, Lila packages a set of pre-configured, high-performance styling utility classes loaded automatically by the asset('css/tailwind.css') CDN helper. 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.