WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Situation: my client has this simple gallery built with WP_Query showing the latest media added to the site:

$cola = new WP_Query(
    'post_type' => 'attachment',
    'post_status' => 'inherit',
    'posts_per_page' => 15,
    'post_mime_type' => 'image/jpeg',
    'orderby' => 'date'

that's working perfect. Except for now we're using AdRotate and want to display ads on the website, but we don't want these ads to be added to the query above.

A simple solution for this would be to only fetch media that is attached to a post/page, since ads never get attached to anything. This would be achievable by using post_parent: array(_of_all_post_ids) - except that we already have about 4k posts now, so this is definitely not a good approach.

Any ideas how to go about that?

Note: my client is not a techie so this is why i'm ruling out using FTP to use the banner folder AdRotate creates on wp-content. For their planned use, the media gallery would be perfect for the ads.

share|improve this question
up vote 2 down vote accepted

A similar approach to your post_parent idea is to add a filter to posts_where:

function bbg_filter_out_non_attachments( $sql ) {
    global $wpdb;

    // Maybe do some conditional logic to decide whether to filter this query, then...
    return $sql . " AND $wpdb->posts.post_parent != 0 ";
add_filter( 'posts_where', 'bbg_filter_out_non_attachments' );

Another technique is to do a manual query for post IDs with no post_parent, and then pass it to post__not_in:

$ad_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = 0 AND post_type = 'attachment'" ) );
$query_args['post__not_in'] = $ad_ids;
// etc

If you don't like the idea of mucking around directly with SQL, you could also piece something together that adds a piece of postmeta to every item uploaded through the Media Library (instead of on a new post), and then include a meta_query parameter in your WP_Query. Note, however, that this isn't going to be anywhere near as efficient as simply looking for post_parent (which is data that already exists, and does not require a table join).

share|improve this answer
I like the second approach, although i fear it will become heavier and heavier with time (i already have more than 2k attachments). On the other hand, since i'm fetching only the last 15 images, maybe querying only the last 50 posts will do... Will try! :) – moraleida Mar 20 '12 at 15:55
Hum... somehow my query is getting every media result because most of the attached images have post_parent=0 on wp_posts even though they're effectively attached to posts. Maybe the parent/child relationship for attachments is somewhere on wp_postmeta? – moraleida Mar 20 '12 at 16:17
Neverming the last comment. I was working with a corrupt db that i thought was a true copy of the real one. post_parents are there. :) – moraleida Mar 20 '12 at 16:31
Awesome, just throwed in a limitation to get the last 100 posts and it worked perfectly. Thanks! – moraleida Mar 20 '12 at 16:59
Whoop, that's great! – Boone Gorges Mar 20 '12 at 18:12

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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