How to filter custom posts by custom field in WordPress admin area


The Problem

When we use custom posts type and it has thousands of posts, it become necessary to filter those posts in WordPress admin dashboard. Recently I faced a similar problem. I was working on a WordPress site for antique products and I was using custom post type and custom fields. But because there was a lot of different type of products and had to rearrange and edit those often, client asked for a solution to filter sold and unsold products separately in WordPress admin.

The Solution

I added these code in functions.php file to create a dropdown of filter options at the top of the all posts. So, when I select SOLD and click on filter button, only sold items will be displayed. Here is the code you can use too for your project:

Step 1:
Add this code in the functions.php file of your WordPress theme.

/** Create the filter dropdown */
add_action( 'restrict_manage_posts', 'wpse45436_admin_posts_filter_restrict_manage_posts' );

function wpse45436_admin_posts_filter_restrict_manage_posts(){
    $type = 'post';
    if (isset($_GET['post_type'])) {
        $type = $_GET['post_type'];

    //add filter to the post type you want
    if ('NAME_OF_YOUR_POST' == $type){ //Replace NAME_OF_YOUR_POST with the name of custom post
        $values = array(
            'label1' => 'value1', //Replace label1 with name and value1 with the value of custom field
            'label2' => 'value2', //Replace label2 with name and value2 with another value of custom field
        <select name="ADMIN_FILTER_FIELD_VALUE">
<option value=""><?php _e('Filter By ', 'wose45436'); ?></option>
        <?php $current_v = isset($_GET['ADMIN_FILTER_FIELD_VALUE'])? $_GET['ADMIN_FILTER_FIELD_VALUE']:''; foreach ($values as $label => $value) {
                        '<option value="%s"%s>%s</option>',
                        $value == $current_v? ' selected="selected"':'',
        <?php } } /** if submitted filter by post meta */ add_filter( 'parse_query', 'wpse45436_posts_filter' ); function wpse45436_posts_filter( $query ){ global $pagenow; $type = 'post'; if (isset($_GET['post_type'])) { $type = $_GET['post_type']; } //Replace NAME_OF_YOUR_POST with the name of custom post if ( 'NAME_OF_YOUR_POST' == $type && is_admin() && $pagenow=='edit.php' && isset($_GET['ADMIN_FILTER_FIELD_VALUE']) && $_GET['ADMIN_FILTER_FIELD_VALUE'] != '') { $query->query_vars['meta_key'] = 'META_KEY'; //Replace META_KEY to the actual meta key
        $query->query_vars['meta_value'] = $_GET['ADMIN_FILTER_FIELD_VALUE'];


Step 2:
Read the comments in the code and replace with your custom post name, the value of custom fields and the name of custom field as described.

Connect with me