Templates¶
Templates are arvel's server-side templating layer. Where Views cover returning a
template and passing it data, this page covers the template language itself — displaying data,
control structures, inheritance, and the form helpers. Templates are Jinja
files under resources/views/, rendered asynchronously, with autoescaping on by default.
Displaying data¶
Pass data to a view and echo it with {{ }}:
Output is HTML-escaped automatically, so {{ name }} is safe against XSS. To render trusted HTML
verbatim, mark it | safe — only ever on values you control.
Control structures¶
{% if user.is_admin %}
<a href="/admin">Dashboard</a>
{% elif user.is_member %}
<span>Welcome back</span>
{% else %}
<a href="/login">Sign in</a>
{% endif %}
<ul>
{% for post in posts %}
<li>{{ loop.index }}. {{ post.title }}</li>
{% else %}
<li>No posts yet.</li>
{% endfor %}
</ul>
Template inheritance¶
Define a layout with named blocks, then extend it — the arvel equivalent of a master layout:
{# resources/views/layouts/app.html #}
<!doctype html>
<html>
<head><title>{% block title %}arvel{% endblock %}</title></head>
<body>{% block content %}{% endblock %}</body>
</html>
{# resources/views/posts/index.html #}
{% extends "layouts/app.html" %}
{% block title %}Posts{% endblock %}
{% block content %}
{% for post in posts %}<article>{{ post.title }}</article>{% endfor %}
{% endblock %}
Including subviews¶
Components (macros)¶
Reusable, parameterized fragments are expressed as macros:
{% macro alert(message, kind="info") %}
<div class="alert alert-{{ kind }}">{{ message }}</div>
{% endmacro %}
{{ alert("Saved!", kind="success") }}
Forms & CSRF¶
State-changing forms must carry the CSRF token; csrf_field() emits the hidden input, and
method_field() spoofs PUT/PATCH/DELETE for HTML forms that only support GET/POST:
<form method="POST" action="/posts/{{ post.id }}">
{{ csrf_field() }}
{{ method_field("PUT") }}
<input name="title" value="{{ old('title', post.title) }}">
{% if errors.title %}<span class="error">{{ errors.title[0] }}</span>{% endif %}
<button>Save</button>
</form>
See CSRF Protection and Validation for the mechanisms behind these helpers.
Available global functions¶
These functions are registered on every template — no need to pass them from the controller:
| Function | Returns |
|---|---|
route(name, **params) / url(path) |
a URL to a named route / path |
asset(path) |
a URL to a bundled asset (see Asset Bundling) |
vite(*entries) |
the hashed <script>/<link> tags for one or more Vite entries, as trusted Markup |
csrf_token() / csrf_field() |
the raw CSRF token / a hidden _token input |
method_field(method) |
a hidden _method input for verb spoofing |
trans(key, **repl) / trans_choice(key, n) |
a translated / pluralized string |
can(ability, *args) / cannot(...) |
authorization checks (see Authorization) |
auth() / guest() |
the current user / whether the visitor is a guest |
config(key, default) |
a configuration value |
old(key, default) / errors |
repopulated input / the validation error map |
See also¶
- Views — returning templates and passing them data.
- Asset Bundling — the
asset()helper and Vite integration. - Localization —
trans()/trans_choice().