Home › Forums › Add-ons › Repeater Field › 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?
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.
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.