1

I'm currently working on a project where I'm loading a post with ajax. I'm using get_post() to get the post, setup_postdata() to setup the post data, and get_template_part() to load the template containing the markup I want. My function looks like this:

public function get_content($url) {  

    global $post;

    $post_id = url_to_postid($url);

    if($post_id){

        $post = get_post($post_id);

        setup_postdata( $post );
            ob_start();
            get_template_part('template/page', 'default');
            $content = ob_get_contents();
            ob_end_clean();
        wp_reset_postdata();

        return array('status' => 'success', 'content' => $content);         

    } else {

        return array('status' => 'error','message'=> 'Fant ikke post til relevante url..');

    }   

    die();  

}

My template is containing a nested loop to display a catering menu based on categories. So I use get_categories() to get all the categories that have posts and then get_posts() to display the posts for parent category. My template looks like this:

<nav class="catering-nav">
<?php   
    $category_args = array(
        'type'                     => 'menus',
        'child_of'                 => 0,
        'parent'                   => '',
        'orderby'                  => 'name',
        'order'                    => 'ASC',
        'hide_empty'               => 1,
        'hierarchical'             => 1,
        'exclude'                  => '',
        'include'                  => '',
        'number'                   => '',
        'taxonomy'                 => 'catering_themes',
        'pad_counts'               => false 

    );      

    $categories = get_categories($category_args);

    if ( $categories ) { 

    echo '<ul id="catering-menu" class="list-unstyled catering-menu">';

        foreach ( $categories as $cat ) {   

            echo '<li class="has-children menu-item"><a href="' . THEME_URL . '/themes/' . $cat->slug .'/">' . $cat->name .'</a>';

            $menus_arg = array(
                'post_type' => 'menus',
                'order' => 'ASC',
                'orderby' => 'name',
                'post_status' => 'publish',
                'tax_query' => array(
                    array(
                        'taxonomy' => 'catering_themes',
                        'field' => 'slug',
                        'terms' => $cat->slug,
                    )
                ),              
                'posts_per_page' => -1
            );      

            $menus = get_posts( $menus_arg );

            if ( $menus ) { 

            echo '<ul class="list-unstyled sub-menu">';

                echo '<li class="menu-item menu-item-title"><span class="catering-nav-back">Tilbake</span><span class="catering-nav-title">' . $cat->name .'</span></li>';

                foreach ( $menus as $post ) : setup_postdata( $post );

                    echo '<li class="menu-item"><a href="' . get_the_permalink() . '">'. get_the_title() .'</a></li>';

                endforeach; 

                wp_reset_postdata();

            echo '</ul>';    

            } 

            echo '</li>';

        }

    echo '</ul>';    

    }       

?>  

</nav>

<!-- Title and Content from the get_post() -->
<article id="post-content">
        <div class="row">
            <div class="col-md-11">
                <h1 class="post-title"><?php the_title(); ?></h1>
            </div>
            <div class="col-md-1">
                <a id="content-close" class="button-close" href="#"></a>
            </div>          
        </div>  
        <div class="row">
            <div class="col-md-12">         
                <?php the_content(); ?>
            </div>      
        </div>  
</article>

The loop getting the catering menus is working great, but the title and content that are supposed to come from the post loaded with get_post() is showing the data from the last post loaded in the catering menu loop. Do some wordpress genius know why this is happening?

1

Your inner loop overwrites the contents of $post, so any later template tags use the values of whatever it last contained.

"But I used wp_reset_postdata()!" you say? What that function does is try to restore $post from $wp_query->post. It's meant to restore the main query after secondary queries. You have two secondary queries here, so that method fails.

To fix it- either use $wp_query as a new WP_Query instance for your outer loop, which will result in wp_reset_postdata() working as expected, or assign your outer post to some other variable name and don't use template tags that rely on the global $post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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