Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm doing an archive page for a theme that will contain only images thumbnails. The maximum amount of thumbnails that the page layout can contains is 12. So as query I would like to been able to get two different results.

If there is 12 thumbnails, show them all.

If there is less than that maximum, fill the rest with the amount of placeholder that you need to bring the result to 12.

Here my first draft:

 <?php 

    $count = 1;
    query_posts( 'posts_per_page=12&order=ASC' );

    if (have_posts()) : while (have_posts()) : the_post(); ?>
        <div class="archive-post-single">
            <?php if ( has_post_thumbnail() ) { 
            ?>


            <a href="<?php echo get_permalink(); ?>"><?php the_post_thumbnail(); ?></a>


            <?php

            }

            ?>  

        </div>


        <?php $count++;
      endwhile; endif; ?>

    <?php if ($count < 12) { ?>

<div class="archive-post-single">
<img src="<?php bloginfo('template_directory'); ?>/images/thumb.png" alt="" />
</div>
<?php } ?>
    </div>  

        <?php wp_reset_query(); ?>
share|improve this question

3 Answers 3

There are two kinds of loops in PHP:

  • With a unknown amount of elements ( while(), foreach(), do() while, etc)
  • With a specific number of elements (for() )

You need a loop with a specific number of elements (in this case 12 elements). So a while loop is not what you need. At first take a look at the loop which is normaly used in WordPress

$posts = new WP_Query( 'numberposts=12' );
echo '<ol>';

while( $posts->have_posts() ) {
  $posts->the_post();
    $title = get_the_title();
    echo '<li>' . $title . '</li>';
}

echo '</ol>';

This loop display posts as long as there are any posts left. If there are only five posts, only five posts will be displayed.

Let assume you have only five posts, but want to display 12 list elements. Let start with a loop which will create 12 list elements.

echo '<ol>';
for( $number = 0; $number < 12; $number++ ) {
  // create list element
}
echo '</ol>';

Now we need a switch inside our loop to decide if there is another post to display or not. If there is another post, display the post title. If not, display something else like a placeholder.

echo '<ol>';
  for( $number = 0; $number < 12; $number++ ) {

   if( $number < $post_count ) {
     // display post
   } else {
     //display placeholder
   }

echo '</ol>';

As long as the number of the current loop item is smaller as the amount of all posts, display a post, else display the placeholder.

Now we just need the number of posts. This is quiet easy: $post_count = $posts->post_count;

$posts = new WP_Query( 'numberposts=12' );
$post_count = $posts->post_count;

    echo '<ol>';

    for( $number = 0; $number < 12; $number++ ) {

      if( $number < $post_count ) {
        // display the post
        $posts->the_post();
        $title = get_the_title();
        echo '<li>' . $title . '</li>';

      } else {
        //display the placeholder
        echo '<li>No more posts</li>';

      }
    }

    echo '</ol>';

I hope this will help and clarify the difference between a while-loop and a for-loop.

share|improve this answer

Hopefully this should do the trick. If you add meta_key => _thumbnail_id to your query it will only query posts with featured image. Hence you can remove the has_post_thumbnail() check also.

$count = 0;
query_posts( array( 'posts_per_page' => 12, 'order' => 'ASC', 'meta_key' => '_thumbnail_id' ) );

if (have_posts()) : while (have_posts()) : the_post(); ?>

        <div class="archive-post-single">
            <a href="<?php echo get_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
        </div><?php

        $count++;
    endwhile;
endif;

wp_reset_query();

if ( $count < 12 ) {
    for ($i = $count; $i <= 12; $i++) { ?>

        <div class="archive-post-single">
        <img src="<?php echo get_stylesheet_directory_uri(); ?>/images/thumb.png" alt="" />
        </div><?php

    }
}
share|improve this answer
    
just a question - what is the advantage of putting a meta_key over has_post_thumbnail() ? –  krembo99 Dec 10 '11 at 9:56
    
In your case it would be an advantage. Since you are showing 12 posts per page. For example out of the first 12 posts, 3 posts don't have a featured image set. The count of the no. of posts in your previous query would be 12 as having a featured image is not a criteria in your first query, but in the new query it would be 9. Plus the new query will fetch the 12 most recent entries having a featured image, only then will it fill the remaining with the default images. I guess that is what you want right? –  Joshua Abenazer Dec 10 '11 at 10:03
    
Ok the previous comment was answered with regard to the one asking the question. Din't see that the commenter and the asker are not the same :) –  Joshua Abenazer Dec 10 '11 at 10:27
    
I guess you are right . that is an option. In my themes I handle this problem in a totally different way, which is to set a default (fallback) image by hooking save_post update_post, if no other was set . that way, the clients can not go wrong. (well.. they will always find a way :-) but until now it worked for me.) –  krembo99 Dec 10 '11 at 10:36
    
Thank you very much for your help Joshua, it work like a charm! I couldn't do it without you :) François –  francois Dec 10 '11 at 18:01

Plugin for the rescue

I wrote a plugin for exact that case. It's simply called »WP default img« and can be grabbed at GitHub.

Usage

It's simple: Add an image size. Echo the placeholder. Done.

// functions.php during init:
add_image_size( 'default_img', 80, 80, true );

echo wp_default_img( array( 
     'url'  => get_site_url( null, 'your_path' ).'/some_img.jpg'
    ,'size' => 'default_img' 
) );

It also has two filters:

  • wp_default_img_attr // Default attributes (height/width/alt/etc.)
  • wp_default_img // The output/result

The plugin is quite old, but still valid. But to be honest: I'd make it much shorter and easier (from an internal perspective) these days.

Core feature

I also added a Trac ticket to get this feature in core, as I see many people needing it.

If you think this is needed, just add yourself to the ticket and comment. If it gets popular, maybe it will find its way into core.

share|improve this answer

Your Answer

 
discard

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.