wordpress, web, design

There is a special kind of plugins called must-use (MU) plugins. They were first introduced with WPMU (WordPress Multi User), the predecessor of WordPress Multisite. But what’s so special about them? Let’s find out.

Must-use plugins reside in wp-content/mu-plugins, although you can change that location by defining WPMU_PLUGIN_DIR (and WPMU_PLUGIN_URL for the respective url) in wp-config.php. WordPress scans this folder for PHP source files and executes them in alphabetical order. This is done before any other plugin or theme code is executed.

No admin interface

There is no admin interface for must-use plugins, except a read-only section of the plugins screen. What that means is that, there is no user role that can manipulate them. They cannot be installed from any repository, nor can they be activated/deactivated. If we want to deactivate a MU plugin, we have to have access to the filesystem. Consequently, activation and deactivation hooks will not run, because they don’t apply.

No header needed

Considering the loading mechanism we described above, it is obvious that these plugins do not need a header in order to be recognized. There’s no way for the administrator to know who the plugin author is or what it does. But maybe more importantly, WordPress has no way of knowing what is the minimum PHP/WordPress version for the plugin to run.

A subfolder solution

As we mentioned above, WordPress only looks inside WPMU_PLUGIN_DIR for code to run. Although this simplifies things, there are cases when we want a more organized way to load our plugins. A good way to do that is by implementing a proxy module loader, like so:

<?php

foreach(glob(WPMU_PLUGIN_DIR."/*/module.php") as $module) require $module;
PHP

Let’s save this as wp-content/mu-plugins/modules.php. Now from WordPress’s perspective, there is only one plugin installed. This plugin will search all of the subfolders for files named module.php and run them. If we want to disable a module, all we have to do is rename its main source file to i.e. _module.php. Moreover, this doesn’t prevent us from installing other plugins in the base folder (thus the modules differentiation).