Filter by ACF Meta Data in WordPress Admin

Handling metadata in WordPress is not that hard, and if you use ACF, it can be a better experience.

For me, ACF is one of the best plugins when it comes to WP development. Using it, we have a lot of handy fields; we can make various and unique solutions with it.

One of the best thing about this CMS is modularity. We can combine various solutions to achieve the needed result like using the pre_get_posts to make custom filters in the admin.

Filter by ACF Field Value in WordPress

You may need a custom filter for your post type based on metadata. It is useful in the admin if you have a lot of records. Fortunately, we can easily add a new select filter which displays well in the specific administration page.

In this example, we will create a filter for our events post type based on weekdays.

Create The Dropdown

We hook into the restrict_manage_posts action to display our dropdown markup.

  1. First, we check if we are at the correct page using the get_curren_screen() function and its data.
  2. After this, we get and sanitize the meta field (event_day, which is the name of our field in ACF).
  3. We fill up our choices, which can be anything, static or dynamic.
  4. Finally, we build the select field markup using the previously declared values.
/**
 * Add a select dropdown filter with meta values.
 */
function pine_event_day_dropdown() {
    $scr = get_current_screen();
    if ( $scr->base !== 'edit' && $scr->post_type !== 'events') return;

    $selected = filter_input(INPUT_GET, 'event_day', FILTER_SANITIZE_STRING );

    $choices = [
      'monday' => 'Monday',
      'tuesday' => 'Tuesday ',
      'wednesday' => 'Wednesday',
      'thursday' => 'Thursday',
      'friday' => 'Friday',
      'saturday' => 'Saturday',
      'sunday' => 'Sunday'
    ];

    echo'<select name="event_day">';
        echo '<option value="all" '. (( $selected == 'all' ) ? 'selected="selected"' : "") . '>' . __( 'Összes esemény', 'pine' ) . '</option>';
        foreach( $choices as $key => $value ) {
            echo '<option value="' . $key . '" '. (( $selected == $key ) ? 'selected="selected"' : "") . '>' . $value . '</option>';
        }
    echo'</select>';
}

add_action('restrict_manage_posts', 'pine_event_day_dropdown');

After this, if we navigate to our post type’s list page, we will see a plus select field in the filter section right above the list. You can choose a value from this list and then click on the filter button. If you do so, you will see that the event_day param with a day name value in the URL.

Filter the Results

To modify the results, we have to use the pre_get_posts filter; we wrote about it in more detail in a previous post.

  1. We made our conditions to check that this code only runs when it needed. Checking the main query on the admin side and check it is the events list page.
  2. We also check if the event_day is set and has a value other than all.
  3. The last step is the gist, modifying the query based on the value which we set in the dropdown.
/**
 * Filter the results based on meta data.
 */

function pine_event_day_filter($query) {
    if ( is_admin() && $query->is_main_query() ) {
      $scr = get_current_screen();
      if ( $scr->base !== 'edit' && $scr->post_type !== 'events' ) return;

      if (isset($_GET['event_day']) && $_GET['event_day'] != 'all') {
        $query->set('meta_query', array( array(
          'key' => 'event_day',
          'value' => sanitize_text_field($_GET['event_day'])
        ) ) );
      }
    }
}

add_action('pre_get_posts','pine_event_day_filter'); 

As you see in this example, you do not have to use ACF to create the fields. In the code, we didn’t use any unique functions, just the ones given by WordPress.

Need a web developer? Maybe we can help, get in touch!