Customize Bengal themes and create your own designs in 30 minutes.
Note
Do I need this? Yes if you want to change layouts, CSS, or template structure. Skip if you only write Markdown — the default theme works without theming.
Prerequisites
- Bengal installed
- Basic knowledge of HTML
- Familiarity with CSS
- Basic template syntax (Bengal uses Kida, similar to Jinja2 but with
{% end %}closers)
Understand Theme Resolution
Bengal looks for templates in this order:
- Your project —
templates/(overrides everything) - Your theme —
themes/your-theme/templates/ - Installed themes — Via pip or uv
- Default theme — Built into Bengal
You only need to override what you want to change.
- 1
Create a custom theme
bengal theme new --slug my-themeThis creates:
tree-sitter-querythemes/my-theme/ ├── theme.toml ├── README.md ├── templates/ │ ├── base.html │ ├── home.html │ ├── page.html │ └── partials/ └── assets/ └── css/ └── style.css - 2
Configure your theme
Update
bengal.toml:toml[build] theme = "my-theme"Or use
config/_default/build.yamlfor split configuration:yamlbuild: theme: "my-theme" - 3
Override templates selectively
You do not need to copy all templates. Extend the default:
html{# themes/my-theme/templates/base.html #} {% extends "base.html" %} {% block header %} <header class="custom-header"> <h1>{{ site.title }}</h1> {% for item in menus.main %} <a href="{{ item.href }}">{{ item.name }}</a> {% end %} </header> {% end %}Everything not overridden inherits from the default theme or parent theme.
- 4
Add custom CSS
Create
themes/my-theme/assets/css/custom.css:css:root { --color-primary: #3498db; --color-text: #2c3e50; } .custom-header { background: var(--color-primary); padding: 2rem; }Include in your template:
html{% block extra_head %} <link rel="stylesheet" href="{{ asset_url('css/custom.css') }}"> {% end %}
Template Variables
Key variables available in templates (all support safe dot-notation access):
| Variable | Description |
|---|---|
site.title |
Site title from configuration |
site.description |
Site description |
site.baseurl |
Site base URL |
site.pages |
All pages in the site |
menus.main |
Main navigation menu (safe access) |
page.title |
Current page title |
page.content |
Rendered HTML content (use with| safe) |
page.href |
Page URL with baseurl applied |
page.date |
Publication date |
page.tags |
List of tags |
page.description |
Page description |
params |
Page frontmatter (cascades page → section → site) |
theme |
Theme configuration (safe dot-notation access) |
bengal |
Engine metadata |
Bengal provides 80+ template functions. Common ones:
asset_url('path')— Generate asset URLsurl_for('path')— Generate page URLsget_menu('name')— Get a navigation menutime_ago/date_iso— Format dates ({{ page.date | time_ago }})truncate_chars(text, length)— Truncate text
Debug Theme Issues
# List available themes
bengal theme list
# Get theme info
bengal theme info --slug default
# Debug theme resolution
bengal theme debug
# Discover installed themes
bengal theme discover
# Swizzle a template for customization
bengal theme swizzle --template-path partials/header.html
Next Steps
- Theme Customization — Deep dive into overrides
- Template Functions — All available filters and functions
- Variables Reference — Complete template variables
- Assets — CSS, JS, and image handling