Docs: Themes

Themes

How a tilspire theme is structured, what it owes the modules it displays, and how to fork the starter theme safely.

A tilspire theme is a plain folder of templates, components and assets — nothing compiled, nothing built.

Anatomy of a theme #

  • theme.json — the manifest: name, version, author, description, license and tags, plus an optional options list whose entries (key, label, type, default and a few more) become settings you can change in the admin panel.
  • components/ — shared partials, such as the header and footer.
  • views/ — the templates for each kind of page tilspire renders.
  • assets/ — the theme's own CSS, JavaScript, fonts and images.

A theme that draws its own sign-up form (views/auth-register.php) calls <?php $this->signupChecks(); ?> inside the form, before the submit button, since 1.17.3. It adds the checks that keep bots out. Without it, sign-ups are held to the per-address limit alone, and Health says so.

What a theme provides, and what tilspire fills in #

Since 1.4.0, what a theme owes the modules it displays is written down. A theme claims each job it wants to do itself; for every job it doesn't claim, tilspire fills in a working default, so a module always renders properly on any theme.

The jobIf the theme doesn't claim it
A content container: the width and padding around page contenttilspire adds a small stylesheet that constrains it
The icon set modules usetilspire loads the icons when a page needs them
The stylesheets and scripts a module or page asks fortilspire adds them to the page itself
The SEO head block: title, description, canonical link, robots, Open Graph, Twitter and JSON-LDtilspire writes the parts the theme left out, and leaves the ones it wrote alone
A way in: a link to /account for membersNothing can be filled in here — put the link in your navigation
The --cms-* colours, radii and fonts modules style themselves withModules fall back to neutral values of their own

A theme that claims a job gets its page back untouched, and keeps control over where things go.

Content fields in your templates #

Pages built on a content-model template carry typed fields. Themes read them through the Template API — field(), rows() and related() — which escapes each value according to its declared type. The starter theme shows how, and the Template API lists every call: pages by Layout or parent, dates, pictures, links, the logo and more.

Design #

Since 1.15.0, Site ▸ Design changes the active theme's colours, fonts, sizes and layouts without editing a file. A theme declares what may change in its theme.json options: a colour, number or font option can name the CSS custom property it sets, and a layout option offers the layouts the theme itself provides. tilspire writes only those values, from allowlists, and fonts come from a set it hosts itself, so nothing is fetched from elsewhere.

A change is proposed, never applied at once: it waits in the Review queue, where you can preview it on your site as it looks now and after. A colour pair that fails the WCAG contrast check is refused, with its ratio. The Assistant and the Operator API can propose designs the same way.

Languages and menus #

On a site with more than one language, the Template API returns the visitor's language, and menus reach a theme through menu() already translated. A theme that shows no language switcher gets a plain one from tilspire.

Choosing the active theme #

Set the active theme under Site ▸ Themes. It applies across the whole site.

Start from the starter theme #

tilspire ships with a starter theme at site/themes/default/. It's built to the theme contract and written to be read end to end and forked, not treated as a finished showcase. Copy it into a new folder under site/themes/, rename it in its theme.json, and activate your copy.

A theme forked before 1.14.0 #

If your theme asks can('access_admin') to decide who is staff — to let staff past the maintenance page, or to show them a link — change it to isStaff(). Since 1.14.0 staff can sign in on the site, and access_admin is only true while they are signed in to the admin panel, so a staff member browsing the site would otherwise be treated as a visitor. The starter theme made the same change. Asking for a specific permission is unaffected.

Never edit the starter theme in place #

site/themes/default/ is one of the paths tilspire's updater manages. Every update overwrites it completely, so any change you make there directly is lost the next time you update. Always work in a copy.