WordPress as framework

To run a plugin only when it is needed the plugin author has to identify the pages where the code actually does something.

WordPress offers a surprisingly simple way to do that: the global variable $pagenow.
It is set before a plugin is called in wp-includes/vars.php.

In a spam block plugin I have written recently I needed my plugin to run on four pages only:

  • wp-comments-post.php to filter the posted comments
  • wp-admin/plugins.php to add a link in the plugin row to the settings
  • wp-admin/options-discussion.php to show two option fields
  • wp-admin/options.php to save the option fields

So I added a helper method to my plugin controller …

/**
 * Check if we need an instance of our class.
 *
 * @return boolean
 */
public static function start_me()
{
    global $pagenow;

    if ( empty ( $pagenow ) )
        return FALSE;

    self::$page_base = basename( $pagenow, '.php' );
    $active_pages    = array (
        'options',
        'options-discussion',
        'plugins',
        'wp-comments-post'
    );

    if ( ! in_array( self::$page_base, $active_pages ) )
        return FALSE;

    return TRUE;
}

… and check that method before I do anything else in my plugin:

if ( T5_Spam_Block::start_me() )
    add_action(
        'wp_loaded',
        array ( T5_Spam_Block::get_instance(), 'plugin_setup' )
    );

And if my plugin is called it does only what is really needed, nothing else:

/**
 * Register actions.
 *
 * @wp-hook wp_loaded
 * @return  boolean
 */
public function plugin_setup()
{
    // Register callbacks only when needed.
    if ( 'wp-comments-post' === self::$page_base )
        return add_action(
            'pre_comment_on_post',
            array ( $this, 'check_comment' )
        );

    if ( 'options' === self::$page_base )
        return add_action(
            'admin_init',
            array ( $this, 'register_setting' )
        );

    if ( 'options-discussion' === self::$page_base )
        return add_action(
            'admin_init',
            array ( $this, 'add_settings_field' )
        );

    // Now 'plugins' === self::$page_base
    // Used by add_settings_link() later.
    $this->plugin_base  = plugin_basename( __FILE__ );

    return add_filter(
        'plugin_row_meta',
        array ( $this, 'add_settings_link' ),
        10,
        2
    );
}

As a framework WordPress offers the tools to specialize each part of the plugin code. But it is up to the authors to use these tools, and many authors fail here.