WordPress offers a clear separation between design, content and functionality.
Themes very clearly handle the overall design and layout of a website while plugins offer the ability to add new features to the WordPress installation.
Therefore, the question of whether or not your functionality belongs in a plugin or a theme should get a fairly straightforward answer. In practice, the waters get a bit murky when considering both the flexibility of WordPress as well as the divergent intentions of different web developers.
Before we examine these nuances though, let’s first define exactly what we mean by “functionality”.
The term “functionality” is a common buzzword that gets thrown around pretty loosely these days by developers, designers and clients alike, but exactly what are we talking about when we reference it?
For the most part, just about anybody involved would agree it to be a general term describing a specific feature set that has been introduced into a system. In WordPress, almost all types of functionality can be broken down into four primary categories:
- Core WordPress functionality
- Functionality that enhances existing feature sets within core WordPress
- Functionality that introduces entirely new feature sets unavailable within core WordPress (including third party application integration such as Twitter)
- Functionality that aids a specific theme in handling variables from a design and layout perspective
Whether you are looking to add a real-time feed of Tweets to your sidebar, a jQuery image gallery on your home page, or set up your site to be ranked better in search engines, these four categories should cover just about anything you want to throw at WordPress.
If we accept that all functionality within WordPress falls within one of these four categories, and if we consider that WordPress provides us a logical location to “house” specific types of operations, we can make some fairly linear projections as to whether a specific piece of functionality belongs within a plugin or within a theme.
Core WordPress functionality is simply included within WordPress, and should never be directly edited at any time. If you do, bad things can happen to you … think “removing random pieces of your engine just to see what happens”.
Functionality that either enhances existing WordPress core features or introduces brand new features typically belongs as a plugin so it can be added and removed as necessary.
Likewise, functionality that aids a specific theme belongs within that theme, but it’s useful to note that this is typically scripting that helps display specific pieces of content rather than add or extend functions—in this way, the intent of the scripting is different. It’s more about display logic than it is about site functionality—and that’s probably the most important distinction to make in determining for yourself where to place your site’s custom functionality.
Display Logic and Site Functionality
The truth is that while you are, indeed, working with functional pieces of scripting on your site, you should be able to pretty squarely place any scripting into one of two categories. The script either:
- Adds to or enhances the actual features of your WordPress site (Site Functionality), or
- Assists you in displaying that information to your audience (Display Logic).
We all have a pretty reasonable idea of what site functionality is, but display logic has everything to do with how we actually display useful data within the context of the theme. Common examples of display logic include:
- Registering sidebars and widgetized areas
- Registering new WordPress menus
- Custom conditional logic inserted into the Loop
- Post thumbnail scripting references such as TimThumb
Incorporating pre-fabricated site functionality via the plugin system by customizing a theme’s display logic is the most common form of WordPress development performed by the typical WordPress developer.
Most of us spend our time finding slicker and more effective ways of integrating existing tools we find across the Web to create solutions for our clients.
Often, the difference between good coding practice and poor coding practice lies in recognizing the difference between actual site functionality and display logic, and coding each in the appropriate location.
ABC Real Estate: a Case Study
If this is all as clear as mud so far, let’s see if we can’t clean up the stream a little bit by applying it to a practical example. Suppose we have a new client who is a realtor with ABC Real Estate, and they’d like us to develop a new site built on WordPress with the following special “functionality” requests:
- Because they’ll be running regular seminars, the client would like some form of an event management system
- The client would like to make sure that each of their properties is displayed in a constant, intuitive way that leaves room for multiple photos—the number will vary per house listing
- The client would like to show six featured properties that they select on the home page in a specific format
- The client would like Facebook comments integrated into their site so that visitors can easily share potential homes with their friends
Each of these requests seems more than reasonable and intuitive for a real estate website, but let’s sort out exactly where we’d add each piece of functionality listed above.
1) Because they’ll be running regular seminars, the client would like some form of an event management system
This one is pretty simple. Because WordPress doesn’t contain an event management system in its core, we’ll need to add one via the plugin system. Could we write our own and add it directly to the theme itself? Technically, sure—but it wouldn’t make a lot of sense because there are already so many event management systems available that we can try in a heartbeat.
Further, if we were absolutely bent on writing our own system, it’d be easiest to contain all of the files necessary for the system in their own place to keep things tidy … sounds like a plugin to me.
2) The client would like to make sure that each of their properties are displayed in a constant, intuitive way which leaves room for multiple photos—the number will vary per house listing
This one is a touch more complex, and a bit of a trick question. Since we are talking about how things are displayed, you might think we’re immediately in the realm of display logic. However, WordPress 3.0 introduced the notion of post types which allows developers to create a specific display format for a specific type of post.
You can collect a discrete set of data within the WordPress Admin for each record within the post type, and then output that record to a post template inside the theme which allows the post to be output to the screen in a specific, unique way.
Because of the unique way that post types operate, when you work with them you are essentially forced to create both display logic as well as site functionality. We’ll go over this in a bit more detail further on in this article.
3) The client would like to show six featured properties that they select on the home page in a specific format
This is display logic. We’re adding nothing new here at all, but rather picking specific pieces of stored content from the database. This is always done directly within the theme.
4) The client would like Facebook comments integrated into their site so that visitors can easily share potential homes with their friends
Third party application integration—in this case, it’s Facebook. Piece of cake … we’ll add one of the litany of Facebook commenting plugins available for WordPress and integrate it appropriately. Plugin, all the way.
“Great, so I understand how WordPress would prefer me to add my site functionality, but I have my own way of doing things that really works for me.”
To that I say, “I completely understand where you are coming from, but allow me to make a few (hopefully) compelling points that just might change your mind”.
First of all, if you are developing site functionality yourself, you’ll likely find it much more useful to do so within the context of a plugin than directly within the theme for purposes of portability.
After all, even after a specific job has been completed and the site launched, a large percentage of developers retain intellectual property rights to programs that they develop and utilize within sites they work on, and sooner or later there is a necessity to reuse the same code (or a version of it) for another project. Plugins make this site functionality portable and easy to install, saving quite a bit of time in the long run.
Because WordPress plugins are structured to maintain all of their files in separate directories away from other plugins and core WordPress features, they inherently provide an instant modicum of order to the functions written throughout the site.
For instance, if you are having an issue with the meta description on the home page and you know you are using an SEO plugin that handles that specific function (easily looked up by referencing the active plugin listing in the WordPress Admin), you’ll know exactly where you need to begin investigating the source of the issue, even if you were not the original developer that put the site together.
In this way, plugins can actually provide a loose form of documentation in and of themselves, giving developers reasonable clues as to where certain functions might live in even the most poorly documented sites.
Troubleshooting is another fabulous reason to maintain site functionality within plugins rather than embed it directly into the theme. Adding new features to a WordPress site can occasionally cause conflicts and “break” a website, causing any number of display or performance issues that need to be corrected.
When these types of things go bump in the night, the first line of defense most seasoned developers leap to is to begin an examination of existing plugins to see where scripting may be happening. Using WordPress’s plugin system to activate and deactivate plugins provides a handy way to eliminate active scripts running on the site and bring them back one by one to determine which are the offending scripts.
Without the ability to turn plugins on and off, a developer can be stuck stumbling around in the dark trying to sort out exactly which scripts are conflicting with one another and causing a buggy result to the end user.
Finally, don’t underestimate the importance of flexibility in your website functionality. The more of the site’s core functionality that is directly built into the theme, the more difficult it becomes to make design changes to that theme, or even swap out entirely. It may sound clichéd, but the Web is constantly shifting and changing, and ultimately so is your website—probably faster than you might think.
Hard coding site functionality into a theme can lead to time consuming edits, changes and overhauls in the long term (and often the short term as well) as you realize that something you thought was so absolutely crucial yesterday that you based your entire site development upon it becomes entirely obsolete next week.
Believe me, it’s happened to the best of us.
Breaking the Rules
“Alright …” I hear you say. “That’s all well and good, but I have a good reason to deviate …”
Every subjective argument like this has situations that bear solid reasoning to go your own way, and I think it’s useful to point a few out here as well.
Reason #1: Post Types
In our case study, we discussed putting together a customized post type to handle the display format for a property listing. Pragmatically, this involves putting two pieces of code together: 1) an array initializing the data for the post type, and 2) the post template to handle the visual display within the context of the theme.
While the second component here is clearly an issue of display logic, the array initializations are a bit more fuzzy. This function is commonly defined within the theme’s
functions.php file, but it’s important to note that it could be defined with a functions file initialized within the plugin system.
In many ways, this makes a touch more sense as it keeps a clean separation between site functionality and design components, but as of this writing initializing the array within the theme’s
functions.php file is the clearly the most common practice. It is certainly a gray area.
Reason #2: Specialized Page Templates
Occasionally, it becomes important to create a special page on a WordPress site that simply performs a specific function. Perhaps you are iframing something from another site, or pulling in some type of custom functionality that isn’t particularly conducive to working within the constructs of the standard WordPress page template and content editor.
When this is the case, a common practice is to register a new page template with the standard WordPress syntax in the template file, and then include the functionality directly within that particular page. In this instance, the functionality is not portable to other sites at all, but often it is done in a situation where that is not necessary.
Reason #3: Protecting the Client from Themselves
As much as we’d all like to believe that WordPress is a bulletproof system that clients are unable to break, we all know that isn’t wholly accurate. Occasionally, there is a very good reason to hard code something.
Let’s say you have a client who needs to edit the sidebar on his or her website, but continually adds to or edits the wrong item. In this instance, it can be useful to hard code simple elements into the sidebar that you are reasonably sure the clients themselves will never need to update on their own, guarding against the possibility that they might accidentally delete it.
Examples of things that might be hard coded could include an email opt-in box, or perhaps social media connection buttons.
Reason #4: Developing a Specialized Product for a Specific Industry
There are many theme developers out there who build targeted WordPress themes tailored to specific industries. These themes lack a certain amount of flexibility, but the upshot is that for the target market they serve additional flexibility is unnecessary. Examples of this include real estate specific themes, product review themes, or question-and-answer aggregation themes.
Reason #5: Time and Budget Considerations
It’s sometimes faster to code something directly into a theme than it is to make it modular and use a plugin as defined as best practice. When time is a factor or your client has a tight budget you need to adhere to, an argument can be made that a legitimate reason exists to cut corners and code site functionality directly into the theme.
It’s important to note that this is certainly not best practice, but it is a reason to do what you need to do to get the job done.
What’s the Bottom Line?
The question of where to house your site’s functionality is like just about anything else … there is a straightforward answer based on fairly finite rules, but you can always come up with the justification to go your own way if needed.
Best practice is to determine which functionality is best described as display logic and which functionality is best described as overall site functionality, with display logic being added directly to the theme and site functionality being enveloped within the plugin system.
Is this reflected in the way you work?