Overview
In this section, we'll explain how the Style Guide integrates with WordPress.
This page is a work in progress.
Introduction
Unlike traditional WordPress sites, Nova themes contain no templates; instead, they hold configuration files in two forms:
- Nova configurations, in JSON format.
- Plugin configurations, in PHP (as we do for PMC's non-Nova themes).
Following this design, template files cannot be added to Nova themes; they are
intentionally disregarded by the pmc-nova plugin. In their place, Nova themes
use a configuration file that defines which Nova component is used to render a
given WordPress request.
Request Flow
Needs a flowchart.
Request → WP loads default.php → Renderer invoked → Component_Loader
invoked → Template_Interceptor invoked → Config invoked → Component's
Model invoked → Component's Controller invoked → Renderer captures
output → default.php outputs shell around output captured by Renderer.
Nova's common template
For every supported request (more on that in the Template Configuration
section), the pmc-nova plugin uses a single template file and directs
WordPress to load that file in place of the file its template hierarchy
specifies; it is found in pmc-nova/templates/default.php. It encompasses
what would be found in header.php and footer.php, along with the Nova
integration.
Template Configuration
While Nova themes do no support templates, this does not mean that we've abandoned the long-established template hierarchy (opens in a new tab) that WordPress provides. In its place, we've created a JSON configuration that provides the same flexibility without requiring individual PHP templates. Each top-level key in the configuration maps to a query type supported by the WordPress template loader; within each key is an object that maps specific query results to Nova components, along with a wildcard that's used for any context not otherwise provided for.
The following is a simplified example. It shows how the homepage is mapped to
the <TemplateHomepage /> component, while archive pages are routed to the
<TemplateArchive /> component. In this configuration, all single posts,
regardless of post type, are routed to the <TemplateArticle /> component.
{
"home": {
"*": {
"*": "template-archive",
"1": "template-homepage"
}
},
"single": {
"*": "template-article"
}
}See the Template Configuration page for more detail.
Template Interceptor
The Template Interceptor, found in the
\PMC\Nova\Templating\Template_Interceptor class, is a re-implementation of the
logic WordPress uses to determine which template to load for a given request.
While not ideal, it is necessary to re-implement this feature because WordPress
defines it in a way that cannot be reused. Specifically, the list of query
conditionals, and the order in which they're evaluated, is hardcoded in
wp-includes/template-loader.php. The Template Interceptor respects Core's
order and combines that logic with the template configuration discussed in the
preceding section.
See the Template Interceptor page for more detail.
Component Loader
The Component Loader, found in the \PMC\Nova\Templating\Component_Loader
class, is responsible for:
- Loading the component configured for a particular query;
- Using the component's model to building the data object required to render the component; and
- Rendering the component's template by way of its controller.
The Component Loader can only be used in the common template discussed earlier
in this section. When rendering components for other situations, such as
widgets and Gutenberg blocks, Nova provides the \PMC\Nova\render_component()
utility function.
Component Models
Models are the cliché "glue" that binds Nova's components to the data their templates require. Depending on where a component is found in the tree, it may accept:
- a post or term ID,
- a post-type slug,
- text retrieved from a WordPress data object,
- data from another PMC Plugin,
- data set via a WordPress settings screen, or
- myriad other inputs.
See the Component Models page for more detail.
Component Controllers
Controllers are responsible for rendering components' templates. They receive from the corresponding models the data required by the templates.
In most cases, a component's controller simply extends the base class and includes no additional methods. In some cases, such as when a component depends on another PMC Plugin or a component's template includes a WordPress hook, the controller will include a callback for the hook and the related hook addition.
See the Component Controllers page for more detail.