Skip to content

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.

Every page template is a two-file pair:

FileRole
templates/my-page.phpWordPress template — fetches data, builds context, calls Timber::render()
views/templates/my-page.twigTwig 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.


Run the generator to scaffold both files at once:

Terminal window
wp instance make template services
# → templates/services.php
# → views/templates/services.twig

Then skip to step 3 below to assign the template in the admin.


Or create the files manually:

  1. Create the PHP template

    Add a new file in templates/. The Template name: comment is what WordPress shows in the admin dropdown.

    templates/services.php
    <?php
    use Timber\Timber;
    /** Template name: Services */
    $context = Timber::context();
    $context['post'] = Timber::get_post();
    Timber::render('templates/services.twig', $context);
  2. Create the Twig template

    Add the matching Twig file in views/templates/. Always extend layouts/base.twig and fill in the content block.

    {# 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 %}
  3. 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.


Add any data you need to $context before calling Timber::render():

templates/services.php
$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 %}

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:

templates/services.php
$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.


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