Skip to content

Building a theme

Building a theme

How a site gets its shape and its appearance, and where to start.

A theme is a directory under themes/. It holds three things:

  • The schema — what content exists and what it is made of.
  • The views — the Vue components that turn that content into pages.
  • The styles — how they look.

That is the whole of a site’s appearance and structure. Nibble supplies the machinery around it: routing, caching, the control panel, search, images.

Start with a theme of your own

bin/rails nibble:generate:theme almanac

This copies the starter into themes/almanac and makes it the site’s active theme. Do not edit themes/crumbs — it is Nibble’s, and an upgrade replaces it. Yours is yours forever.

Then start the site and edit away; changes appear as you save.

bin/dev

The pages

Page What it covers
Schema collections, taxonomies, globals, navigation and forms, as YAML
Blueprints and fields what an editor sees on the form, and every fieldtype
Views which view renders what, layouts, and blocks
Queries asking for the content a page needs, beside the view
Theme helpers ready-made components for rich text, images and pagination
Content written as files a collection whose pages are Markdown in your repository
The Content API reading the same content from somewhere else

How a page is rendered

Worth reading once, because it explains where to put things:

  1. A request arrives. Nibble checks its redirects first.
  2. It works out what the URL points at — an entry, a taxonomy term, or nothing.
  3. It reads the query sidecar next to the view: a small YAML file saying what else the page needs, like the latest posts or the site’s globals.
  4. It renders your Vue view, on the server, with that content as props.
  5. It caches the result against everything the page used, so publishing any of those clears exactly the right pages.

Steps 3 and 4 are yours. The rest is Nibble’s and does not need your attention.

What a theme directory holds

themes/almanac/
├── layouts/          the frame around a page
├── views/            one view per kind of page, each with an optional .yml beside it
│   └── sets/         blocks an editor can add to a page
├── components/       your own components
├── styles/           CSS
├── schema/           the collections, blueprints and so on this theme needs
├── content/          example content, imported at install if the site wants it
└── theme.yml         the theme's name, and which Nibble it expects

A site can add or override any of the schema in its own schema/ directory, which is how one theme serves several sites without forking.