Multiple Loops in WordPress. Second loop not resetting

I’ve created a custom post type with custom fields inside WordPress. I created a new page template that runs through a loop and that works great. I’m trying to add a similar loop to the home page’s sidebar but it doesn’t work correctly.

First, the working code on my own page template.

Read More
<h2>Upcoming Events</h2>
<?php $todaysDate = date('Y/m/d');
$event_query = new WP_query('post_type=events&posts_per_page=-1&post_status=publish&meta_key=event_date&meta_compare=>=&meta_value=' . $todaysDate . '&orderby=meta_value&order=ASC');
?> 

<ul id="featured_event_list">
<?php if ($event_query->have_posts()): ?>
<?php while ($event_query->have_posts()) : $event_query->the_post(); ?>
<li>
    <h3><?php the_title(); ?></h3>
    <p>
    <?php if ( get_post_meta($post->ID, 'event_featuring', true) ) : ?>
        <strong>Featuring:</strong> <?php echo get_post_meta($post->ID, 'event_featuring', true) ?><br />
    <?php endif; ?>
    <?php if ( get_post_meta($post->ID, 'event_date', true) ) : ?>
        <?php $event_date = get_post_meta($post->ID, 'event_date', true);
        $new_event_date = date("F j, Y",strtotime($event_date)); ?>
        <strong>Date:</strong> <?php echo $new_event_date ?>
        <?php endif; ?>
        <?php if ( get_post_meta($post->ID, 'event_end_date', true) ) : ?>
        <?php $event_end_date = get_post_meta($post->ID, 'event_end_date', true);
        $new_event_end_date = date("F j, Y",strtotime($event_end_date)); ?>
        - <?php echo $new_event_end_date ?>
    <?php endif; ?>
        <br />
    <?php if ( get_post_meta($post->ID, 'event_time', true) ) : ?>
        <strong>Time:</strong> <?php echo get_post_meta($post->ID, 'event_time', true) ?><br />
    <?php endif; ?>
    <?php if ( get_post_meta($post->ID, 'event_location', true) ) : ?>
        <strong>Location:</strong> <?php echo get_post_meta($post->ID, 'event_location', true) ?>
    <?php endif; ?>
    </p>
    <p><?php the_excerpt(); ?></p>
</li>
<?php endwhile; ?>
<?php else: ?>
<li>Sorry, no upcoming events.</li>
<?php endif; ?>
</ul>

That works fine, but when I put a modified version of that code as a widget inside of functions.php, it doesn’t work:

<?php
function eventsWidget() { ?>
    <div class="uwf_widget">
        <h3 class="events"><span>Featured Events</span></h3>
        <ul>
<?php
        $todaysDate = date('Y/m/d');
        $event_widget_query = new WP_query('post_type=events&posts_per_page=2&post_status=publish&meta_key=event_date&meta_compare=>=&meta_value=' . $todaysDate . '&orderby=meta_value&order=ASC');
?> 
        <?php if ($event_widget_query->have_posts()) :?>
        <?php while ($event_widget_query->have_posts()) : $event_widget_query->the_post(); ?>
            <?php $event_date = get_post_meta($post->ID, 'event_date', true);
            $new_event_date = date("F j",strtotime($event_date)); ?>
            <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?> - <?php echo $new_event_date; ?> &nbsp;&raquo;</a></li>
        <?php endwhile; else: ?>
            <li>Sorry, no upcoming events.</li>
        <?php endif; ?>
        </ul>
            <p class="more"><a href="/about-us/events/">more events &raquo;</a></p>
        </div>
<?php } ?>

Now, if I put that code inside the normal sidebar (instead of on the homepage) – it works fine. So, clearly there is something wrong with multiple loops on the home page and the sidebar. If I simplify the widget so it only grabs 2 “events” it will grab two posts (regardless of the post_type). I’ve tried rewind_posts and wp_reset_query, so I’m not sure what else to try?

Related posts

Leave a Reply

4 comments

  1. I have the same problem and it was caused by wp_hook ‘pre_get_posts’

    <?php function custom_get_posts( $query ) {
    if ( !is_admin() && false == $query->query_vars['suppress_filters'] )
        $query->set( 'post_type', array('post', 'events', 'pages') );
    
        return $query;
    }
    add_filter( 'pre_get_posts', 'custom_get_posts' );
    ?>
    

    To solve this problem you can remove this filter before your WP_Query and add it again after this query.

    <?php
    
    remove_filter( 'pre_get_posts', 'custom_get_posts' );
    
    /*
     * Your new WP_Query
     */
    
    add_filter( 'pre_get_posts', 'custom_get_posts' );
    
    ?>
    
  2. Try adding a global post; declaration at the start of your function.

    <?php
    function eventsWidget() { 
        global $post; ?>
        <div class="uwf_widget">
            <h3 class="events"><span>Featured Events</span></h3>
            <ul>
    <?php
            $todaysDate = date('Y/m/d');
            $event_widget_query = new WP_query('post_type=events&posts_per_page=2&post_status=publish&meta_key=event_date&meta_compare=>=&meta_value=' . $todaysDate . '&orderby=meta_value&order=ASC');
    ?> 
            <?php if ($event_widget_query->have_posts()) :?>
            <?php while ($event_widget_query->have_posts()) : $event_widget_query->the_post(); ?>
                <?php $event_date = get_post_meta($post->ID, 'event_date', true);
                $new_event_date = date("F j",strtotime($event_date)); ?>
                <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?> - <?php echo $new_event_date; ?> &nbsp;&raquo;</a></li>
            <?php endwhile; else: ?>
                <li>Sorry, no upcoming events.</li>
            <?php endif; ?>
            </ul>
                <p class="more"><a href="/about-us/events/">more events &raquo;</a></p>
            </div>
    <?php } ?>
    
  3. Try a rewind_posts() after your endwhile in whichever loop is used first (if your sidebar call is at the bottom of your template, do it in your page template, or the opposite if the sidebar is called at the top).

    Another approach:

    <?php
    function eventsWidget() { ?>
        <div class="uwf_widget">
            <h3 class="events"><span>Featured Events</span></h3>
            <ul>
            <?php $todaysDate = date('Y/m/d');
            query_posts('$post_type=event&posts_per_page=2');
            if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
            <?php while ($have_posts()) : the_post(); ?>
                <?php $event_date = get_post_meta($post->ID, 'event_date', true);
                $new_event_date = date("F j",strtotime($event_date)); ?>
                <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?> - <?php echo $new_event_date; ?> &nbsp;&raquo;</a></li>
            <?php endwhile; else: ?>
                <li>Sorry, no upcoming events.</li>
            <?php endif; ?>
            </ul>
                <p class="more"><a href="/about-us/events/">more events &raquo;</a></p>
            </div>
    <?php } ?>
    
  4. I finally solved this. I used get_posts and built an array and for some reason it now works on the home page.

    <?php
    function eventsWidget() {?>
        <div class="uwf_widget">
            <h3 class="events"><span>Featured Events</span></h3>
            <ul>
    <?php
            global $post;
            $todaysDate = date('Y/m/d');
            $event_args = array('post_type' => 'events', 
                                'numberposts' => 2,
                                'meta_key' => 'event_date',
                                'post_status' => 'publish',
                                'meta_compare' => '>=',
                                'meta_value' => $todaysDate,
                                'orderby' => 'meta_value',
                                'order'=> 'ASC');
            $event_widget_query = get_posts( $event_args );
            foreach ($event_widget_query as $post) : setup_postdata($event_widget_query); ?>
                <?php $event_date = get_post_meta($post->ID, 'event_date', true);
                $new_event_date = date("F j",strtotime($event_date)); ?>
                <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?> - <?php echo $new_event_date; ?> &nbsp;&raquo;</a></li>
            <?php endforeach; ?>
            </ul>
                <p class="more"><a href="/about-us/events/">more events &raquo;</a></p>
            </div>
            <?php wp_reset_query(); ?>
    <?php } ?>