“coming soon” placeholder blog posts?

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="http://example.com/path/to/coming-soon.png" alt="coming Soon" />";
  }
  return $html;
}, PHP_INT_MAX, 2 );

Leave a Comment