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.

  • Janke

    If i would like to filter out products with discounted price from Woocommerce, then what should i modify within your code? It seems that meta_key for sale price is _sale_price but i cannot figure out how to modify your snippet to make it work.

  • J Fournier

    This is great, but I am having a problem with it. After I run the filter once, the options no longer show up in the select. If I remove the ADMIN_FILTER_FIELD_VALUE from the url and then load the page, the options show up again. Do you have a solution for this? Thanks!

  • J Fournier

    Fixed the issue I was having. Don’t use capital letters or a post type where it says NAME_OF_YOUR_POST.

Connect with me