“coming soon” placeholder blog posts?

The question:

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:

enter image description here

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>

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

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

Leave a Comment