Benefits to using functionality plugins with WordPress

I discovered the technique of using functionality plugins several months ago and was reluctant at first. When building a site with WordPress using my own theme, I usually just dump any custom functionality I want into the functions.php file. But the idea with functionality plugins is that you put non-theme-specific code into a plugin instead. This prevents your code from being overridden when changing themes.

Addressing objections

At first, this might seem like a bunch of hassle for little payoff. You might be thinking:

“I don’t know much about making plugins.”

But a functionality plugin is not a big plugin like you would normally think of. It is simply one file (you can optionally put it into a folder) that works just like your functions.php file, only you must put a special header at the top. For instance, this website uses a plugin I made called “Matt Watson Functionality” that is simply one file I placed in my wp-content/plugins folder and named mattwatson-functionality.php. It starts like this:

<?php
/**
   * Plugin Name:       Matt Watson Functionality
   * Plugin URI:        https://www.mattwatson.org/
   * Description:       Matt Watson functionality plugin
   * Version:           1.0.0
   * Author:            Matt Watson
   * Author URI:        https://www.mattwatson.org/
   * License:           GPL-2.0+
   * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
   * Text Domain:       mattwatson-functionality
 */

From there on, I put whatever PHP code I want, just like I would in the regular functions file.

“I’m using my own theme that I’m never going to change, so what’s the point?”

This is certainly a common use case scenario — where a developer is coding their own or a client’s website and is only using WordPress’s theming feature because that’s what you must do in order to use the CMS. This kind of “theme” is not meant to be used by anyone else, is not going to be distributed in anyway, and is not meant to be switched out. In essence, the theme is the website.

While it is true that such a website is not designed in the first place to allow the user to switch themes, there are still other scenarios where having your functionality code separate from the theme is useful. For instance, in 3-5 years when the website frontend design plans get overhauled, you might want to develop the frontend code from scratch again using a new custom theme. Essentially, you are rebuilding the website… but if you’ve used a custom functionality plugin, you have saved yourself some time. You don’t need to migrate non-frontend-related code to the new theme, because your plugins will just carry over.

Using a functionality plugin with other themes

Most chatter I’ve read on using functionality plugins are directed toward developers who are coding their own theme. But what if you’re a lazy developer like me who is just using a standard theme from the WordPress.org repo? It is rather common, in fact, for developers to have ugly personal websites or use other people’s themes, because they just don’t have time to work on it. When you use a third-party theme, though, you pretty much lose the ability to write anything to the functions.php file, because your changes will be deleted on a theme update. This is annoying if all you need to do is add a few lines of code to, say, the head of your pages, or inject a few style rules for whatever reason. This often results in just downloading a plugin from WordPress.org. A lot of these plugins do super basic things and are largely meant for non-developers.

But if you’re a developer and used to touching the code, you can just add a functionality plugin to do basic things instead of using other people’s plugins, which are usually large and designed to do a lot of things you might not even need.

For instance, I decided to use the Twenty Fifteen theme for this site, and I wanted to track my site’s traffic using my self-hosted Matomo installation. While I could have downloaded a plugin from WordPress.org that would inject Matomo’s JavaScript snippet into my page head, I can just do it myself in my own functionality plugin. And hey, while I’m at it, I’ll go ahead and add anything else I need to the wp_head hook, such as my favicon links.

<?php

// [... Plugin header]

add_action('wp_head', 'mw_wp_head');
function mw_wp_head() {
	?>
	<!-- MW Custom Plugin -->
	<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
	<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
	<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
	<link rel="manifest" href="/site.webmanifest">
	<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
	<meta name="msapplication-TileColor" content="#da532c">
	<meta name="theme-color" content="#ffffff">

	<?php if( !is_user_logged_in() ): ?>
		<!-- Matomo -->
		<script type="text/javascript">
		  var _paq = _paq || [];
		  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
		  _paq.push(['trackPageView']);
		  _paq.push(['enableLinkTracking']);
		  (function() {
		    var u="//piwik.mattwatson.org/";
		    _paq.push(['setTrackerUrl', u+'piwik.php']);
		    _paq.push(['setSiteId', '1']);
		    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
		    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
		  })();
		</script>
		<!-- End Matomo Code -->
	<?php endif; ?>
	<!-- /MW Custom Plugin -->
	<?php
}

When you need to push code but can’t FTP

Usually, to update your custom theme’s functions.php file, you would just FTP it (or use a deployment service that does the equivalent). But there might be times where you need to update someone’s website but don’t have access to FTP. For example, the website might have an IP address whitelist, and you’re working remotely today. Or maybe your FTP program is not working for some reason. Not an ideal situation to be in, but it happens.

The more functionality code you have extracted out to plugins, the easier it will be for you to make updates in a pinch. You can just change the plugin and re-upload it in the WordPress admin area. Of course, you could do the same for the theme, but that involves re-uploading all theme files from a zip. Easier just to upload your-plugin-name.php on the plugins screen.

Final thoughts

Going from dumping all your functions in the theme to dumping them in a functionality plugin might not magically make your code that much more organized. You can always be more organized by doing things like applying object-oriented programming with classes to using namespaces, etc., but this is at least a good start with concrete payoffs.