简体   繁体   中英

Wordpress - Multiple loops on a page

I have got multiple loops on a page. First loop gets the posts from update post type, second loop gets a page link, third one gets post post type, again fourth one gets a specific page link and then there is the last loop that fetches the current page data. ie I have got something like the following:

Fetch the updates

<?php $updates = get_posts(array('post_type' => 'update', 'post_per_page' => 4)); ?>
<?php foreach ($updates as $update): ?>
    <?php setup_postdata($update); ?>
    <li>
        <span><?php the_time(get_option('date_format')); ?></span>
        <h4><a href="<?php echo $update->guid; ?>"><?php echo get_post_meta($update->ID, 'msp_onhome_title', true); ?></a></h4>
    </li>
<?php endforeach ?>

Fetch the news page link:

<?php
    $the_slug = 'news';
    $args=array(
      'name' => $the_slug,
      'post_type' => 'page',
      'post_status' => 'publish',
      'numberposts' => 1
    );
    $blog_page = get_posts($args);

    if( $blog_page ) : 
?>
    <span class="stylish-extend">
        <a href="<?php echo $blog_page[0]->guid; ?>">More News &rarr;</a></span>                                    
<?php endif; ?>

Fetch posts:

<?php $color_classes = array('dark-blue', 'dark-red', 'black', 'maroone', 'light-blue'); ?>

<?php $posts = get_posts(array('post_type' => 'post', 'post_per_page' => 5)); ?>
<?php foreach ($posts as $post): ?>
    <?php setup_postdata($post); ?>
    <li>
        <article class="blog-post">
            <header>
                <p class="post-title dark-blue">
                    <a href="<?php echo $post->guid; ?>"><?php the_title(); ?></a>
                    <span>Posted in <i><?php the_category(', '); ?></i> by <i><?php the_author(); ?></i></span>
                </p>
            </header>
        </article>
    </li>
    <!-- <span><?php the_time(get_option('date_format')); ?></span> -->
<?php endforeach ?>

Fetch Page link

<?php
    $the_slug = 'blog';
    $args=array(
      'name' => $the_slug,
      'post_type' => 'page',
      'post_status' => 'publish',
      'numberposts' => 1
    );
    $blog_page = get_posts($args);

    if( $blog_page ) : 
?>
        <a href="<?php echo $blog_page[0]->guid; ?>">Head to blog &raquo;</a>

<?php endif; ?>

Fetch the actual page content (current page)

<!-- Problem here -->
<section id="meet" class="light">
    <?php if (have_posts()): while( have_posts() ) : the_post();  ?>
        <?php the_content(); ?>
    <?php endwhile; endif; ?>
</section>

The problem lies here ie it doesn't show the actual page content. Strangely, when I take this loop above all the loops at the top most position, it shows the page data correctly. I have tried wp_reset_query() and wp_reset_post_data() (or was it wp_reset_postdata() ?) after each of the loop but it didn't work. Another thing I tried is, saved the reference of the $wp_query in a variable, performed the loops and then restored the $wp_query ie like the following:

global $wp_query;
$temp_wpquery = $wp_query;

// perform all the loops and stuff

global $wp_query;
$wp_query = $temp_wpquery;

// perform the stuff

Still the results were same. Can any body please tell me what am I doing wrong here? Why doesn't it show the current page data in the last loop?

You'll need to use the variable name $post specifically (not another variable name) in setup_postdata() otherwise it wont work.

try to change the code like this:

<?php $updates = get_posts(array('post_type' => 'update', 'post_per_page' => 4)); ?>
<?php foreach ($updates as $post): ?>
    <?php setup_postdata($post); ?>
    <li>
        <span><?php the_time(get_option('date_format')); ?></span>
        <h4><a href="<?php echo $post->guid; ?>"><?php echo get_post_meta($post->ID, 'msp_onhome_title', true); ?></a></h4>
    </li>
<?php wp_reset_query(); endforeach ?>

Depending on where you are using setup_postdata() (if it is not in the main loop, or in a function/sidebar widget, for example), you may also need to declare - global $post; .

You don't need to save reference for $wp_query instead save the reference of global $post;

At the very top after get_header()

Insert this piece of code:

global $post;
$originalpost = $post;

//.... Then
//All your awesome stuff here
//...

//Before the actual page contents
<?php $post = $originalpost; ?>

<section id="meet" class="light">
    <?php if (have_posts()): while( have_posts() ) : the_post();  ?>
        <?php the_content(); ?>
    <?php endwhile; endif; ?>
</section>

The following has worked for us when conditionally including various PHP files that have sub-loops which predicated on post tags or other meta data of the main post for that page. As one of the previous responses suggested, including wp_reset_postdata() is necessary. Does read like you should at least be running wp_reset_postdata() immediately before the last content loop based on your current design.

Case 1: simply reference the global $wp_query variable.

global $wp_query;
if (have_posts()) {
    while( have_posts() ) :
        $wp_query->the_post();
        the_content();
    endwhile;
}
wp_reset_postdata();

Case 2: running additional query

$the_query = new WP_Query( 'page_id=1369' );
while ( $the_query->have_posts() ) :
    $the_query->the_post();
        the_content();
endwhile;
wp_reset_postdata();

What worked for me is, storing the $post in some variable, performing all the stuff, assigning stored $post value back to $post and after that I used setup_postdata($post) and then, without using any loop. And that's it. Following is the sample code:

global $post;
$temp_post = $post;

//.....
// Every thing else
//...

//Before the actual page content
<?php $post = $temp_post; ?>

<section id="meet" class="light">
    <?php setup_postdata($post); ?>
        <?php the_content(); ?>
</section>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM