I have a page set up with six posts per page with two rows of three posts. If I only have one post up, I would like the other five to have “placeholder images” letting the viewers know that more posts are coming. Kind of like this:

I would create the placeholder images to put in there.
Here is how my blog is set up. Pretty basic. Has anybody ever done anything like this before?
<div id="article-list">
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<div class="post-info">
<?php the_title( sprintf( '<h1 class="entry-title"><a href="%s" rel="nofollow noreferrer noopener" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h1>' ); ?>
<?php mobile_mix_posted_on(); ?>
</div>
<?php if ( '' != get_the_post_thumbnail() ) {
the_post_thumbnail();
} ?>
</article><!-- #post-## -->
<?php endwhile; ?>
<?php mobile_mix_paging_nav(); ?>
<?php else : ?>
<?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>
</div>
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can add a filter to 'loop_start', count how may posts you have and inject the needed number of “fake” posts that are intances of WP_Post not having a reference in DB.
add_filter( 'loop_start', function( $query ) {
$module = $query->post_count % 6;
$to_fill = $module === 0 ? 0 : 6 - $module ;
if (
(int) $query->post_count === 0
|| (int) $to_fill === 0
|| ! $query->is_main_query()
|| $query->is_singular()
// probably you need to put other conditions here e.g. $query->is_front_page()
// to affect only specific pages and not all...
) {
return;
}
$query->post_count += $to_fill;
$query->found_posts += $to_fill;
$fake = clone $query->posts[0];
$fake->post_title = 'Coming Soon';
$fake->post_name = 'coming-soon';
$fake->is_fake = TRUE;
$fake->ID = 0;
$fake_posts = array_fill( 0, $to_fill, $fake );
$query->posts = array_merge( $query->posts, $fake_posts );
} );
Edit: avoid template editing
Now we have to prevent fake posts to have a permalink
add_filter( 'the_permalink', function( $permalink ) {
if ( isset($GLOBALS['post']->is_fake) ) {
return '#';
}
return $permalink;
} );
And use coming soon image as post thumbnail:
add_filter( 'get_post_metadata', function( $check, $pid, $key ) {
global $post;
if ( $key === '_thumbnail_id' && empty($pid) && isset( $post->is_fake ) ) {
$check = 1; // just a non falsey number to pass has_thumbnail check
}
return $check;
}, PHP_INT_MAX, 3 );
add_filter( 'post_thumbnail_html', function( $html, $pid ) {
global $post;
if ( empty($pid) && isset( $post->is_fake ) ) {
$html = '<img src="https://example.com/path/to/coming-soon.png" alt="coming Soon" />';
}
return $html;
}, PHP_INT_MAX, 2 );
Method 2
Here’s one idea how one could play with the the_posts filter in a way that you don’t have to modify your current template code:
/**
* Append "Coming Soon" posts, if there are not enough posts
*
* @see http://wordpress.stackexchange.com/a/161275/26350
*/
add_filter( 'the_posts',
function( $posts, $q )
{
if( ! is_admin() && $q->is_main_query() )
{
$count = count( $posts );
$ppp = $q->query_vars['posts_per_page'];
// Assume there's at least one post available, before filling up:
if( $count > 0 && $count <= $ppp )
{
// Cet "Coming Soon" post
$tmp = get_post( 123 ); // Adjust this ID to your needs
// Fill up with the "Coming Soon" post:
for( $i = $count + 1 ; $i <= $ppp; $i++ )
{
$posts[] = $tmp;
}
}
}
return $posts;
}
,99, 2 );
This assumes you have a Coming Soon! post/page, you just have to modify the post ID.
Notice that this is for PHP versions 5.3+.
Update: Thanks to @G.M. for the tip about skipping the pre_get_posts hook.
I hope you can modify this to your needs.
Method 3
Having spent 50 minutes unsuccessfully explaining accepted answer to colleague…
I want to point out that for simple case the basic check of post count might be perfectly sufficient to template such output:
if ( 6 > $wp_query->post_count ) {
// placeholder output
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0