WordPress: How to show a specific post or page

Jun 04, 2010 by Tony Chung in Technology

I have a lot of fun playing with content management systems. Last week I wrote about some of the fun stuff I’m doing with MediaWiki. This time I’ll be looking at a specific task common to WordPress template creation: How to retrieve the contents of a specific post or page using the get_post() function.

My first attempts using get_post() returned empty values. After hours of searching and plugging away at the task, things started to click. I figured I should record this keep track of the solution for future reference, and to help out anyone else with the same problem.

Retrieving a specific post using get_post()

The get_post() function takes two arguments:

  • $var_id: The ID (of type integer) of the post you wish to retrieve.
  • $type: The data type returned. Default is an object. The data could also be returned in an array, either associative or key-indexed (ARRAY_A), or numerically indexed (ARRAY_N).

An idiosyncrasy of the get_post() function is that because the function passes $var_id internally as a reference, the parameter cannot be a literal integer. You must pass the parameter as a variable.

What data is returned?

This example shows how to retrieve the data object for my “About” page, or post id #2. Insert the following code in a PHP template, or within the body of a function:

$post_id = 2;   // specify the post id to retrieve
$specific_post = get_post( $post_id ); // get the post object

Use PHP’s print_r() function to display the following:

[ID] => 2
[post_author] => 1
[post_date] => 2008-05-07 16:14:19
[post_date_gmt] => 2008-05-07 23:14:19
[post_content] => { removed to save space, but you get the idea... }
[post_title] => About Tony Chung
[post_category] => 0
[post_excerpt] =>
[post_status] => publish
[comment_status] => closed
[ping_status] => closed
[post_password] => { not telling }
[post_name] => about_tony_chung
[to_ping] =>
[pinged] =>
[post_modified] => 2009-06-20 12:03:59
[post_modified_gmt] => 2009-06-20 20:03:59
[post_content_filtered] =>
[post_parent] => 0
[guid] =>
[menu_order] => 0
[post_type] => page
[post_mime_type] =>
[comment_count] => 0
[filter] => raw

You can then output any of these values by referencing their key. Because the default data type is an object, to display the contents of the post_title property, you would use

echo $specific_post -> post_title;

If you request the data as an ARRAY_A instead, use the following statement:

echo $specific_post['post_title'];

Letting WordPress format your content for you

Hey, wait a minute! WordPress includes number of internal functions that process your content for you. This processing pretties up text by breaking blocks of text into paragraphs, replacing square bracketed options like captions into full HTML, and making straight quotes and apostrophes all nice and curly.

When you display your content, you could use the following statement:

echo wpautop( $specific_post -> post_content );

wpautop() takes care of basic content formatting for you.

However, if your pages require processing for options in square brackets, like image captions, or embedded media plugins, you should instead use the setup_postdata() function instead. This lets you publish the output using the_content().

setup_postdata($specific_post);
the_content();

For more information, read How WordPress Processes Post Content, or Displaying Posts Using a Custom Select Query at the WordPress Codex.

More random stuff because I’m just that way

This next example shows how to put a number of things together. I needed a way to display a random page based on the specific section a user visits. To restrict the list of page choices, I organized the pages into collections of pages and sub-pages (or children). By passing the page parent as a parameter, this function chooses a random page from the list of its page children.

function random_page_select( $parent_page )
{
  // creates array of child pages under $parent_page
  // in order to choose a random page

  // get page_children
  $page_children = get_pages( 'child_of=' . $parent_page );
  foreach( $page_children as $page_child )
  {
    $page_list[] = $page_child->ID;
  }

  // give the mt_rand() function a lo-high range
  // lo is 1, high is the size of the array
  // reduce the result by 1 because $page_list array
  // is zero-indexed
  $page_key = mt_rand( 1, sizeof( $page_list ) ) - 1;

  // select random page child based on this key
  $post_id = $page_list[$page_key];

  // gather post content
  $specific_post = get_post( $post_id );

  // format post content
  // option 1: print wpautop( $specific_post->post_content );
  // or option 2:
  setup_postdata($specific_post);
  the_content();
}

Adding a post heading

In the above function, the title of the post is missing. This is intentional, because in my application the page title is meant to be the same on every load. It’s easy enough to add the title. Simply output the post_title property into an appropriate location in your template.

Most WordPress templates use this:

post_title; ?>

I’m more comfortable using this:

echo '

' . $specific_post -> post_title . '

'; ?>

Whatever you choose to use, be consistent.

I hope this post helps you out with your WordPress template creation. I look forward to hearing your responses. Thanks for reading!

 

  • Liamhassimi

    Hi there, been looking around for ages for a solution to my problem. Basically I want to display the 2 most recent posts out of the loop in a widget which will be placed above the loop so that it shows the 2 most recent posts in full and the rest smaller with thumbnails.

    Thus explaining the difficulty having with displaying the two most recent posts outside the loop. Would be great if you could help me with this and I will happily give you £20.

    Yours,
    Liam [http://www.tsty.co.uk/blog/

    • Hey Liam: My time costs just a bit more than that, but let me point you in the right direction. My information about get_post() is only half right. A better method would be to set up different instances of the WP_Query() object for your sidebars. Then create separate loops.

      Oh, and remember when you do so, that wp_reset_query() is your friend.