简单地删除您拥有的代码并将其替换为默认循环。您不应将主查询替换为自定义查询。使用pre_get_posts根据需要修改主查询。
这就是你的分类页面的样子
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your template tags and markup
}
}
由于您的问题是排序,我们将使用usort 和the_posts 过滤器在循环运行之前但在主查询运行之后进行排序。我们不会使用多个循环,因为它们非常昂贵且资源密集,并且会破坏页面功能
我已对代码进行了注释,以便于理解。 (注意:以下代码未经测试,由于数组取消引用,需要 PHP 5.4+)
add_filter( 'the_posts', function ( $posts, $q )
{
$taxonomy_page = 'product-range';
$taxonomy_sort_by = 'product-categories';
if ( $q->is_main_query() // Target only the main query
&& $q->is_tax( $taxonomy_page ) // Only target the product-range taxonomy term pages
) {
/**
* There is a bug in usort that will most probably never get fixed. In some instances
* the following PHP warning is displayed
* usort(): Array was modified by the user comparison function
* @see https://bugs.php.net/bug.php?id=50688
* The only workaround is to suppress the error reporting
* by using the @ sign before usort
*/
@usort( $posts, function ( $a, $b ) use ( $taxonomy_sort_by )
{
// Use term name for sorting
$array_a = get_the_terms( $a->ID, $taxonomy_sort_by );
$array_b = get_the_terms( $b->ID, $taxonomy_sort_by );
// Add protection if posts don't have any terms, add them last in queue
if ( empty( $array_a ) || is_wp_error( $array_a ) ) {
$array_a = 'zzz'; // Make sure to add posts without terms last
} else {
$array_a = $array_a[0]->name;
}
// Add protection if posts don't have any terms, add them last in queue
if ( empty( $array_b ) || is_wp_error( $array_b ) ) {
$array_b = 'zzz'; // Make sure to add posts without terms last
} else {
$array_b = $array_b[0]->name;
}
/**
* Sort by term name, if term name is the same sort by post date
* You can adjust this to sort by post title or any other WP_Post property_exists
*/
if ( $array_a != $array_b ) {
// Choose the one sorting order that fits your needs
return strcasecmp( $array_a, $array_b ); // Sort term alphabetical ASC
//return strcasecmp( $array_b, $array_a ); // Sort term alphabetical DESC
} else {
return $a->post_date < $b->post_date; // Not sure about the comparitor, also try >
}
});
}
return $posts;
}, 10, 2 );
编辑
这是您的循环在编辑中按顺序显示页面的外观
if ( have_posts() ) {
// Display the range term title
echo '<h1>' . get_queried_object()->name . '</h1>';
// Define the variable which will hold the term name
$term_name_test = '';
while ( have_posts() ) {
the_post();
global $post;
// Get the terms attached to a post
$terms = get_the_terms( $post->ID, 'product-categories' );
//If we don't have terms, give it a custom name, else, use the first term name
if ( empty( $terms ) || is_wp_error( $terms ) ) {
$term_name = 'SOME CUSTOM NAME AS FALL BACK';
} else {
$term_name = $terms[0]->name;
}
// Display term name only before the first post in the term. Test $term_name_test against $term_name
if ( $term_name_test != $term_name ) {
// Close our ul tags if $term_name_test != $term_name and if not the first post
if ( $wp_query->current_post != 0 )
echo '</ul>';
echo '<h2>' . $term_name . '</h2>';
// Open a new ul tag to enclose our list
echo '<ul>';
} // endif $term_name_test != $term_name
$term_name_test = $term_name;
echo '<li>' . get_the_title() . '</li>';
// Close the ul tag on the last post
if ( ( $wp_query->current_post + 1 ) == $wp_query->post_count )
echo '</ul>';
}
}
编辑 2
上面的代码现在已经过测试并且可以工作了。根据要求,这是在我的本地安装上运行的测试。对于这个测试,我使用了 OP 中的代码和我的代码。
结果
(此结果是通过Query Monitor Plugin 获得的。此外,所有结果都包括由小部件、导航菜单、自定义功能等进行的相同额外查询)
正如我之前所说,证据在布丁中