What is a WordPress theme?
For anyone who has worked with another development framework, this question can be a mysterious proposition. With other frameworks – Drupal, Ruby on Rails, Symphony and so on – the separation of concerns principle is easy to discern.
Whether it is the view in an MVC system or the presentation layer in an OSI model, the part of the software or framework that controls what the user sees is easily definable. While a WordPress theme does, in general, provide the presentation layer, it can do much more.
The fact that the bar to entry for WordPress is so low is both a gift and a curse. It is a gift because one can dive in and do amazing things without a high level of technical knowledge (I realise now that I built my first theme without any real understanding of PHP – I was a master of copy and paste!)
It is a curse because as a platform it is so forgiving. You can go against the WordPress coding standards for PHP, HTML, CSS and JavaScript (netm. ag/standards-267) and it is possible that your theme will still work just fine.
In this article I will lay out some tips to guide you to better development practices and a more thorough understanding of WordPress themes.
I will explore how to structure your theme in a sane and straightforward way, and take a closer look at the WordPress templating system and how data is retrieved.
Follow these rules and you'll be on your way to creating a perfect WordPress theme in no time.
01. Separate functionality and presentation
Many WordPress theme authors try to cram all the functionality into their theme, when much of it belongs in plugins. I am very much an advocate of keeping a theme as close to the presentation/view layer as possible.
If the functionality I am working on does not provide visual enhancement or frontend display, it probably belongs in a plugin. Limiting theme functionality also enables users to more easily change the look of their site, without fear of losing a key piece of functionality.
What if you have a plugin that is tightly coupled with the theme? My approach here is to include styles for the plugin functionality in the theme.
This approach can also potentially lower the number of http requests, which makes for better site performance.
02. Write procedural code
As I have become more involved in the WordPress community, I have seen a common thread in those of us who consider ourselves 'themers': many of us learned our PHP through learning WordPress.
WordPress is written in a mostly procedural manner, which means many of us understand procedural programming better than we do object oriented programming (OOP).
But because WordPress still supports PHP 5.2 we tend to find ourselves either writing pseudo- OOP code or prefixing all our functions with something in order to prevent naming conflicts.
I think we should to try and push our community forward and not limit ourselves because of a version of PHP that has been unsupported for over four years (netm.ag/version-267).
I encourage you to use PHP namespaces (netm.ag/ namespaces-267) instead of pseudo-OOP code or prefixed functions, especially when you're building themes for clients directly and know the environment the code will run in.
I only learned about PHP namespaces late last year, and now I want to go back and rewrite everything I have ever done.
Defining a namespace or sub- namespace helps ensure your files are organised and readable. Each of these namespaces is a different scope, so you can have functions with the same name throughout your project.
As long as these functions are in a different namespace, you will not create conflicts or cause fatal errors in the site.
In the examples shown in the images above, you'll see that both files have functions called load() and register_taxonomy() but they are not within a class.
They are written just like the procedural code we are familiar with working in WordPress. And since they are in separate name spaces there will not be issues.
03. Enqueue your scripts and styles
I will be the first to admit that on the first couple of themes I built, I did this wrong.
If you come from a world of static HTML, you will be accustomed to writing tags such as
<pre><link rel="stylesheet" type="text/ css" href="theme.css"></pre> or <pre> <</script></pre>)
The third argument is dependencies. For example, let's say you are adding a slider script to your theme and this script requires jQuery to be loaded before it will work.
Using the direct linking method, you would have to pay close attention to the order in which you placed these files.
Using wp_enqueue_script() to include your slider script means you can pass a dependency of jQuery and WordPress will make sure jQuery is loaded on the page before your slider script.
WordPress ships with a couple of dozen scripts (netm.ag/scripts-267) that you can add using this method by simply calling the handle to enqueue, or passing the handle as a dependency of your script.
The wp_enqueue_style() function also has a dependency argument, so you can determine load order of style sheets as well.
The other reason I recommend using wp_enqueue_script() is the last parameter in the wp_enqueue_script() function referenced previously, which determines whether or not the script loads in the header or the footer of the site.
By default, the function will load the script in the header. I wish it was the other way around, as most scripts should be loaded at the bottom of the page, for performance reasons (netm.ag/ performance-267).
However, this gives you an easy way to determine what loads in the header versus the footer of a site, instead of having to copy tags between the two.
04. Use template parts
Have you noticed that I like breaking things down into components a lot?
WordPress has a highly useful function called get_template_part() that we can use in our templates to call bits of reusable and frequently used code. I often use this function inside the WordPress Loop, as seen in this example from a 'page.php' template:
<pre> <?php if ( have_posts() ) : ?> <main id="content" class="site-content" role="main"> <?php while ( have_posts() ): the_post(); get_template_part( 'partials/content', 'page' ); endwhile; ?> </main> <?php endif; ?> </pre>
The inside of 'content-page.php' looks like this:
<pre> <article class="entry"> <header class="entry-header"> <?php the_title( '<h2 class="page-title">', '</h2>' ); ?> <?php if ( ! empty( $post->subtitle ) ) {?> <p class="subtitle"><?php echo esc_ html( $post->subtitle );?></p> <?php } ?> </header> <section class="entry-content"><?php the_ content(); ?></section> </article> </pre>
Many of my templates will use exactly the same logic and markup as above. By using get_template_part() , I can include that entire snippet with just one line of code. And if I need to change the markup or logic, I only have to alter it in one place.
While there are many more points we could discuss on building themes, this list will get you a long way towards creating a clean, maintainable and secure WordPress codebase.
Words: Corey Ellis
Corey Ellis is a senior frontend engineer at 10up. He's also the organiser of WordCamp Austin 2015 and helps run the WordPress Austin Meetup coreyellis.me. This article was originally published in net magazine issue 267.
Liked this? Read these!