Creating a theme

Creating a theme

A theme is responsible for the front-end's appearance. It's a templates/<slug>/ folder with a theme.json manifest and a set of .tpl files. PHP in templates is forbidden — only template-engine tags.

Quick start: a blank theme

Don't write from scratch — download a ready-made skeleton:

Download the blank theme (zip)

Inside: theme.json, _partials/head.tpl and foot.tpl, the base home.tpl, page.tpl, news_list.tpl, news_full.tpl, search.tpl, 404.tpl and assets/theme.css. Unzip so the starter-theme/ folder lands in templates/, activate the theme in Settings → Templates, and rename it to your own (the folder and the slug in theme.json).

theme.json

{
  "name": "My Theme",
  "slug": "mytheme",
  "version": "1.0.0",
  "author": "Author name",
  "description": "Short description",
  "regions": ["header", "main", "footer"]
}

slug matches the folder name and is used in the theme option.

Minimal set of templates

FileWhen it's called
home.tplhome page
page.tplstatic page /p/{slug}
news_list.tplnews list / category / search
news_full.tplsingle article page
search.tplsearch results
404.tpl"not found" page

Plus reusable pieces in _partials/ (e.g. head.tpl, header.tpl, footer.tpl) and assets in assets/.

Quick start: "your own theme in an hour"

  1. Copy templates/default/templates/mytheme/.
  2. Edit theme.json.
  3. Replace the styles in assets/theme.css.
  4. Rewrite _partials/head.tpl and the footer to fit your markup.
  5. If needed, override home.tpl, news_list.tpl, news_full.tpl, page.tpl.
  6. Activate the theme in Settings → Templates.
  7. Check responsiveness and dark mode.

Assets and versioning

Put all css/js in templates/<slug>/assets/ (external CDNs are forbidden by the CSP policy). Include them in _partials/head.tpl:

<link rel="stylesheet" href="/templates/mytheme/assets/theme.css?v=1">
<script src="/templates/mytheme/assets/theme.js?v=1" defer></script>
In production nginx caches static files for a long time. After editing .css/.js, bump the version (?v=1?v=2), otherwise returning visitors get the old file from cache.

Dark mode

Themes inherit the core's CSS variables (--bg, --surface, --text, --accent, etc.). Dark mode is toggled with the data-theme="dark" attribute on <html>. Toggle buttons:

<button data-celena-theme="light">☀</button>
<button data-celena-theme="dark">☾</button>
<button data-celena-theme="auto">A</button>

Overriding plugin templates

A theme can override any plugin template without touching the plugin itself. Just create a file at:

templates/<mytheme>/plugins/<slug>/<path>.tpl

The engine looks for a plugin template in this order: active-theme override → default-theme override → plugin original. Delete the theme file and the original returns. More — Building a plugin.

Template cache

After editing a .tpl in production, clear the compiled-template cache (storage/cache/tpl/*) — otherwise the old version is served. Locally the cache invalidates itself by mtime; the admin has Settings → Performance → Clear cache.