Skip to content

Development

Most features follow the same three-step cycle:

  1. PHP — fetch data from WordPress, build a context array
  2. Twig — render the context as HTML
  3. SCSS/JS — style and add interactivity

Run this from the theme root to start Vite with hot-module replacement:

Terminal window
ddev npm run dev

Open your site in the browser. SCSS changes hot-reload without a page refresh; PHP/Twig changes trigger a full reload.


WordPress routes a request to a PHP template (e.g. single.php). That file builds a context array and passes it to Twig:

single.php
use Timber\Timber;
$context = Timber::context(); // global data (site, theme, user)
$context['post'] = Timber::get_post(); // the current post
Timber::render('templates/single.twig', $context);

Every key you add to $context becomes a variable in the Twig template:

{# views/templates/single.twig #}
{% extends 'layouts/base.twig' %}
{% block content %}
<h1>{{ post.title }}</h1>
{{ post.content }}
{% endblock %}

All templates extend layouts/base.twig, which provides the full HTML document with header, footer, and a {% block content %} for the page body.

A handful of variables are available in every Twig template without you adding them:

VariableTypeDescription
siteTimber\SiteSite name, URL, etc.
themeTimber\ThemeTheme directory, URI
userTimber\User | nullLogged-in user or null

To add your own global data (available on every page), use app/Hook/TimberHook.php. See the Context guide for details.


What you’re buildingLocation
WordPress hook / filterapp/Hook/
Extending a Timber post/termapp/Classmap/
A reusable PHP helperapp/Util/
A post type or taxonomy slug constantapp/Constant/
A page templatetemplates/ + views/templates/
Custom Twig function or filterapp/Hook/TimberHook.php
An AJAX endpointapp/Ajax/Action/ (see Ajax)
A REST endpointapp/RestAPI/ (see REST API)
JS featureassets/src/js/modules/
SCSS componentassets/src/scss/partials/

Here is the typical flow for adding a team members section to a page:

  1. Define ACF fields in acf-php/templates/team.php
  2. Create the PHP template in templates/team.php — fetch posts, build context
  3. Create the Twig template in views/templates/team.twig — render HTML
  4. Add SCSS in assets/src/scss/partials/_team.scss, import it in scss/site.scss
  5. Assign the template in WordPress admin → Page Attributes → Template

See Page Templates for the step-by-step walkthrough of this pattern.


Scans the PHP codebase for type errors and bugs:

Terminal window
ddev composer run-script phpstan

Formats all Twig templates:

Terminal window
ddev npm run prettier

Checks JS and SCSS against the project’s coding standards:

Terminal window
ddev npm run lint

Fix all errors and warnings before pushing to production. If a rule genuinely cannot be satisfied, ask a fellow developer before disabling it.

Creates optimised, minified assets:

Terminal window
ddev npm run build

Always verify the build succeeds before deploying.