WordPress plugin structure, don't load unnecessary code
Published on Permalink
When developing WordPress plugins it is important to decide whether code needs to be loaded or not as early in the request lifecycle as possible. Why bother loading unnecessary code and hooking into actions and filters that will never run for the request being made? Having said that, it is also important to keep your code structured and not go overboard with this.
Conditional loading of code
What worked well for me so far is to split my code up into several files and load each of these files based on simple conditionals. While this might not do that much in terms of performance this will also help you in the long run by forcing a certain structure in your code.Let's start with a no-brainer: admin section specific code versus public or frontend section specific code.
Do not load admin code in the public area
It makes no sense to load code that hooks into admin specific hooks for requests to the front page of a website. So let's split up our code into two files:public.php
, containing all public or frontend code, like shortcode callbacks andwp_enqueue_scripts
hooks.admin.php
, containing all admin section code, like settings pages.
We can then load each of these files based on the
outcome of the is_admin()
function, which
will return true if the URL begin requested is in the
admin section.
define( 'MYPLUGIN_DIR', plugin_dir_path( __FILE__ ) );
// load code that ALWAYS needs to be loaded
// (registering post types, widgets, etc..)
require MYPLUGIN_DIR . 'includes/init.php';
if( ! is_admin() ) {
// load code that only needs to be loaded for the public section
// (stylesheets, shortcode callbacks, template functions, etc..)
require MYPLUGIN_DIR . 'includes/public.php';
} else {
// load code that is only needed in the admin section
// (setting pages, admin menu, etc..)
require MYPLUGIN_DIR . 'includes/admin.php';
}
AJAX requests
We can add one more conditional to the snippet above to differentiate between AJAX requests and regular (non-AJAX) requests. We can do this by checking for a constant namedDOING_AJAX
.
For AJAX requests, is_admin()
will always
return true
, which makes it unnecessary to
check for AJAX in requests for the public section. My
complete initializing code usually looks something like
this.
define( 'MYPLUGIN_DIR';, plugin_dir_path( __FILE__ ) );
// all requests
require MYPLUGIN_DIR . 'includes/init.php';
if ( !is_admin() ) {
// public sectionrequests
require MYPLUGIN_DIR . 'includes/public.php';
} else if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
// AJAX requests
require MYPLUGIN_DIR . 'includes/ajax.php';
} else {
// admin section requests
require MYPLUGIN_DIR . 'includes/admin.php';
}
Combining these 3 simple conditionals will keep the footprint of your plugin for each request as low as possible and forces you to follow a certain code structure, which you will benefit from in the long run.
Additions or suggestions? Please leave them in the comments. :-)