WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Get 1 attachment per post from X category outside the loop (7 posts)

  1. davebowker
    Member
    Posted 4 years ago #

    Hey,

    Hope someone can help with this. What I want is to display 5 attachments but only 1 attachment per post (so 1 attachment from a total of 5 different posts) from a specific category in the sidebar, which links to the posts permalink.

    I'm using the following code so far which gets all attachments from all posts, but some posts have more than 1 attachment and I just want to show the first one, and link it to the permalink of the post.

    <?php
    
    $args = array(
    	'post_type' => 'attachment',
    	'numberposts' => 5,
    	'post_status' => null,
    	'post_parent' => null, // any parent
    	'category_name' => 'work',
    	);
    $attachments = get_posts($args);
    if ($attachments) {
    	foreach ($attachments as $post) {
    		setup_postdata($post);
    		the_title();
    		the_permalink();
    		the_attachment_link($post->ID, false);
    		the_excerpt();
    	}
    }
    
    ?>

    Cheers.
    Dave

  2. vtxyzzy
    Member
    Posted 4 years ago #

    I think what you want is to have an outer loop which retrieves posts, with an inner loop to display the attachment. This is UNTESTED:

    <?php
    $args = array(
       'posta_per_page' => 10, // An arbitrary number. Set high enough to be sure to get 5 posts with attachments
       'caller_get_posts' => 1, // Ignore stickies
       'category_name' => 'work',
    );
    $myquery = new WP_Query($args);
    if ($myquery->have_posts() {
       $postcount = 1;
       while ($myquery->have_posts()) {
          $myquery->the_post();
          if ($postcount > 5) break;
          $attachment_args = array(
             'post_type' => 'attachment',
             'numberposts' => -1,
             'post_status' => null,
             'post_parent' => $post->ID
          );
          $attachments = get_posts($attachment_args);
          if ($attachments) {
             ++$postcount;
             foreach ($attachments as $attachment) {
                echo apply_filters('the_title', $attachment->post_title);
                the_attachment_link($attachment->ID, false);
                break;
             }
          }
       }
    }
    ?>
  3. vtxyzzy
    Member
    Posted 4 years ago #

    There may be simpler ways to do this. See this article for possibilities.

  4. davebowker
    Member
    Posted 4 years ago #

    Hey vtxyzzy,

    Cheers for looking into this. Unfortunately so far it's not working. I know your code was untested and produced an error when I ran it. I think this may be due to a missing ')' on line 8 which I then added.

    Upon trying again it ran without error, but returned no results. I'm not a hardcore PHP programmer, so you may be pretty much correct with your code apart from tweaking it slightly.

    I did try that link when I first started to do this. That's where I got the original code from. Anything more you can do to help would be greatly appreciated.

    Cheers,
    Dave

  5. vtxyzzy
    Member
    Posted 4 years ago #

    OK, please try the code below. It has been minimally tested.

    <?php
    global $wpdb;
    echo '<h2>TESTING GET FIRST ATTACHMENT FOR N POSTS</h2>';
    $max_posts = 5;
    $sql = "SELECT posts.ID, attach.ID attachID, attach.post_title, MIN(attach.post_date)
    FROM $wpdb->posts posts, $wpdb->posts attach
    WHERE posts.ID = attach.post_parent
    AND attach.post_type='attachment'
    AND attach.post_status = 'inherit'
    AND posts.post_type = 'post'
    AND posts.post_status = 'publish'
    AND posts.post_date <= NOW()
    GROUP BY posts.ID
    ORDER BY posts.post_date DESC
    LIMIT $max_posts";
    $postIDs = $wpdb->get_results($sql);
    foreach ($postIDs as $postID) {
      echo '<div>';
         echo '<h3>' . apply_filters('the_title',$postID->post_title) . '</h3>';
         the_attachment_link($postID->attachID,false);
      echo '</div>';
    }
    ?>

    BTW, I found the_attachment_link to be EXTREMELY slow. Try running the code with it commented out for a comparison.

  6. davebowker
    Member
    Posted 4 years ago #

    Hey vtxyzzy,

    I tried the code above but couldn't get it to work. What I ended up with was based off your suggestion of loop and loop again. This is the code I have now, and seems to work.

    <?php query_posts('category_name=work&posts_per_page=10'); ?>
    					<?php while (have_posts()) : the_post(); ?>
    						<?php
    						$args = array(
    							'order'          => 'ASC',
    							'post_type'      => 'attachment',
    							'post_parent'    => $post->ID,
    							'post_mime_type' => 'image',
    							'post_status'    => null,
    							'numberposts'    => 1,
    						);
    						$attachments = get_posts($args);
    						if ($attachments) {
    							foreach ($attachments as $attachment) {
    								//echo apply_filters('post_title', $attachment->post_title);
    								echo "<li><a href='";
    								echo the_permalink();
    								echo "' title='";
    								echo the_title();
    								echo "'>";
    								echo wp_get_attachment_image($attachment->ID, 'thumbnail', false, false);
    								echo "</a></li>";
    							}
    						}
    						?>
    					<?php endwhile;?>

    I'm not sure how fast it is or if it's the best way to do it, but for now it works.

    Cheers,
    Dave

  7. vtxyzzy
    Member
    Posted 4 years ago #

    Glad you got it working. Now, please use the dropdown at top right to mark this topic 'Resolved'.

Topic Closed

This topic has been closed to new replies.

About this Topic