| Posted under Articles

WordPress: how to add custom filters in post list admin area

Ever had a project where you needed to add custom filters in the admin area for a custom post type? Here is how it is done:

You will need to hook on the ‘restrict_manage_posts‘ filters to add your filter (dropdown) and to ‘parse_query‘ to alter the query according to the filter selection.

For example, if you want to add a filter to display a list of years for the user to select, add the following code in your functions.php file:


if (is_admin()){
   //this hook will create a new filter on the admin area for the specified post type
   add_action( 'restrict_manage_posts', function(){
        global $wpdb, $table_prefix;

        $post_type = (isset($_GET['post_type'])) ? quote_smart($_GET['post_type'], true) : 'post';
 
        //only add filter to post type you want
        if ($post_type == 'YOUR_POST_TYPE_HERE'){
            //query database to get a list of years for the specific post type:
            $values = array();
            $query_years = $wpdb->get_results("SELECT year(post_date) as year from ".$table_prefix."posts
                    where post_type='".$post_type."'
                    group by year(post_date)
                    order by post_date");
            foreach ($query_years as &$data){
                $values[$data->year] = $data->year;
            }

            //give a unique name in the select field
            ?><select name="admin_filter_year">
<option value="">All years</option>

                <?php 
                $current_v = isset($_GET['admin_filter_year'])? $_GET['admin_filter_year'] : '';
                foreach ($values as $label => $value) {
                    printf(
                        '<option value="%s"%s>%s</option>',
                        $value,
                        $value == $current_v? ' selected="selected"':'',
                        $label
                    );
                }
                ?>
            </select>
            <?php
        }
    });

    //this hook will alter the main query according to the user's selection of the custom filter we created above:
    add_filter( 'parse_query', function($query){
        global $pagenow;
        $post_type = (isset($_GET['post_type'])) ? quote_smart($_GET['post_type'], true) : 'post';

        if ($post_type == 'YOUR_POST_TYPE_HERE' && $pagenow=='edit.php' && isset($_GET['admin_filter_year']) && !empty($_GET['admin_filter_year'])) {
            $query->query_vars['year'] = $_GET['admin_filter_year'];
        }
    });
}

Using this technique you can actually add any filter you want.

You can read more about this here.

Thanks for your likes, this will motivate me to write posts more often!