Advanced JavaScript loading

The module based approach you’ve seen in CSS and PHP extends to JavaScript as well. There is no central location where all JavaScript files are enqueued conditionally. Instead, they are enqueued by the PHP components using those scripts. That way, each component is compartmentalized and self-sustaining.

A good example of this is the accessibility component, which uses a JavaScript file to ensure the main menu is accessible for all input devices, including keyboard, touch, and mouse.

The file in question is navigation.js, which sits under ‘assets’ and ‘js’. The reason it sits there is because the build process needs to be able to get its hands on the JavaScript files and compile them out. And that all happens inside the assets folder.

The component that enqueues this file is found under the “inc” folder and “Accessibility”.

The component first calls the initialize function and triggers add_action(), wp_enqueue_scripts(), and points to a custom function. Apart from the initialize function, this is the standard way of calling wp_enqueue_scripts() and calling in custom scripts and invocations. The only difference is that in WP Rig, this is placed inside the component. In other themes, it’s usually placed inside the functions.php file in a long list.

The action_enqueue_navigation_script() function that was just called with the add action() call contains the standard wp_enqueue_scripts() invocation. Here we used wp_enqueue_scripts() exactly how you would always use it.

But this is the old way of loading script. The web has moved past this best practice, and WP Rig now allows you to load scripts in the modern way. Traditionally, JavaScript was loaded at the bottom of a document to avoid rendering conflicts. Modern JavaScript has done away with this practice, thanks to the “async” and “defer” attributes, and the ability to precache script files.

“Async” and “defer” allow us to load script files in the <head> section of the document, and then either tell the browser to run the script asynchronously (when the file is fully loaded), or defer running the script until everything else is in place.

WP Rig has custom functionality allowing you to declare either “async” or “defer” for each individual script you enqueue. So you can choose exactly what you want to happen to each individual script.

This is cutting edge and not yet supported in WordPress, but this code will be supported at some point in the future, and you will not run into any conflicts.

JavaScript in WP Rig

JavaScript plays an ever more important role in web development, and we’re seeing more and more JavaScript in WordPress core and WordPress themes and plugins.

WP Rig itself doesn’t have much JavaScript included. There are three files: customizer.js, which relates to the customizer, lazyload.js, which helps put lazy loading of images, and navigation.js, which helps with accessibility for the main menu.

That said, WP Rig is ready for any JavaScript you want to create. The build process is configured for ES2015, aka ES6, aka ES.Next, with full ESLint support compiling via Babel and code minification, all out of the box, without any configuration on your part.

Like CSS, you build JavaScript in the assets.js source folder. The build process Lint compiles, optimizes, and minifies the code before placing it in the root js folder, ready for use by modern and older browsers.

In short, you write modern JavaScript. WP Rig makes sure it works everywhere.

Functions in WP Rig

All WordPress themes must have a file called functions.php. Traditionally, this is the file that contained all the set up of the theme and all the customizations. However, as WordPress has evolved, more and more of that functionality has moved out of functions.php and into other files.

In WP Rig, we’ve taken that to the extreme by removing all functionality from functions.php, and just letting this file control the function of WP Rig itself, so that all the modularity works.

That means, as you create new functions for your own custom themes with WP Rig, you never touch functions.php itself. This file is no longer where you place any functionality. All custom functionality lives inside the “/inc” folder under different php modules.

This also introduces a new way of doing things where custom functions are concerned, and here is an example showing how.

If we go to sidebar.php, the template file that generates the sidebar, you’ll see a conditional statement that says, “if not WP Rig is primary sidebar active.” The operative function here is this one, is is_primary_sidebar_active().

But then. it’s prefixed by the wp_rig() function, and if you hover over it, it says, “provides access to all available template tags of the theme.” This function was introduced in WP Rig to ensure that you stay within the namespace of the theme. In very simple terms, it just means you can’t call this function from outside the theme, and this function will never collide with anything that happens in WordPress itself.

This setup looks different from how a traditional theme would do it. You’ll notice there is no theme name prefix in front of this custom function but it works much the same way. So instead of the theme prefix, you have this custom wp_rig() function, which handles that functionality for you.

We see this again and again here. We have wp_rig()-> is_primary_sidebar_active(). Then, we have wp_rig() -> print_styles(), which adds the style sheets, and further down you see wp_rig() -> display_primary_sidebar().

So what are these functions: is_primary_sidebar_active() and display_primary_sidebar()?

Well, if we go to the sidebar component, we can find these functions declared. So let’s start from the top and see how all this is strung together. First, we declare a new constant called PRIMARY_SIDEBAR_SLUG, and this will be the slug that’s used for the sidebar:

This is what we target anytime we are working with the sidebar.

Scrolling further down, we set up the template tags that will be available to the theme. And those template tags are: is primary sidebar active and display primary sidebar

They point at functions that sit inside this particular file, is primary sidebar active and display primary sidebar. So this is how the new object orientation takes an existing function inside a component and lifts it up so it becomes available to the rest of the theme. Then we register a sidebar just like we normally would in a WordPress theme only we use the ID static:: PRIMARY_SIDEBAR_SLUG. (It’s the slug that was defined up at line 30.)

Then when we scroll to the bottom, we find these two custom functions that were used in sidebar.php: is_primary_sidebar_active() and display_primary_sidebar(). And as you can see, these functions wrap standard WordPress functions, so we have is_active_sidebar() inside is_primary_sidebar_active(). Likewise, you can see dynamic_sidebar() inside display_primary_sidebar().

What’s happening here is that WP Rig is wrapping WordPress functionality in new custom functionality to provide tighter control over exactly what happens. Instead of calling dynamic_sidebar() directly from sidebar.php, we call this custom functionality in the component. That means we can filter the output and change the output into whatever we want before it gets passed on to WordPress.

Like we mentioned earlier, this is different from how WordPress themes have operated until this point. But, this is how PHP is written as of right now. It’s a different way of approaching things, and it gives you far more control once you see what’s going on.

Theme features and customization

4.4 Theme features and customization

WordPress provides a long list of optional features the themes can choose to hook into.

WP Rig hooks into almost all of these features to give you a boilerplate starting point, where you can either customize the features to fit with your particular theme design or disable them if you don’t want them.

These features also serve as a good introduction to how the object orientation and modularity of PHP and WP Rig work. So let’s take a closer look both at the frontend, the backend, and how the code works. 


We’ll start in the Customizer. Themes can choose to add support for a custom logo and a header image. The custom logo is found under “Site Identity.” At the top, you can select a logo, select an image, and crop the image to fit the specification of the theme. Then, it appears somewhere within the theme layout. 

This functionality, along with all the other PHP modules, are found under the “inc” folder. Here, you have specific modules for each individual function of the themes. You can see below, we’re looking at the custom logo, which is found under “Custom_Logo” and “Component.php”: 

Toward the bottom of this file, you’ll find the actual setup with the add_theme_support() function. This is the standard PHP code. Here, we then define the height, width, flex-width, and flex-height settings for that particular feature. You can change this to anything you need. There are also some additional parameters you can add in if you want.

This is how the PHP modules in WP Rig work. We used to place this kind of functionality either in “functions.php,” or maybe in something like “template-tags.php.” In WP Rig, we’ve broken them out into their own modules and they are completely standalone. This way, they are easy to find, and you contain functionality within their own files. 

The same thing goes for other functions.

Here, we can add a header image to the sites:

That functionality sits under another component called Custom_Header (inc/Custom_Header/Component.php). Inside that Component.php file, we first add theme support for a custom header, and then we have all the different settings available to us.

So this is where you would make changes to that custom header if you wanted it to display differently or behave in a different way: 

Editing the Block Editor (Gutenberg) settings

The block editor, AKA Gutenberg, has also introduced new features themes can hook into. They include things like font sizes and custom colors for a specific element. 

Below, we have a paragraph. We can set a custom font size, and we can also set both a background color and a foreground color for the contents within any one of these. All of this can be defined by the theme itself. 

This is all found in the “Editor” component. Here off the top, we find theme support for editor styles. That means the theme ships with its own style sheet for the editor to customize the editor experience. That’s what you find under the editor folder (/inc/Editor/Component.php) under style and sources:

There is also theme support for WP block styles, where we include the bundled styles for blocks that come with WordPress. Finally, there’s added theme support for “align-wide,” which allows us to align images “wide” or “full-wide”, outside of the regular content. 

Scrolling down, you’ll see support for the editor color palette. These are the colors you see in the sidebar of the Block Editor. Here, there are a handful of different colors defined, and you can see how they work: 

Toward the very bottom, we also have theme support for editor font sizes. It’s the same concept: an array of font sizes that you can customize to fit with your particular needs. 

Note: When you add custom colors and custom font sizes, you also need to add adjoining CSS to match. That CSS is found inside /assets/css/src/_custom-properties.css.

Below, you can see the custom editor colors. They’re all defined as custom properties (or CSS variables). Same with font sizes. The colors and font sizes are applied in “content.css”:

If you scroll further down inside content.css you’ll see “Custom block colors.” We have the CSS classes .has-theme-primary-color, .has-theme-secondary-color, and so on. And all these colors and sizes are defined.

When you use these features remember: you also have to make changes to your CSS accordingly. 

Other functionalities defined in the “/inc” folder

Now that you see how these PHP modules work, you can read through the list of folders inside the “/inc” folder and kind of get an idea of what these different functionalities are.

A few examples: “Image_Sizes” controls image sizes, “Nav_Menus” controls nav menus, and “Post_Thumbnails” activates support for post thumbnails. “Sidebars” is where we define the actual sidebars.

(Note: the Lazyload module has been removed since it is now supported by WordPress core functionality.)

You can see the /inc/Sidebar/Component.php file above. Any time you want to make a change or add additional features, you do it inside these files by just extending what’s already there, copying functions, and then getting everything to work.

Optional template files

WordPress uses what’s known as the “template hierarchy” to figure out which template file to use when displaying a specific type of content. This graphic comes from the WordPress template hierarchy page (interactive version of WordPress template hierarchy) in the WordPress developer handbook, and it shows you the entire flowchart of the process of selecting which template file to use.

WordPress template hierarchy diagram (see previous link for interactive version)
WordPress Template Hierarchy chart

I’m showing you this because, at the very end, on the right hand side here, you can see index.php. This is the fallback file for all template files, so if no other template files exist, WordPress automatically falls back to index.php as the main template file. That’s what WP Rig does out of the box. It provides index.php as the only template file in use. However, as you’ve seen previously in the course, WP Rig also ships with optional template files directly from the template hierarchy, you can drag and drop into your theme and they automatically take effect. Those template files sit under the folder called “optional“.

Template files in optional directory

  • archive.php
  • attachment.php
  • category.php
  • custom-page-template.php
  • custom-post-template.php
  • front-page.php
  • search.php
  • single.php
  • singular.php

Here you have template files for the most common things people want to do in the template hierarchy. Things like a template for single.php, that would be a single post. A template for page.php, that would be a regular page. A template for singular pages, that would be pages or posts. We have archive, and attachment, and category, and a custom page template, a custom post template, and even a front page template.

The idea here is, all of these optional template files have been created so that they are quite opinionated about how to display content. They are different from what index.php would do, and give you a starting point as you start extending your theme. The idea here is, as you build up your own theme, whenever you run across a situation where you need a custom template for just one scenario, say only single posts, they maybe need some additional content, or only pages need a certain type of styling, or you need to customize the search output, or maybe you need a custom template for a specific category, or all categories. In those circumstances, you can go into the optional folder, grab whatever file matches roughly what you want, and just drag and drop it into the root folder. That template file then automatically takes effect and takes effect in place of index.php for that particular template scenario, and then you can use that template file to customize the experience further.

I recommend you take some of these files and dump them into the root of the folder, just to see what happens and see how they work differently. They can be useful, but they’re not always necessary, so think carefully about how you do things here. First, make sure that you use modularity as much as possible to create the output you want without adding additional template files, then if you can’t make those modules work the way you want to, then consider adding in one of these optional template files to give you that extra level of control of a specific display, and if that doesn’t work, then you can create your own custom template files based on either the optional ones, or based on the template hierarchy you see here.

Templates and file structure

The templates in WP Rig work pretty much the same way WordPress templates have always worked. The only difference is they’re more modular than they have been previously.

index.php = single template for all views

Out of the box, WP Rig uses index.php as the single template file for all views, meaning whether you have a post or a page or an index page or an archive, it’s all powered by index.php. This is to make the starter theme as small as possible, and it gives you the option as the developer to choose how you want to extend it, rather than having to work with existing files.

<?php
/**
 * The main template file
 *
 * This is the most generic template file in a WordPress theme
 * and one of the two required files for a theme (the other being style.css).
 * It is used to display a page when nothing more specific matches a query.
 * E.g., it puts together the home page when no home.php file exists.
 *
 * @link https://codex.wordpress.org/Template_Hierarchy
 *
 * @package wp_rig
 */

namespace WP_Rig\WP_Rig;

get_header();

wp_rig()->print_styles( 'wp-rig-content' );

?>
	<main id="primary" class="site-main">
		<?php
		if ( have_posts() ) {

			get_template_part( 'template-parts/content/page_header' );

			while ( have_posts() ) {
				the_post();

				get_template_part( 'template-parts/content/entry', get_post_type() );
			}

			if ( ! is_singular() ) {
				get_template_part( 'template-parts/content/pagination' );
			}
		} else {
			get_template_part( 'template-parts/content/error' );
		}
		?>
	</main><!-- #primary -->
<?php
get_sidebar();
get_footer();

Looking at the actual index.php template file, you’ll see this is very much like any other WordPress template file (see code sample above). Off the top, we call get_header(); which gives us header.php. Then we call in the style sheet for the content style so that it appears right above the actual content it will style. Then we have a <main> element and we do the post loop where we check to see if there are any posts available.

If there are posts available, then we get the template part called page_header. So that displays just the header section of the page. Then we go and see while we have posts, go get the posts, and then run the template part called entry. And here we’d look for the current post type, and then we grab that template part and display it. Then, if this is not a singular post, meaning it’s an index of some sort, then we get the template part called pagination to display previous posts or newer posts at the bottom. And then finally, if something goes wrong or there are no posts, we can also get the template part for error. Then at the very bottom, we can call in sidebar.php and then footer.php just like any other WordPress theme.

Modular PHP within template-parts directory

What you see here is the main difference between this template and WordPress template files you may have worked with in the past or template files you’ll find in other themes: in WP Rig there are far more modules, or more pieces to this. That’s because WP Rig wants to make development as easy as possible for you. And breaking things apart like this helps you create dry code, without it being too complex.

So what’s really happening here is we use all these different template parts to focus in on specific functionality. You can see all these template parts in the folder that is aptly named template-parts. Here, we have template parts for content, that would be the main post or page content. We have template parts for the footer, that’s on the bottom of the page. And we have template parts for the header.

screenshot of code editor showing file structure of WP Rig, template-parts directory is circled (/wprig-master/template-parts/) with subdirectories: content, footer and header
Go to /template-parts/ to find PHP template parts that are pulled into index.php

If we go up to header first, you can see kind of how this works. So if I open up header.php, you’ll see header.php starts off like any header does. We use declare the doctype and set up the overall head section of the document. Then we set up the skip-link so that we skip down to the content for accessibility purposes, and then go into the actual header with a class site-header.

screenshot of header.php file with header element (class of site-header) and template parts within header: custom_header, branding, and navigation (location of header template parts: /template-parts/header/branding.php, etc.)
header.php pulls in branding, custom_header and navigation from PHP files in /template-parts/header/ directory

And here we have three components, custom_header, which displays the custom header image, branding, which displays the site title and tagline, and navigation, which is the main menu.

These three pieces are contained in three separate modules up here under template-parts and header. So custom_header.php displays the header image tag, branding.php displays the site-title and site-description (see screenshot below of branding.php), and navigation.php sets up the site-navigation.

screenshot of branding.php file where site-branding and site-description div elements are created (located in /wprig-master/template-parts/header/)
branding.php file creates branding HTML and is located in /template-files/header/

Now seeing this, you can also see why this has been modularized to this extent, because it means if you have a custom post type and you want to have a special navigation just for that custom post type, you can create a new navigation file here, make some slight alterations to the existing code, and then save it as a new file, and then call it in from a custom header file. Same thing with branding.php, same thing with custom_header.php, and everything else. So you don’t have to make changes to the file and then copy a bunch of stuff over, you’re only working on the specific component you’re looking for. This becomes even more clear when we look at content (/wprig-master/template-parts/content/).

screenshot of entry_content.php file in code editor (located in /wprig-master/template-parts/content/)
entry_content.php is shown (located in /wprig-master/template-parts/content/entry_content.php)

Here we can see entry-content.php, which is the file that generates the actual content of a post or page, only focuses on the entry-content and nothing else. So here, you have just the content and then links (page-links) if there are multiple pages to the content, and nothing else. Then you can place that in any order you want in relation to other pieces of content. And you can also focus in on this ONLY if you want to create a specific template for something else. This modularity is in place to make it easier for you to make custom templates, and also easier for you to find the code you’re looking for, any time you want to make a change.

PHP in WP Rig

The PHP in WP Rig is fundamentally different from how themes have used PHP in the past. If you’ve worked with themes before, you’ll notice this right away. The file and folders structure is new, and what goes inside the files is also new.

So what’s going on? The simple answer is WP Rig has been re-engineered from the ground up to use PHP according to modern standards and best practices. The complicated answer is that the PHP in WP Rig is object-oriented, modular, and uses namespaces for added functionality and security.

If you’re interested in the technical aspects, you’ll find an extensive article explaining all of this in great detail on the WP Rig wiki page. The good news is, you don’t have to be a PHP expert, or an expert on object-oriented PHP to make sense of this new way of doing things. Everything works the same as before, just slightly differently.

In this chapter, we’ll take a deep dive into the PHP of WP Rig to give you a firm understanding of what’s going on, and how everything works so you can work with it.

Advanced CSS debugging and configuration

Because your theme uses several different modular style sheets and some of those style sheets import the content from partials, it’s important to know how to find out what file holds a specific style rule, so you can edit it directly.

The build process has accounted for this scenario by generating source maps for each style sheet. These source maps are available to the browser, so when you open the dev tools of any browser and inspect an element, the browser will tell you where that particular rule sits in the original style sheets.

In this example, you can see the inspector is telling you that the CSS is being set in _typography.css:

These source maps make it easy to navigate the original CSS files when you want to make changes to your CSS.

Remember, though: in the end, the browser is only served with the global.min.css file. The CSS from the _typography.css file sits inside the global.min.css file in a minified format.

In some cases, you may need to look at the actual minified code that’s output through the build process. (Sometimes, there are scenarios where what you write in the original files may look correct, but once it gets compiled out, something goes wrong and you need to find out what that is.)

The problem is, if you look at the actual output of these minified files, you see that they’re almost impossible to read for humans. That’s great for computers — no spaces, no wasted data. But humans cannot read this in any functional way:

For that reason, there’s a configuration setting you can use to turn the the minification off temporarily for CSS.

You find it in the “config” folder, inside the “config.default.json” file. In the “debug” section, you can change debug settings for styles, scripts, and PHPCS.

(Note: Here, debug for styles and scripts should be set to false by default, and PHPCS should be set to true. It is set to false here in the recording and in the screenshot below for technical reasons.)

In the “debug” section, having “styles” set to “false” means that the CSS that gets output is minified.

If you change this to “true” and then restart the build process, the build process will output the same exact CSS, except it won’t be minified in these files. So that way, you can actually see in a human-readable form, what the CSS looks like when it gets served to the browser.

This is only useful if you run into really serious problems and you think something is going wrong in the build process. But, it does happen, and that’s why this feature exists, so that you can directly test the code.

PostCSS settings

There’s some other interesting things related to styles inside this config file too that are worth looking at. Under the “styles” section, you’ll see it says “stage: 3”.

Stages relates to how advanced you want the features in PostCSS to be. Stage 3 means you are adopting some pretty aggressive standards when it comes to modern best practices for CSS. That means you can use modern features that are not currently available in browsers; then, PostCSS and Autoprefixer will make the code work for older browsers for you.

If you’re less willing to use modern features, you can change this number. Stage 1 would be just for current browsers. But we’d recommend leaving the setting at Stage 3, because that’s like a nice, aggressive stance on future standards.

(Reminder: If you want to change any of these settings, you do it the way we’ve outlined changing other settings in the past: you copy the entire section out and place it into config.json, matching the structure of the config.default.json file. The config.json file is where you change and customize the settings to whatever you want.)

We’d recommend leaving these defaults in place, though. Because although all these things are currently cutting edge, they will become the new standard in the future. And building standards-based code today will mean that your themes are ready for when that future comes.

Create and preload stylesheets

Seeing how modular style sheets are called at individual template level, one of the first questions you may have is, “how do I hook into this feature and add my own custom, modular style sheets?”

Conditional preloading of stylesheets can be used to improve the performance of the theme.

Say for example, you want to create a stylistic change that only appears on single pages, using the page.php template.

The first thing to know is that WP Rig only uses one template file out of the box: index.php, which is used to display everything. (The front page, whole pages, archives, everything is run off index.php.)

However, if you go into the WP Rig files, you’ll see there’s a folder called “optional” that contains optional template files you can use if you want to.

This video will give you instructions on how to use those template files, and how to set up stylesheets that -only- apply to those templates.

(Note: The plugin referred to in this video is “Show Current Template”. To download it, go here: https://wordpress.org/plugins/show-current-template/)