Is there some wordpress magic/plugin that will make the media library only show images that were uploaded to a specific custom post type? I have a custom post type called "artists", I want, when admin click to upload/attach an image, that the media library popup only show images that have been uploaded to the artists custom type, and not the entire site.

I use the ACF plugin for handling custom fields, and custom post types ui. Is this possible?

  • Let me check if I understand it correctly... So you want to change media library popup in such way that it shows only images that were uploaded to specific CPT if you open it while editing this CPT. And it should work like always when you're editing other post types? – Krzysiek Dróżdż Jun 8 '15 at 20:23
  • What's the context/reasoning behind doing this? Are you trying to implement an artist picker? – Tom J Nowell Jun 9 '15 at 0:44
  • The use case in my case is a large WordPress site where not everyone edits the same post types. It's much tidier (and useful) to show the most recent related file uploads as opposed to uploads from all over the site, so that files that need to be reused can easily be picked. (I didn't ask this question originally but added the bounty. I'm trying to do exactly what Krzysiek described (thanks for the answer, I'll try it)) – guidod Jun 10 '15 at 3:41
up vote 9 down vote accepted
+50

I'm not 100% sure if I get your problem right, but... Maybe this will help you...

Media uploader gets attachments with simple WP_Query, so you can use many filters to modify it's contents.

The only problem is that you can't query posts with specific CPT as parent using WP_Query arguments... So, we will have to use posts_where and posts_join filters.

To be sure, that we'll change only media uploader's query, we'll use ajax_query_attachments_args.

And this is how it looks, when combined:

function my_posts_where($where) {
    global $wpdb;

    $post_id = false;
    if ( isset($_POST['post_id']) ) {
        $post_id = $_POST['post_id'];

        $post = get_post($post_id);
        if ( $post ) {
            $where .= $wpdb->prepare(" AND my_post_parent.post_type = %s ", $post->post_type);
        }
    }

    return $where;
}

function my_posts_join($join) {
    global $wpdb;

    $join .= " LEFT JOIN {$wpdb->posts} as my_post_parent ON ({$wpdb->posts}.post_parent = my_post_parent.ID) ";

    return $join;
}


function my_bind_media_uploader_special_filters($query) {
    add_filter('posts_where', 'my_posts_where');
    add_filter('posts_join', 'my_posts_join');

    return $query;
}
add_filter('ajax_query_attachments_args', 'my_bind_media_uploader_special_filters');

When you open media uploader dialog while editing post (post/page/CPT), you'll see only images attached to this specific post type.

If you'd like it to work only for one specific post type (let's say pages), you'll have to change condition in my_posts_where function like so:

function my_posts_where($where) {
    global $wpdb;

    $post_id = false;
    if ( isset($_POST['post_id']) ) {
        $post_id = $_POST['post_id'];

        $post = get_post($post_id);
        if ( $post && 'page' == $post->post_type ) {  // you can change 'page' to any other post type
            $where .= $wpdb->prepare(" AND my_post_parent.post_type = %s ", $post->post_type);
        }
    }

    return $where;
}
  • Thanks for your helpful comment, I deleted my answer so as not to confuse anyone. +1 on yours. – jackreichert Jun 8 '15 at 21:26

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.