Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

The setting Settings -> Reading -> Posts Page is set to my 'News' page, and the loop for the home.php template is populated with posts... great.

However I want to also be able to create another loop (even with WP_Query if needed) of which contains the actual page of which I've specified my Posts Page to be.

Whenever I try and and instantiate this loop it returns loads of posts instead of the page I've asked for, here's my code, compare the args with the request SQL:

<?php

    $page = new WP_Query(array('post_type' => 'page', 'page_id' => 39));
    print_r($page);

    // REQUEST: SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'page' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10

?>

You can see the request SQL query is wrong, I'm guessing because I've set the page as the Posts Page it's preventing me from using it within a loop.

Is there a way around this? I want to use the title, content and custom fields within the home.php template.

Thanks

share|improve this question
add comment

2 Answers

You can get the selected page for posts by the following code:

$page_for_posts = get_option( 'page_for_posts' );

Then, get the requested post by:

$post = get_post( $page_for_posts );

And, get the data you need:

echo apply_filters( 'the_title', $post->post_title );
echo apply_filters( 'the_content', $post->post_content );
echo get_post_meta( $post->ID, $key, $single);
share|improve this answer
    
Thanks Mike, I've got the first two parts, I really need it to overwrite the loop. I tried using setup_postdata but that fails too... looks like WP doesn't want me to do this ;-) –  Ben Everard Jan 16 '13 at 12:18
    
What do you mean by, "I really need it to overwrite the loop"? –  Chip Bennett Jan 16 '13 at 12:23
    
I worded that badly, as my 'News' page is the 'Posts page', the loop it initially populate to display a range of posts, I need to be create a new loop just for the page, thus overwriting the global $post object. So functions like the_title() will work without having to pass an ID. –  Ben Everard Jan 16 '13 at 12:36
    
Hmm, if setup_postdata really doesn't work, I wonder if there is a workaround for this. Perhaps you can create an if-statement in your page? –  Mike Madern Jan 16 '13 at 13:15
    
"I need to be create a new loop just for the page, thus overwriting the global $post object. So functions like the_title() will work without having to pass an ID" - Are you wanting your custom loop before or after the main query loop? What code have you tried? What happened unexpectedly, or didn't happen as expected? –  Chip Bennett Jan 16 '13 at 15:43
add comment

Assuming that you're using home.php, that you output the main query loop as per normal, and that you want to output a secondary loop using the $post information for the page_for_posts page:

  1. Define your custom query using WP_Query() and appropriate post parameters.
  2. Target the normal post object for the page, via `get_option( 'page_for_posts' )
  3. Output your custom query loop
  4. Reset $post, using wp_reset_postdata().
  5. Output the main query loop

For example:

<?php
/**
 * Blog posts index template file: home.php
 */

get_header();

 // Let's output your custom loop *first*
$home_query_args = array(
    'page_id' => get_option( 'page_for_posts' )
);
$home_query = new WP_Query( $home_query_args );

if ( $home_query->have_posts() ) : while ( $home_query->have_posts() ) : $home_query->the_post();
    // Output your custom query as per normal,
    // using all normal post template tags,
    // such as the_title(), the_content(), the_permalink(), etc.
endwhile; endif;

// IMPORTANT: Reset $post
wp_reset_postdata();

 // Now output the main loop query
if ( have_posts() ) : while ( have_posts() ) : the_post();
    // Normal loop output here,
    // using all normal post template tags
endwhile; endif;

get_footer();

The secret sauce here is wp_reset_postdata(). It resets the $post global to the main loop query.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.