Skip to main content
Robert Michalski

Where to add custom WordPress code and when to load it

Where to add custom code in WordPress? #

There are several places to add custom php code to WordPress.

  1. Putting the code in functions.php of the active theme
  2. Creating a must-use plugin (mu-plugin)
  3. Creating a plugin

Most WordPress guides, tutorials and posts on forums usually go with option 1, adding custom code in functions.php in the active theme because it's the easiest.

Adding code in functions.php of a theme #

This way of adding custom code is very simple, probably why most tutorials and guides use it. It only requires putting the code in the functions.php file of a theme. If there are errors caused by the custom code, the theme can be disabled from the WordPress admin.

The drawback is that the custom code only runs when the that particular theme is active. Remember to move the code when changing themes.

Creating a must-use plugin #

Adding custom code in a mu-plugin is almost as simple as adding it to the themes functions.php file, however it requires some diligence. Care must be taken to do certain things in the right order and at the right time, or the website might crash because of PHP errors.

The benefit of adding custom code in a mu-plugin is that code will always be run, regardless of which theme is used. Another benefit, or drawback, depending on what is required, is that mu-plugins can't be disabled from WordPress admin. To disable a mu-plugin, either (re)move the file or comment out the code in it, which requires file access on the server that hosts the website.

First make sure that there is a mu-plugins folder in wp-content, create it if it doesn't exist. It's enough to create a file with a comment at the top so WordPress recognises and loads it. Then put in any custom code.

wp-content/mu-plugins/01_my_custom_code.php

<?php
/**
 * Plugin Name: My custom mu-plugin
 * Description: My custom WordPress code 
 * Author: Your Name
 */

// add custom code here

Creating a plugin #

Adding custom code as a plugin is only slightly more work than creating a mu-plugin, the benefit is that plugins can be disabled from the WordPress admin.

Create a folder for the plugin inside the WordPress plugins folder, then create a file with then same name as the folder with .php as the file extension.

wp-content/plugins/my-custom-plugin/my-custom-plugin.php

<?php
/**
 * Plugin Name: My custom plugin
 * Description: My custom WordPress code as a plugin 
 * Author: Your Name
 */

// add custom code here

When to run custom code #

Themes #

Code in themes runs after plugins are loaded, making it safe to use code from other plugins, as long as the used plugins are active.

function YOUR_OWN_THEME_PREFIX_is_plugin_active($plugin_path) {
    return in_array($plugin_path, wp_get_active_and_valid_plugins(), true);
}

if (YOUR_OWN_THEME_PREFIX_is_plugin_active('woocommerce/woocommerce.php')) {
    add_action('woocommerce_action', function(...),  { ... }, 10, 2);
    add_filter('woocommerce_filter', function($value) {
        ...
        return $value;
    }, 10, 1);
}

Must-use plugins #

Must-use plugins are loaded before normal plugins and themes, and they're run in the alphabetical order of their file name. Calling code from other WordPress plugins must happen after normal plugins are loaded. Put code inside functions that run on WordPress hooks and filters and check that any plugins used are also available and active.

If there are several mu-plugins that also call code from other mu-plugins, care must be taken to make sure they load in the correct order. For instance having a mu-plugin with helpers that other mu-plugins are using, to reduce code duplication.

Since mu-plugins load-in the order of their file-name the file-systems case-sensitivity must be taken into account. Developing locally, for instance on macOS, which has a case-insensitive file system by default, plugins might load in another order than on the server. Servers are probably running Linux or a flavor of BSD that almost always use a case-sensitive file-system.

Example of naming mu-plugins

NOTE: It doesn't really become a problem until there are multiple mu-plugins depending on other mu-plugins.

Plugins #

Plugins are loaded in alphabetical order of their folder name, therefore the loading order for plugins is not guaranteed. This makes it possible to call functions and classes before they have been defined, resulting in critical PHP errors and "white screen of death" or displaying stack-traces and other error information to the user. Plugins that utilise functions or classes from other WordPress plugins must do so after all plugins are loaded, when all classes and functions have been defined and are available. Put code inside functions that run when WordPress hooks and filters are fired and check that any other plugins used are available and active.

Example code for mu-plugins and plugins #

function YOUR_OWN_PLUGIN_PREFIX_is_plugin_active($plugin_path) {
    return in_array($plugin_path, wp_get_active_and_valid_plugins(), true);
}

add_action('plugins_loaded', function() {
    // this code will run after all active plugins are loaded
    if (YOUR_OWN_PLUGIN_PREFIX_is_plugin_active('woocommerce/woocommerce.php')) {
        add_action('woocommerce_action', function(...),  { ... }, 10, 2);
        add_filter('woocommerce_filter', function($value) {
            ...
            return $value;
        }, 10, 1);
    }
})