Apply filters with multiple filters

The way apply_filters() works is that the developer provides a name for the filter, and the value that can be filtered. This lets other code modify that value by adding a filter.

In addition the value, however, apply_filters() can also pass additional values to hooked functions so that they can be used inside the filter callback. These are passed as additional arguments to apply_filters():

$value = apply_filters( 'my_filter_name', 'abc', 'arg1', 'arg2' );

In that example, developers who are filtering 'abc' can also access 'arg1' and 'arg2' in their code. This can be useful for passing on additional information about the context, or raw data that was used to create the original value, so that the other developer can re-use it.

An example in WordPress is the the_title filter. This filter also passes along the post ID so that the filter callback can know the ID of the post whose title is being filtered:

apply_filters( 'the_title', $title, $id );

In your example, the same filter is applied to two separate values, but each instance passes along a unique 2nd value that can be used to differentiate between the two.

So if we just look at the filter:

apply_filters( 'pta_sus_public_output', __('You have signed up for the following', 'pta_volunteer_sus'), 'user_signups_list_headers_h3' )

There are 3 parts:

  • pta_sus_public_output The name of the filter.
  • __('You have signed up for the following', 'pta_volunteer_sus'), the value that you can filter.
  • user_signups_list_headers_h3 An additional value that can be used in the filter callback.

In the second filter the last argument is different:

apply_filters( 'pta_sus_public_output', __('Click on Clear to remove yourself from a signup.', 'pta_volunteer_sus'), 'user_signups_list_headers_h4' )

In that case it’s user_signups_list_headers_h4.

So by checking this second value, you can apply the filter to only one of the filter instances.

To do this you need to specify that you accept 2 arguments in your callback function:

add_filter( 'pta_sus_public_output', 'function_to_change_user_signups_list_headers_h4', 10, 2 );

That’s the last number there. This is the $accepted_args property. The number before that is the priority, and 10 is the default value.

Then inside your function_to_change_user_signups_list_headers_h4() function, accept the additional argument with whatever variable name you want. I’ll use $context:

function function_to_change_user_signups_list_headers_h4( $text, $context ) {

The value of $context will now be either user_signups_list_headers_h3 or user_signups_list_headers_h4 (or possibly other values, if the filter is used elsewhere in the plugin), and we can use this to only apply your filter to only the one you want:

function function_to_change_user_signups_list_headers_h4( $text, $context ) {
    if ( 'user_signups_list_headers_h4' === $context ) {
        $text="Sorry you can not clear";
    }

    return $text;
}