I write quite opinionated front-end code. It’s one of the advantages of working in the industry for around twenty years, I know what does and doesn’t work. Working in a rapidly developing industry long term has taught me to be open-minded too, to listen to new ideas and to be prepared to adapt them. I’ve learnt the only constant is change.
That said, despite my opinions I dislike declaring something an anti-pattern or is considered harmful. If there was one function in WordPress I could rename, it would be doing_it_wrong
.
The five common WordPress patterns that follow are five patterns I avoid when developing themes and plugins. Below I explain why I avoid them, I’d love to know which of these ideas work for others.
Default body and post classes
WordPress’s default body_class
and post_class
functions return a large number of HTML classes by default.
Taking this post as an example, the default body class would be single single-post postid-3198 single-format-standard
and the default post class would be post-3198 post type-post status-publish format-standard hentry category-code tag-wordpress
.
None of these class names match my naming convention, so I like to strip them down substantially. I prefix my body classes with t-
(for template) and aim to reduce the classes to either t-List
or t-Singular
. You can find the code for this in an earlier post on controlling the body class.
The post class gets a similar treatment, although it is reduced down to the component name I have chosen for the site and any required microformats class. On this site I start with Article
, hentry
and h-entry
(microformats 2).
Using microformat classes for styling
Microformats are class names Google and other popular search engines use to understand the data on a web page. A list of posts will contain several hentry
blocks to indicate each post, and each post will contain an entry-title
to indicated the post’s title.
A common example for styling these is to attach the styles to the microformat class:
.entry-title {
font-size: 1.5rem;
margin-bottom: 0;
}
As search engines support multiple forms of structured data, I like to treat the microformat classes as hooks for the search engine only. Down the track, should I decide to replace the microformats with schema.org, the microformat classes can be removed without the need to alter the CSS.
Testing the body class for JavaScript conditionals
Some of the most useful PHP functions in WordPress are the conditional tags; is_single()
and is_front_page()
(to name two of many). Most of these conditional tags are reflected in the body class, i.e. is_single()
adds the single
class and is_front_page()
adds the home
class. Unfortunately, these functions have no JavaScript equivalent. As a result, you often see code testing the body class as a proxy:
isSingle = -1 < document.body.className.indexOf( 'single' );
if ( true === isSingle ) {
// do stuff
}
As themes and plugins can filter the body class, it’s not possible to be 100% certain the presence of body.single
matches the output of the PHP function is_single()
. In most cases it probably does but I don’t like to depend upon a probability.
Instead, I use the JavaScript localisation features of WordPress to pass such tests directly from PHP to JavaScript. For an enqueued script with the handle pwcc-functions, the result will be:
wp_localize_script( 'pwcc-functions', 'pwccConfig', array(
'is' => array (
'single' => is_single(),
),
) );
As a nice side-effect, in JavaScript the test becomes clearer:
if ( true === pwccConfig.is.single ) {
// do stuff
}
This approach is less likely to result in errors if a theme or plugin changes the body class in ways that haven’t been considered. It’s coding defensively.
Just use jQuery
If a script depends on jQuery in WordPress, it needs to list it as a dependency when registering or enqueuing it:
wp_enqueue_script(
'pwcc-functions', // handle
'/path/file.js', // source
array('jquery'), // jQuery
'20150530-31', // version
true // load in footer
);
This actually enqueues two external files, jQuery and jQuery migrate. jQuery migrate adds a backward compatibility layer that may not be needed for your site.
For reasons of backward compatibility, WordPress loads jQuery and jQuery migrate in the HTML header. Each file blocks rendering of your site and slows it down for your visitors. Allowing jQuery migrate to load will slow it down further.
If you maintain your JavaScript to avoid deprecated jQuery functions, you can remove the reliance on jQuery migrate and save your visitors an HTTP request by listing jquery-core
as a dependency.
In general, I think there is an over reliance on jQuery and other libraries in web-development but that’s a story for another day.
Starting with more than two templates
As the section on the body class indicated, I consider WordPress themes to be constructed of two main templates: a singular template covering pages, posts and attachments, and a list template covering archives, the blog index and search results.
My themes start with singular.php (introduced in WordPress 4.3) and index.php.
A complex theme may require additional templates, in which case I will build up the theme rather than start with complexity built in.
What are your practices?
These are the common patterns I avoid, it’s what works for me. My approach is to start simply, to code defensively and to build up from there.
Leave a comment letting me know what works for you. If you think something on the list above is doing_it_wrong (for want of a better name), tell me why. I can learn from other’s experience as much as my own.
Leave a Reply