Get it All
Together

One of the most important concepts in the world of WordPress web development is that of the parent/child relationship between themes. The parent/child relationship is a scenario in which a “parent” theme represents the final source of all code: if you cannot find a given file in a theme declared a “child” of one parent, then you should be able to find that file in the parent. The purpose of this relationship is to allow the child theme to extend and enhance the parent theme as suits a given website’s needs, while still maintaining the base level functionality of the parent theme. This failover system further augments WordPress’s excellent Template Hierarchy structure, guaranteeing a suitable template layout file for any request.

When properly understood and executed, this parent/child relationship allows developers to build complex parent themes from which all manner of new websites can be built in the child theme. Doing so is a sure-fire way to maximize the learning curve of your software: new techniques and interfaces can become available to the next project, instead of stuck in a single-site solution.

In my case, my parent theme is really just a toolbox of functionality and layout helpers with almost no usable layout of it’s own: it provides the toolbox and a few baseline layouts like a generic archive and single-post page. All the implementation of that toolbox happens in the child theme. I have even augmented the parent/child relationship a bit by providing failover support for JavaScript files and non-layout files in my theme.

That said, I’m always looking for better ways to make use of this relationship. So I was pretty excited when I found out that Advanced Custom Fields comes with the option to save it’s field declarations as local JSON files. I’d previously been doing all the work of creating Custom Post Types – and their backend interfaces – more or less by hand. But having worked with ACF for a bit, I realized it was a more efficient means of adding meta fields by miles.

Now it seemed, I’d found a way to statically create the fields I needed for my base CPTs and have them extend and be extended by a child theme. Perfect!

Not So Perfect, Yet.

Now, I’m pretty particular about my directory structure for my plugins. I like things organized more like the PSR2 standard prefers and fortunately, the WordPress-Core standard also recommends something similar. With that in mind, ACF’s default location for local JSON does not suit me. I’d rather not have an /acf-json directory in the root of my theme. Instead, I’d prefer to have my ACF-specific JSON files live somewhere in the /Library/ directory of my theme.

But there is a solution for this! Advanced Custom Fields provides filter hooks in that part of the code that saves and retrieves JSON, as they explain in the documentation for local JSON. Those hooks are ‘acf/settings/save_json’ and ‘acf/settings/load_json’. So my first attempt to move the JSON to my desired destination looked like this:

The persistent problem I ran into with this setup was that ACF seemed always to be confused as to which directory it should be saving and recalling from. If you read through that code, it at least attempts to establish the same parent/child relationship as WordPress uses for standard template files. New changes to Custom Fields should always be stored in the current (most often, the child) theme directory. When pulling JSON to populate fields, a child theme’s /Library/Acf-Json folder should be used first, followed by the parent theme.

But in practice, after successfully changing a field name in a child theme, the Custom Fields admin pages would show the correct new name and the Write Post screen would display the old name. Those fields did not present the option to “synchronize” themselves, so there seemed to be no real fix. This was all discussed with the forum help at ACF here.

After a bit of digging and considering and reading the actual ACF files in question (/advanced-custom-fields/includes/wpml.php, if you’re interested), I decided that rather than simply add my own code to the acf/settings/save_json hook, I would remove the default function completely. By doing this and using array_push to be sure I was saving the directories in the correct order, I was able to achieve the the correct functionality. So I commit this blog post for the benefit of those who find themselves similarly challenged by this super-helpful but perhaps less than well-documented feature of Advanced Custom Fields:

For nearly as long as there has been a WordPress, themes have included a functions.php file. This file provides a lot of extra, for lack of a better word, “functionality” to your WordPress blog. And while so much else about WordPress has changed over the years, it is quite remarkable how little about the functions.php file has evolved.

This is particularly true in light of WordPress’ ability to create child themes. Child themes are separate themes which extend the functionality of their “parent” themes by overriding key theme files. A child theme may only have a style.css file, to refer back to the parent. Or it might include a single.php file, because in the case of this one theme, you want all the functionality of the parent, but you’d like single posts and pages handled differently.

The trouble is: while a template file can override it’s parent, the WP functions.php file just basically loads the namespace with a bunch of free-floating functions, usually prepended with the name of the theme. There isn’t any “overriding” a function in PHP; the only thing you can do is write another function with still another name or prefix. That’s not very efficient use of the namespace and a recipe for confusion.

Instead, what I decided to try was putting my entire list of functions inside a class. Call it ParentFunctions. Inside this class, I also included a self-named initialization function that would do the adding of filters and actions as necessary. Then, all I need to do is instatiate my object – and be sure to call the “global” in each file where its necessary – and I’ve got an extensible model from which to create child themes.

Let’s look at ParentFunctions:

Among the advantages, here, is that our namespace is much cleaner. So is our code: instead of having to trawl through a couple dozen prefix_function_name entries, I can get straight to function_name. But better still, if I want to modify how a function works in a child theme, that’s even easier:

Using classes in your WP functions.php file provides a cleaner, easier interface for extending your themes for whatever you need.

There’s lots of information available on WordPress’s codex about how to create themes for your blog, all of it dealing with the filters and actions you can use to manipulate the active content on your blog in cool ways. It goes without saying that those are important pieces of information, and in fact there are some outstanding tutorials for putting together a theme that you should definitely check out. WPBits is one such resource.

But I’d like to talk about some concepts that happen before you get to the active content: the HTML, and how you go about designing a theme which has to exist in all those varying pieces yet all go together to create one cohesive whole. This is a very high-level tutorial, meaning that specific details will be omitted in order to introduce the most basic concepts. I’m writing more about the workflow than about the process, if you follow me!

Continue reading