Template Controllers
In the files that WordPress uses when it matches a route (e.g. page.php
, single.php
), or within custom theme templates, you can use a controller class rather than writing procedural code.
We call these Template Controllers to distinguish them from ones that haven't been hoisted from WordPress templates. In most respects, they follow the same pattern as standard controllers
// single.php
declare(strict_types=1);
namespace NameSpace\AppName;
use YourNameSpace\AppName\Core\View;
use Forme\Framework\Controllers\AbstractController;
use Psr\Http\Message\ServerRequestInterface;
final class SingleController extends AbstractController
{
public function __construct(private View $view)
{
}
public function __invoke($request)
{
$context = $request->input('fields');
return $this->view->render('single', $context);
}
}
The name of the controller is important
- It should be under your app namespace (even though this doesn't follow PSR-4)
- The class name must be a PascalCase version of the filename with the word Controller on the end (without spaces, dashes and underscores). If the controller name is not correct Forme will not throw any errors - instead you will just get a blank page.
Exceptions
In WordPress, you have a 404.php
file. PHP Classes cannot start with a number so following the usual naming convention will not work here. Instead Forme will look for a controller called Error404Controller
.
Template controller classes won't work for the WordPress header.php
and footer.php
files. In the Forme theme boilerplate these have been done away with entirely in any case, and reimplemented as view partials, so you shouldn't need to use them.
Magic to be aware of
When someone views a page that has a corresponding template controller, the __invoke
method will automatically be called on that controller, and will have $request
passed into it with postId
, fields
and options
pre-filled as part of its body parameters. That fields
value helpfully contains an array with all the ACF fields for the postId
, the options
value contains an array with all the global options page values.
WARNING
The fields and options keys will all be converted to camelCase from the ACF default of snake_case. This is mainly so you can access my_awesome_field
as $myAwesomeField
in the view.
Custom Template Controllers
As a convention, we put custom template controllers in the /template-controllers
directory.
You can add template names to template controllers and they will be picked up for selection in the WordPress admin:
// template-controllers/FooBarController.php;
<?php
declare(strict_types=1);
namespace NameSpace\AppName\Controllers;
use YourNameSpace\AppName\Core\View;
use Forme\Framework\Controllers\AbstractController;
/*
* Template Name: Foo Bar
*/
final class FooBarController extends AbstractController
Middleware
Check out this section to find out how to add PSR 15 middleware to Template Controllers.
Code Generation
You can use the code generator.
forme make template-controller FooBar
This will create a new custom template controller called FooBarController
in the template-controllers
folder.