How to inject a virtual post (i.e. without adding it to the database)

I use a WordPress blog and I want to show a post without adding anything to database.
What I want to say is:

I generate a post when page loads,and prepend it in homepage.
I’ve searched and found wp_insert_post() function but it also add to database.
How can i do this with php?

Read More

For example:
There is a post array which is generated by a query.How can I insert my post to this array before page loaded?

I want clear my idea.Here’s step by step what i want.

*1)*Im generating an array like that
$arr[‘title] = “my title”,
$arr[‘content’] = “my content”,

*2)*WP sends a query to database and have the posts am i right? And there is an array,to show on the theme and main page?
At this point i want to add my external array(generated in step1 ) to this array(generated by WP via a query)

3) By this way i will be able to add a post without adding it to my database.

Related posts

Leave a Reply

2 comments

  1. You can simply add your virtual post in one of your theme templates as raw HTML.

    Alternatively, if you’re feeling adventurous, you could modify the main query results and include your post inside:

    add_action('loop_start', function($query){
    
      // create the post and fill up the fields
      $post = new WP_Post((object)array(
        'ID'           => -1,
        'post_title'   => 'Bla blah',
        'post_content' => 'Your content',
      ));
    
      // add it to the internal cache, so WP doesn't fire a database query for it
      // -1 is the ID of your post
      if(!wp_cache_get(-1, 'posts'))
        wp_cache_set(-1, $post, 'posts');
    
      // prepend it to the query
      array_unshift($query->posts, $post);
    });
    
  2. The currently accepted answer causes the new post to delete the last post in the loop, because it doesn’t update the post count. Here’s my modified version that also includes:

    1. Support for empty categories.
    2. Only one place to declare the new post’s ID.
    3. Adding is_main_query() as the person who originally answered mentioned in a comment.
    4. A setting to decide if the new post should be appended or prepended.
    5. Hiding the post’s date because otherwise you get something like 00000000. I could have used a dynamic date but it may be bad SEO to keep updating the date without updating the content.
    6. Hiding the post’s comment link because it just leads to the homepage.
    7. A setting to control the post type. You might prefer “page” because “post” displays a general category, which I found no way to bypass. “Page” also looks more distinguished among other posts, assuming that’s a good thing.

    Here’s the modified code:

    function virtual_post($query) {
      $post_type = 'page'; // default is post
      if (get_class($query)=='WP')
         $query = $GLOBALS['wp_query'];
      if ($query->is_main_query()) {
         $append = true; // or prepend
         // create the post and fill up the fields
         $post = new WP_Post((object)array(
          'ID'           => -1,
          'post_title'   => 'Dummy post',
          'post_content' => 'This is a fake virtual post.',
          'post_date' => '',
          'comment_status' => 'closed'
         ));
         if ($post_type <> 'post')
           $post->post_type = $post_type;
         // add it to the internal cache, so WP doesn't fire a database query for it
         if(!wp_cache_get($post->ID, 'posts')) {
           wp_cache_set($post->ID, $post, 'posts');
           if ($query->post_count==0 || $append)
             $query->posts[] = $post;
           else
             array_unshift($query->posts, $post);
           $query->post_count++;
         }
      }
    }
    
    $virtual_post_settings = array('enable' => true, 'include_empty_categories' => true);
    if ($virtual_post_settings['enable']) {
      if ($virtual_post_settings['include_empty_categories'])
        add_action('wp', 'virtual_post');
      else
        add_action('loop_start', 'virtual_post');
    }