Page Templates
Page templates let editors assign a specific layout to a WordPress page from the admin. This is the most common way to build unique page designs in Lumbermill.
How It Works
Section titled “How It Works”Every page template is a two-file pair:
| File | Role |
|---|---|
templates/my-page.php | WordPress template — fetches data, builds context, calls Timber::render() |
views/templates/my-page.twig | Twig template — receives the context and renders HTML |
WordPress discovers the PHP file and shows it as an option in the page editor. When the page loads, that PHP file runs, builds a context array, and hands it off to the Twig template for rendering.
Creating a Page Template
Section titled “Creating a Page Template”Run the generator to scaffold both files at once:
wp instance make template services# → templates/services.php# → views/templates/services.twigThen skip to step 3 below to assign the template in the admin.
Or create the files manually:
-
Create the PHP template
Add a new file in
templates/. TheTemplate name:comment is what WordPress shows in the admin dropdown.templates/services.php <?phpuse Timber\Timber;/** Template name: Services */$context = Timber::context();$context['post'] = Timber::get_post();Timber::render('templates/services.twig', $context); -
Create the Twig template
Add the matching Twig file in
views/templates/. Always extendlayouts/base.twigand fill in thecontentblock.{# views/templates/services.twig #}{% extends 'layouts/base.twig' %}{% block content %}<main class="services-page"><div class="container"><h1>{{ post.title }}</h1>{{ post.content }}</div></main>{% endblock %} -
Assign the template in WordPress
Open the page in the WordPress admin, find the Template dropdown in the right sidebar under Page Attributes, and select Services.
Save the page and visit it — your template renders.
Passing Data to the Template
Section titled “Passing Data to the Template”Add any data you need to $context before calling Timber::render():
$context = Timber::context();$context['post'] = Timber::get_post();$context['services'] = Timber::get_posts([ 'post_type' => 'service', 'posts_per_page' => -1,]);
Timber::render('templates/services.twig', $context);{# views/templates/services.twig #}
{% extends 'layouts/base.twig' %}
{% block content %} <main class="services-page"> <div class="container"> <h1>{{ post.title }}</h1>
{% for service in services %} <article> <h2>{{ service.title }}</h2> {{ service.content }} </article> {% endfor %} </div> </main>{% endblock %}Adding ACF Fields
Section titled “Adding ACF Fields”To add custom fields to a page template, create a folder in acf-php/templates/ with two files — one that defines the fields and one that registers the group with a location.
acf-php/templates/services/header.php — define the field group:
<?php
use JorenRothman\ACFBuilder\Fields\Basic\Text;
return createFieldGroup('Services - Header', function ($fieldGroup) { $introText = Text::make('Intro Text'); $fieldGroup->addField($introText);});acf-php/templates/services/index.php — register it for the template:
<?php
use JorenRothman\ACFBuilder\FieldGroupLocations;
$header = loadFieldGroup(__DIR__ . '/header.php');
$location = new FieldGroupLocations;$location->and('page_template', '==', 'templates/services.php');
$header->register($location, 10);The folder is loaded automatically — acf-php/index.php autoloads every nested index.php, so there’s no wiring step.
Fetch the field in the PHP template and add it to the context. The meta key is the field group title and field name joined with underscores and lowercased:
$context = Timber::context();$post = Timber::get_post();$context['post'] = $post;$context['intro_text'] = $post->meta('services_header_intro_text');
Timber::render('templates/services.twig', $context);Then use it in Twig as a plain variable:
<p>{{ intro_text }}</p>See the ACF guide for the full field builder API and all available field types.
File Overview
Section titled “File Overview”After following the steps above your new template consists of two files:
Directorylumbermill/
Directorytemplates/
- services.php
Directoryviews/
Directorytemplates/
- services.twig
With ACF fields, add a folder in acf-php/templates/:
Directorylumbermill/
Directoryacf-php/
Directorytemplates/
Directoryservices/
- header.php
- index.php

