When to use actions and when to use filters

I’m trying to understand where to use filters and where to use actions.

Suppose I have a query in a plugin, which later add on modules might modify to change the results of the query, thus modifying the arguments.

Read More

Would this be an ideal implementation of this concept, or should I be using actions here?

// Function to display list of pages

function get_page_list() {
    $pages_args = array(
        'post_type' => 'page',
        'posts_per_page' => '1'
    );  
    $pages_query = new WP_Query( apply_filters( 'myfilter', $pages_args ) );


    if( $pages_query->have_posts() ) {
        while ( $pages_query->have_posts() ) : $pages_query->the_post();  
            echo get_the_title();
        endwhile;
        // Reset Post Data
        wp_reset_postdata();
    } 


    else echo 'no results found';                 

}
add_action( 'wp_footer', 'get_page_list', 1); 


function change_page_to_post( $pages_args ) {
    $pages_args = array(
        'post_type' => 'post',
        'posts_per_page' => '1'
    );  
    return $pages_args;
}
add_filter('myfilter', 'change_page_to_post');

Related posts

Leave a Reply

3 comments

  1. +1 to both of the other answers, for explaining the primary differences between actions and filters.

    However, to answer your specific question, about which to use for modifying a query:

    1. Injecting your custom query into the template does, as you guessed, require hooking into an existing action. (Whether or not wp_footer is the correct/ideal action is another matter, and would depend on exactly how you intend to use said query.
    2. Allowing your custom query is probably best accomplished using a custom filter, that other Plugins can hook into.

    For example, starting with this code:

    function get_page_list() {
        $pages_args = array(
            'post_type' => 'page',
            'posts_per_page' => '1'
        );  
        $pages_query = new WP_Query( apply_filters( 'myfilter', $pages_args ) );
    
    
        if( $pages_query->have_posts() ) {
            while ( $pages_query->have_posts() ) : $pages_query->the_post();  
                echo get_the_title();
            endwhile;
            // Reset Post Data
            wp_reset_postdata();
        } 
    
    
        else echo 'no results found';                 
    
    }
    add_action( 'wp_footer', 'get_page_list', 1); 
    

    If you want this code to be extensible, you need to provide a way for others to extend it. I would recommend making your custom query args extensible, via custom filter. e.g. this:

    $pages_args = array(
        'post_type' => 'page',
        'posts_per_page' => '1'
    );  
    

    …could easily become this:

    $pages_args = apply_filters( 
        'custom_filter_name', 
        array(
            'post_type' => 'page',
            'posts_per_page' => '1'
        ) 
    );  
    

    Which would then allow other Plugins to modify your query args. For example, if a Plugin wanted to return two posts, instead of one:

    function wpse73840_modify_custom_filter_name( $args ) {
        // Modify posts_per_page
        $args['posts_per_page'] = '2';
        // Return modified args
        return $args;
    }
    add_filter( 'custom_filter_name', 'wpse73840_modify_custom_filter_name' );
    

    I think this gets to what you’re asking. If not, let me know in the comments.

  2. The basic difference is that filters are meant to change some value & actions are meant to do some work. They work almost the same way in the code but the difference is that filters have to return a value whereas actions don’t.

    Let’s say your plugin created a new page in the database. After the task is completed, you want to let other people add some custom fields to the new page. For this task, you’ll want to send an action. Other plugins will hook into this & add the fields only when the page is created

    Now let’s say you’re going to display some message to the user, but you want that message to be customizable by other plugins. Then you’ll apply a filter. Other plugins hooking into the filter will change this message & return it back to you. Now you’ll display the new message to the user. Not the one you originally intended.

    For this reason filters always return a value whereas the return value of an action is ignored.

    Please note that this is not a rule in terms of coding. You may use one or the other as you like & it won’t throw any errors but they are different in how they are named & how wordpress intended them to be & it’s very highly recommended that you follow this pattern.

  3. My Congratulations. You understand topic perfectly. Filters if you want to change incoming content (that’s why its filter). Action thats if want to do something (that’s why its action).