Nova
WordPress Integration
Overview

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:

  1. Nova configurations, in JSON format.
  2. 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.phpRenderer 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.