I am trying to find a way to filter the Media Library by the Post Category that a Media item is assigned with. I can see that you can sort by "attached to" but this only get me a little of the way there. Any suggestions?
I am trying to find a way to filter the Media Library by the Post Category that a Media item is assigned with. I can see that you can sort by "attached to" but this only get me a little of the way there. Any suggestions?
Share Improve this question asked Dec 17, 2013 at 21:14 whodeeewhodeee 1851 silver badge10 bronze badges1 Answer
Reset to default 3You can use pre_get_posts
to filter the query.
So you can
- retrieve a category from query vars
- retrieve the post with that category
- set the media query to include only posts having that post as the parent
To give a UI, you can use the restrict_manage_posts
hook to output a category dropdown.
add_action('pre_get_posts', 'my_filter_media_by_cat');
add_action( 'restrict_manage_posts', 'my_add_media_cat_dropdown' );
function my_filter_media_by_cat( $q ) {
$scr = get_current_screen();
$cat = filter_input(INPUT_GET, 'postcat', FILTER_SANITIZE_STRING );
if ( ! $q->is_main_query() || ! is_admin() || (int)$cat <= 0 || $scr->base !== 'upload' )
return;
// get the posts
$posts = get_posts( 'nopaging=1&category=' . $cat );
// get post ids
$pids = empty( $posts ) ? false : wp_list_pluck($posts, 'ID');
if ( ! empty($pids) ) {
$pidsTxt = implode( ',', $pids );
global $wpdb;
// Get the ids of media having retrieved posts as parent
$mids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_parent IN ($pidsTxt)");
if ( ! empty($mids) ) {
// Force media query to retrieve only media having retrieved posts as parent
$q->set( 'post__in', $mids );
} else {
// force media query to return no posts
$q->set( 'p', -1 ); // Let query found nothing
}
}
}
function my_add_media_cat_dropdown() {
$scr = get_current_screen();
if ( $scr->base !== 'upload' ) return;
$cat = filter_input(INPUT_GET, 'postcat', FILTER_SANITIZE_STRING );
$selected = (int)$cat > 0 ? $cat : '-1';
$args = array(
'show_option_none' => 'All Post Categories',
'name' => 'postcat',
'selected' => $selected
);
wp_dropdown_categories( $args );
}
The negative of this code is that you have to run 3 queries to filter the media...
Result on UI: