Support

Account

Home Forums Add-ons Repeater Field pre_get_post and nested while loop

Solved

pre_get_post and nested while loop

  • I’m trying to sort the archive page of a custom post type sfwd_courses using pre_get_post

    Here’s stripped down version of my archive page:

    
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    
    <h3 class="h2 entry-title" style="font-size: 1em;">
              <a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
    </h3>
                
    
    <?php if ( have_rows( 'presenter' ) ) : ?>
    <ul>
       <?php while ( have_rows( 'presenter' ) ) : the_row(); ?>
          <?php $presenter_info = get_sub_field( 'presenter_info' ); ?>
          <?php if ( $presenter_info ) : ?>
             <?php $post = $presenter_info; ?>
    	 <?php setup_postdata( $post ); ?> 
    	    <li><a>"><?php the_title(); ?></a></li>
    	 <?php wp_reset_postdata(); ?>
          <?php endif; ?>
       <?php endwhile; ?>
    </ul>
    <?php else : ?>
    	<?php // no rows found ?><p>There is no presenter.</p>
    <?php endif; ?>
                
                
    <p>Expires: <?php the_field( 'expiry_date' ); ?></p>
    
    <p>CE Points: <?php the_field( 'ce_points' ); ?>  </p>          
                
    
    <?php endwhile; ?>
    
    <?php endif; ?>
    

    If I use this in functions.php, the sorting works but the presenter_info sub-field (which can contain multiple presenter names — its a post object field) does not display:

    
    
    add_action( 'pre_get_posts', 'my_change_sort_order'); 
        function my_change_sort_order($query){
               if(is_post_type_archive( $sfwd_courses )):
          
               $query->set('orderby', 'meta_value'); 
    	   $query->set('meta_key', 'expiry_date');   
    	   $query->set('order', 'DESC'); 
            endif;    
        };
    

    What am I missing?

  • 
    $sfwd_courses
    

    has no value in your function

  • Thanks John. That’s not it (its actually a global that Learndash LMS creates)

    Even when I use

    add_action( 'pre_get_posts', 'my_change_sort_order'); 
        function my_change_sort_order($query){
            if(is_post_type_archive( 'sfwd-courses' )):
               $query->set('orderby', 'meta_value'); 
    		   $query->set('meta_key', 'expiry_date');   
    		   $query->set('order', 'DESC'); 
            endif;    
        };
    

    and I I check the output of archive-sfwd-courses.php, it does sort correctly (in this case according to descending expiry_date field) but it no longer displays the field presenter_info (the one in the nested while loop.)

    All the fields show correctly when I do not use the pre_get_posts function.

  • 
    add_action( 'pre_get_posts', 'my_change_sort_order'); 
        function my_change_sort_order($query){
    if (!$query->is_main_query()) {
      return;
    }
               if(is_post_type_archive( $sfwd_courses )):
          
               $query->set('orderby', 'meta_value'); 
    	   $query->set('meta_key', 'expiry_date');   
    	   $query->set('order', 'DESC'); 
            endif;    
        };
    
  • John – that’s brilliant. I can’t believe how simple this solution turned out to be. I’m not sure if I understand it fully. isn’t it the main query that we’re trying to order? Thank you for your help on this!

  • The reason is that pre_get_posts is applied to all post queries and ACF does a query to get the posts in the relationship field. When you use pre_get_posts you need to check the details of the query being done before you alter the query. In this case just making sure that you only make changes to the main query. Your filter could have other side effects, like being run on the wrong post type or even being run int the admin causing the admin post list to be altered.

  • Thanks again – I get it now!

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.