Discussion:
Restrict plugin load to certain pages?
David Anderson
2013-07-01 09:02:35 UTC
Permalink
Hi,

I am running a plugin which, like many, loads plenty of code on
irrelevant pages. This one, when profiled in P3 Performance Profiler,
accounts for 0.27 seconds of page load time on pages which it has
nothing to do with (its a forum plugin).

I'm confident that there will be no bad side-effects from simply not
loading this plugin on irrelevant pages (e.g. those without /forum/ in
the URL). Rather than re-writing the plugin, and then doing it again on
every other plugin I find in future with this problem, I'd like to write
some code to simply prevent plugin load, depending on the URL.

Looking at the WP core code, my only option to achieve this seems to be
to be (via an mu-plugin, since a plugin would present a Catch-22) to
hook get_option, detect the option 'active_plugins', and remove the
offending plugin depending on the contents of _SERVER['REQUEST_URI'] and
is_admin() (I don't want to disable anything admin-side).

Questions...
- Anyone see any problem with this idea?
- Anyone done it already and got some code?
- If plugins loaded in a controllable, deterministic order (e.g.
deterministic), and with an action added in
wp_get_active_and_valid_plugins, it would be possible to code this as a
plugin. Do any of the insiders on this list have an opinion upon whether
if I submitted a patch for WordPress core to do this it'd have any
chance of getting in?

Many thanks,
David
--
WordShell - WordPress fast from the CLI - www.wordshell.net
John Blackbourn
2013-07-01 10:30:48 UTC
Permalink
Looking at the WP core code, my only option to achieve this seems to be to
be (via an mu-plugin, since a plugin would present a Catch-22) to hook
get_option, detect the option 'active_plugins', and remove the offending
plugin depending on the contents of _SERVER['REQUEST_URI'] and is_admin() (I
don't want to disable anything admin-side).
You're approaching this from the wrong angle. Rather than not loading
the plugin at all when it's not necessary, you should only load the
required parts of your plugin when necessary. If your mu-plugin is
able to detect the correct condition to determine when your forum
plugin should or should not be loaded, then it can instead be done
within the forum plugin itself.

If your plugin is split up into separate files effectively then you
should only load minimal code on every page load, detect if the rest
of the plugin needs to be loaded (eg. by inspecting the URL as you
state) and then loading its other files when necessary. There's no
need for a separate plugin, and certainly no need for a nasty hack
like filtering the value of the active plugins option.

This can be as simple as (pseudo-code):

if ( url_contains( 'forum' ) )
include 'forum-code.php';

Lots of plugins use similar code for only loading files in the admin
are. It's pretty simple stuff.

if ( is_admin() )
include 'admin-code.php';

Additionally, if your plugin makes good use of object oriented
programming and is split into multiple classes then you can use
autoloading.

John
John Blackbourn
2013-07-01 10:40:49 UTC
Permalink
Post by John Blackbourn
Looking at the WP core code, my only option to achieve this seems to be to
be (via an mu-plugin, since a plugin would present a Catch-22) to hook
get_option, detect the option 'active_plugins', and remove the offending
plugin depending on the contents of _SERVER['REQUEST_URI'] and is_admin() (I
don't want to disable anything admin-side).
You're approaching this from the wrong angle. Rather than not loading
the plugin at all when it's not necessary, you should only load the
required parts of your plugin when necessary. If your mu-plugin is
able to detect the correct condition to determine when your forum
plugin should or should not be loaded, then it can instead be done
within the forum plugin itself.
If your plugin is split up into separate files effectively then you
should only load minimal code on every page load, detect if the rest
of the plugin needs to be loaded (eg. by inspecting the URL as you
state) and then loading its other files when necessary. There's no
need for a separate plugin, and certainly no need for a nasty hack
like filtering the value of the active plugins option.
if ( url_contains( 'forum' ) )
include 'forum-code.php';
Lots of plugins use similar code for only loading files in the admin
are. It's pretty simple stuff.
if ( is_admin() )
include 'admin-code.php';
Additionally, if your plugin makes good use of object oriented
programming and is split into multiple classes then you can use
autoloading.
John
I've just realised you're probably talking about a third party plugin,
in which case my suggestion is mostly moot. Filtering the value of the
active plugins option is a pretty yucky hack, but I don't have any
other suggestions.

Bear in mind that disabling the plugin completely on pages other than
at "/forum" means you'll potentially lose out on related
functionality, such as sidebar widgets that display the latest forum
posts, integration with other parts of your site, etc etc. You'll also
need to ensure the plugin loads when WP-Cron fires, in case it's using
cron events.
Jackson Whelan
2013-07-01 11:21:25 UTC
Permalink
Post by David Anderson
Looking at the WP core code, my only option to achieve this seems to
be to be (via an mu-plugin, since a plugin would present a Catch-22)
to hook get_option, detect the option 'active_plugins', and remove the
offending plugin depending on the contents of _SERVER['REQUEST_URI']
and is_admin() (I don't want to disable anything admin-side).
- Anyone done it already and got some code?
Hi David,

Here's an mu-plugin which does just what you're after:

http://wordpress.org/plugins/disable-plugins/

- Jackson
David Anderson
2013-07-01 18:50:17 UTC
Permalink
Hi,
Post by Jackson Whelan
http://wordpress.org/plugins/disable-plugins/
Jackson - thanks; that looks exactly like what I meant.

John - yes, you're right in your second post; it's someone else's badly
coded plugin that I want to work around rather than re-writing someone
else's code. But the tip to remember cron is useful. I'm confident that
the plugin does nothing else on other pages (no widgets, etc.).

Does anyone with inside knowledge of committing to core have any comment
on whether there'd be any interest in accepting a patch that:
a) loading plugins in a deterministic, easy-to-slot-in-to order
(alphabetic is what springs to mind) rather than relying upon PHP's
array ordering, as at present?
b) ran a filter before deciding to load each plugin, thus giving
earlier-loading plugins an option to disable later loading ones? (And
thus making it possible for a plugin with slug aaaa-disable-plugins to
prevent any of the others)?
With such a patch, the plugin that Jackson links to wouldn't need
special installation plugins to boot-strap itself via mu-plugins.

Many thanks,
David
--
WordShell - WordPress fast from the CLI - www.wordshell.net
Loading...