Select Page

When I am developing a theme or plugin for WordPress, I often have to deal with the so called hooks, more precisely “actions” and “filters”. There are a ton of those hooks in the WordPress core, giving the developer the ability to add custom functionality or output.

The difficult part with WordPress hooks, at least for me, is to find out the right action or filter for the job I am working on. I can use the official WordPress documentation pages for filters and actions in the hope of finding a well documented hook which might be the right one for me. But if it is not one of the commonly used hooks (like “init” or “admin_init”), I often do not know if the hook will even apply on the page or function I am about to customize.

It even gets more difficult if I try to customize a third party plugin. If it uses hooks at all, you are very lucky if they are documented in a way you can work with.

So the best option for me is to not rely on the more or less good hook documentation, but to find out for myself which hooks apply on a page when the user accesses it. To achieve this I use a combination of Apache environment variables and two small core hacks in my WordPress development installation.

Step 1: .htaccess

In the .htaccess file I add these environment variables:

(Make sure that no invisible control characters are created from copying and pasting!)

SetEnv    LOG_ACTIONS       0
SetEnv    LOG_ACTIONS_NEEDLE
SetEnv    LOG_FILTERS       0
SetEnv    LOG_FILTERS_NEEDLE
SetEnv    LOG_HOOKS_PATH    [local_path_to_wp]/wp-content/hooks.log

As you can see, I create a new writeable file, “hooks.log“, in wp-content, which will be used as a hooks log file.

If you only want to display certain filters or actions, use the “NEEDLE” values to narrow them down (write a string after the respective NEEDLE variable).

Step 2: Core hacks

Then I add two hacks in wp-includes/plugin.php. (Note: This is just for development. Don’t do this on your production site.)

In the function apply_filters I add (the part after the globals):

function apply_filters( $tag, $value ) {
    global $wp_filter, $merged_filters, $wp_current_filter;
    
    if (getenv('LOG_FILTERS') == '1' && is_writable(getenv('LOG_HOOKS_PATH'))) {
        $needle = getenv('LOG_FILTERS_NEEDLE');
        if (empty($needle) || (!empty($needle) && strpos($tag, $needle) !== false)) {
            $data = __FUNCTION__ . ': ' . $tag . "\n";
		file_put_contents(getenv('LOG_HOOKS_PATH'), $data, FILE_APPEND);
	    }
    }

    ...

and in do_action I add (the part after the globals):

function do_action($tag, $arg = '') {
    global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;

    if (getenv('LOG_ACTIONS') == '1' && is_writable(getenv('LOG_HOOKS_PATH'))) {
        $needle = getenv('LOG_ACTIONS_NEEDLE');
        if (empty($needle) || (!empty($needle) && strpos($tag, $needle) !== false)) {
            $data = __FUNCTION__ . ': ' . $tag . "\n";
            file_put_contents(getenv('LOG_HOOKS_PATH'), $data, FILE_APPEND);
        }
    }
 
    ...

Usage

Now, whenever I need information about the applied hooks on a page I am working on, I can switch LOG_ACTIONS and / or LOG_FILTERS to 1 in the .htaccess file of my test system, reload the page and check the contents of wp-content/hooks.log which may look like in the example screenshot generated on the login page:

WordPress hooks log