Bengal's template system uses Kida as the default engine, with support for Jinja2 and custom engines.
Template Engines
- Kida (local reference) — Bengal's native template engine (default). Unified
{% end %}blocks, pattern matching, pipeline operators - Jinja2 — Industry-standard engine with excellent documentation and tooling
- Custom engines — Bring your own via the plugin API
Tip
Kida is Jinja2-compatible: Your existing Jinja2 templates work without changes. Use Kida-specific features incrementally.
Template Lookup Order
Bengal searches: Your project → Theme → Bengal defaults
Quick Start
{# templates/layouts/single.html #}
{% extends "baseof.html" %}
{% block content %}
<article>
<h1>{{ page.title }}</h1>
{{ page.content | safe }}
</article>
{% end %}
{# templates/baseof.html #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{{ page.title }}{% end %}</title>
</head>
<body>
{% block header %}{% include "partials/header.html" %}{% end %}
{% block content %}{% end %}
{% block footer %}{% include "partials/footer.html" %}{% end %}
</body>
</html>
{# templates/partials/header.html #}
<header>
<nav>
{% for item in site.menus.main %}
<a href="{{ item.href }}">{{ item.title }}</a>
{% end %}
</nav>
</header>
Key Concepts
| Concept | Syntax | Purpose |
|---|---|---|
| Extends | {% extends "base.html" %} |
Inherit from parent template |
| Block | {% block name %}...{% end %} |
Replaceable section |
| Include | {% include "partial.html" %} |
Insert another template |
| Variable | Templating |
Output a value |
| Filter | {{ text \| truncate(100) }} |
Transform a value |
Template Inheritance
Kida Features
Kida is Bengal's default template engine:
- Unified syntax:
{% end %}closes all blocks (no more{% end %},{% end %}) - Pattern matching:
{% match %}...{% case %}for cleaner conditionals - Pipeline operator:
|>for readable filter chains - Fragment caching: Built-in
{% cache %}directive - Jinja2 compatible: Existing Jinja2 templates work without changes
Choose Your Engine
Kida is the default. To use a different engine, configurebengal.toml (or config/_default/site.yaml):
site:
template_engine: jinja2 # Options: kida (default), jinja2, mako
Custom Engines (BYOR)
Bring your own template engine via the protocol API. Your engine automatically gets all 80+ template functions if it satisfies theTemplateEnvironmentprotocol:
from bengal.rendering.engines import register_engine
from bengal.rendering.template_functions import register_all
class MyEngine:
def __init__(self, site):
self.site = site
self.template_dirs = [site.root_path / "templates"]
# Environment must have globals, filters, tests dicts
self._env = MyEnvironment()
# Automatically get all 80+ template functions!
register_all(self._env, site)
def render_template(self, name: str, context: dict) -> str:
# Your implementation
...
register_engine("myengine", MyEngine)
Then configure:
site:
template_engine: myengine
See Bring Your Own Template Engine for the complete guide.
Tip
Override sparingly: You only need to create templates you want to customize. Usebengal utils theme swizzle <template>to copy a template for customization. Let the rest fall through to theme defaults.