A common, yet unfortunate practice in the WordPress community involves filling theme functions.php
files with tweaks and functionality that is key to a site. The reason this is a bad idea, in short, is that it will tie your critical site functionality to a theme that will eventually change. Good news, though: there is a much better, smarter alternative. It’s called a functionality plugin.
We’re going to create a very simple, very specific functionality plugin that you can (hopefully) use to replace your theme’s functions.php
file. After all, the poor guy deserves a break, doesn’t he?
What (and why) is a functionality plugin?
First of all, the thing to realize with plugins is that, for all intents and purposes, they behave no differently than your theme’s functions.php
file. I won’t say there are no differences, of course, but a plugin file should not be treated as something foreign and strange. If you’ve edited your functions.php
file — even if you’ve just edited it by dropping in PHP
that you found searching online — then you are familiar enough to manage your own plugins.
You can think of it as a portable functions.php file that you can take with you when you change themes.
Having said that, when I refer to a functionality plugin, I’m talking about a certain type of plugin intended to belong to a specific website. You can think of it as a portable functions.php
file that you can take with you when you change themes.
Functionality plugins should contain all of the code that is important for the necessary structure and functionality of your website. By creating a plugin specifically for your website you have the ability of taking the most important parts of your site with you from theme to theme.
Let’s look at a couple of examples. One common thing often added to functions.php
files is a register_taxonomy
function. This sort of function will create a custom taxonomy (like categories or tags, but defined by you) to allow you to organize your content further. This is what it would look like:
function people_init() {
register_taxonomy(
'people',
'post',
array(
'label' => __('People'),
'sort' => true,
'args' => array('orderby' => 'term_order'),
'rewrite' => array('slug' => 'profiles'),
)
);
}add_action( 'init', 'people_init' );
If we include this in our WordPress theme’s functions.php
file we may run into a surprise when (not if) we change our theme in the future and don’t see our custom taxonomy on the Dashboard anymore. In order to maintain our taxonomy we would have to scour the functions.php
file before the theme change to make sure we didn’t miss anything important.
Or, and this is what I recommend, we could create a plugin named after our site and put the function in there. Then we can change themes freely, knowing that our most important, core functionality is preserved safely in a plugin. I call these special types of plugins functionality plugins.
What belongs in a functionality plugin?
To decide what belongs in a functions.php
file and what belongs in a functionality plugin, think long term. Rather than thinking about how your website will look and behave this week, think about how it will look and behave five years from now. With few exceptions, I bet all of our sites will have new and upgraded themes in five years’ time.
For every item we might instinctively want to add to our functions.php
file, we should stop and consider whether our site will depend on that functionality in five years or not. Consider the following list of functions, for example:
register_post_type()
andregister_taxonomy()
, for creating a custom content type and related taxonomy.add_shortcode()
, to create a shortcode for publishing certain kinds of content more easily.add_theme_support( 'post-thumbnails' )
andadd_image_size()
, to enable post thumbnails and set a certain size.
Let’s take the first example, register_post_type()
and register_taxonomy()
. In five years will you still want these types of content available to you on the Dashboard and on your site? Of course you will, that’s your site’s content! Your content and how you can access it shouldn’t be determined by the particular theme you’ve chosen. These, and others like it, should be included in a functionality plugin, not your functions.php
file.
In the second example, add_shortcode()
, we’re adding a way to drop in potentially complex code into our content. There’s a rule of thumb I have for determining what belongs in a plugin: if it modifies or interacts with content it belongs in a plugin. In this case we’re quite literally creating content, and if this function is missing our content will display in the raw shortcode format. In this case as well, it belongs in a functionality plugin.
For more on shortcodes and their use in WordPress themes, see Justin Tadlock’s recent post.
Finally, the third item add_theme_support( 'post-thumbnails' )
and add_image_size()
add a post thumbnail and particular size to your site. This is one case that I would say is debatable, since post thumbnails, and in particular sizes, may depend largely on the particular display of your site. In my own case I define post thumbnails in a plugin, but I could see the argument for including them in theme files instead. So, in this case: it depends.
What belongs in functions.php?
Your theme’s functions.php
file is for any functions or declarations that are necessary for your theme’s appearance. As long as what you’ve added there don’t effect your content in any way, you should be just fine.
There are a number of examples of functions best kept in your theme’s functions.php file:
registern_nav_menus()
register_sidebar()
wp_enqueue_script()
andwp_enqueue_style()
The register_nav_menus()
is appropriately placed in a theme’s functions.php
file, since the placement of the navigation menus themselves depend on the given theme you are using. Keeping this function in a plugin would give you menu placement options on the Dashboard that wouldn’t actually display anywhere in your theme.
register_sidebar()
should also stay in your functions.php
file, since once again registering sidebars in a plugin could mean you have active plugins on the Dashboard that don’t actually show up anywhere on your site. That would be pretty silly.
wp_enqueue_script()
and wp_enqueue_style()
are both similar, and I would say depend on the situation. If you are creating a child theme they belong in functions.php. If you are adding them for another purpose (modifying the WordPress admin bar, for instance) then a plugin would likely be more appropriate. As in our earlier examples, this third example requires a bit of context to be sure whether it belongs in functions.php
or a plugin.
How to create your first functionality plugin
Creating a functionality plugin is easy, particularly if you understand it as an extension of your functions.php
file. You’ll want to start with a plugin file with the appropriate comment header, like this:
/*
Plugin Name: Your Site's Functionality Plugin
Description: All of the important functionality of your site belongs in this.
Version: 0.1
License: GPL
Author: Your Name
Author URI: yoururl
*/
Save that as a PHP file within its own folder in your site’s plugin directory. I would also recommend maintaining a basic readme.txt
file for your own sake. Trust me, you-in-five-years will thank you for starting it today. Document the changes you make to your functionality plugin, as well as what everything does.
If you’d like, download our blank functionality plugin to help you get started.
Now head to your WordPress plugins page and activate your plugin. Congrats, you just activated your own plugin: your own comment-only, functionally empty plugin, but your own plugin nonetheless! It won’t do anything, but the nice part now is that you have a file on your site, a plugin file, that will behave much like you’re used to functions.php
behaving. And instead of abusing your functions.php file with code you will need later on, you can use your new functionality plugin.
What goes in our plugin?
Now comes the fun part, where we move over site-vital functions to our plugin. To briefly recap, we’re interested in moving functions that are vital to our site’s operation stuff we will want around when (not if) we change our theme in the future.
Everyone’s functions.php
file will be slightly different, as well as what will count as “vital site functionality”. But here’s a table with a handful of functions I’ve seen floating around, and where I think they belong:
Purpose of code | Functionality plugin | functions.php |
---|---|---|
Creating shortcodes | Always | Never |
Adding scripts and styles | Depends | Depends |
Creating sidebars | Never | Always |
Creating menus | Never | Always |
Add post types/taxonomies | Always | Never |
Add post thumbnails | Depends | Depends |
Add Google Analytics to footer | Always | Never |
Customize WordPress Dashboard | Always | Never |
Change default Gravatar | Always | Never |
Add custom profile fields | Always | Never |
There are plenty of other examples I could use here (actually, limitless examples) but these should be enough to deliver my point.
Your future creating plugins
Sometimes even the functionality plugin may not provide as much universality as we want. Sometimes it may be better to create our own plugins to create unique functionality in each one. If you’re anything like me, functionality plugins like this will be your first foray into WordPress plugin development. I’m much closer to the beginner side of the spectrum than I am the expert side, but what I’ve learned the past 6 months or so has been driven in large part by working in plugins rather than functions.php
.
Next time you are copying and pasting a function from a website, or perhaps you managed to piece together code doing just what you need for your purposes, consider abstracting it, writing yourself some solid documentation on what it does, and turning it into a plugin of its own. Likely this won’t require anything more than moving that function into a plugin file with the appropriate commented header (seen above). By doing this you will have tiny portable pieces of functionality you can enable on sites whenever you need them.
I, for instance, created a few super simple plugins just this month:
- Admin Bar Hover Intent: This one I’m proud of, because I actually released it into the wild on the plugin directory (something I’ve only done once before). It simply implements jQuery hoverIntent on the dropdowns, requiring a deliberate pause over them before they drop down.
- Admin Bar Cleanup: Sometimes I create plugins that tweak things to operate just the way I like them. In this case, Admin Bar Cleanup just hides the WordPress search bar from the admin bar for me. I don’t use it on every website of mine, but on a few it’s definitely active.
- Login Redirect Home: This plugin simply, when active, redirects all login activity back to the home page. I use this one sparingly: only on team P2 blogs, team wikis, and task tracking sites.
Not long ago I would have just added it to my site’s functionality plugin (or worse the functions.php
file) and moved on, only to likely re-do the same work later in another project.
But each of these plugins requires less than twenty lines of code. All I did was stop myself from adding functionality to only my own site, and stepped back to consider the usefulness of the functions outside of the current project. If there was use for it, I whipped up a quick plugin file and dropped the code in.
read more and see the original article here… wpcanday article