EDIT 2 - FINAL EDIT
在我开始编辑之前,这里有几件事
我的答案中的代码是基本的,旨在演示这些概念。我现在已经测试了这两组代码,所有的工作都如预期的那样。您必须自己添加所有所需的标记、样式和模板标记。
在实现方面,这完全取决于您,我们不是来为您实现代码的。希望您至少了解如何在主题中使用和实现此代码
您已确认这是您的搜索。php,这使得我原始答案中的代码毫无用处。您不应该使用自定义查询更改主查询,因为正如您所看到的,这总是有问题的。请参见this post 我已经完成了这个主题
我的解决方案是粘贴我第一次编辑的代码(EDIT 1) 在您的功能中。php。您必须修改pre_get_posts
根据需要采取行动。我已经测试了代码,它工作得很好。要使其工作,您需要使用main loop 正在搜索中。php。
ORIGINAL ANSWER
我从你的问题中了解到的是
pro
值必须首先按日期排序,然后
free
随机排序
我们将使用与中基本相同的想法your previous question 经过一些修改
在我开始之前,请注意,您不应该使用自定义SQL查询。利用pre_get_posts
, WP_Query
或get_posts
而是相应地创建/调整/修改查询
我还是一个SQL学习者,所以我将放弃你的想法,与WP_Query
使用上述本机函数无法实现所需的排序类型。此外,您不需要运行两个查询来实现这一点,一个就足够了。
我的想法是检索meta_value
属于pro
和free
. 我们将保留默认的“orderby”和“order”参数,因为这无关紧要。我们将使用PHP实现所需的排序顺序
因此,让我们编写代码:
STEP 1
如前所述,我们需要得到所有有
meta_value
属于
pro
和
value
$args = [
\'post_type\' => \'listing\',
\'meta_key\' => \'geocraft_listing_type\',
\'meta_value\' => \'free, pro\',
\'meta_compare\' => \'IN\',
\'posts_per_page\' => -1,
];
$the_query = new WP_Query( $args );
STEP 2
在我个人看来,实现排序顺序的最佳方法是打破
$posts
将数组分成两个单独的数组,其中一个数组将容纳所有带有
meta_value
属于
pro
而另一个阵型将以
meta_value
free
.
$free = [];
$pro = [];
foreach ( $the_query->posts as $post ) {
$meta = get_post_meta( $post->ID, \'geocraft_listing_type\', true );
if ( \'free\' == $meta ) {
$free[] = $post;
}else{
$pro[] = $post;
}
}
unset($post);
STEP 3
使用
meta_value
pro
将保持不变,此帖子数组将根据帖子日期进行排序。我们需要用
meta_value
free
由于您需要对这些帖子进行随机排序,我们将使用PHP函数shuffle()
将这些帖子随机显示
shuffle($free);
STEP 4
我们需要取消原始的
$posts
并用新值重置它。这一价值将通过将两个阵列合并在一起来创造,
pro
首先,然后
free
. 为此,请使用
array_merge()
. 此新数组将设置为的新值
$posts
unset($the_query->posts);
$the_query->posts = array_merge($pro, $free);
STEP 5
现在你可以像往常一样循环浏览你的帖子了
if ( $the_query->have_posts() ) {
echo \'<ul>\';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo \'<li>\' . get_post_meta( $post->ID, \'geocraft_listing_type\', true ). \'</br>\' . get_the_title() . \'</li>\';
}
echo \'</ul>\';
}
wp_reset_postdata();
ALL TOGETHER NOW
<?php
$args = [
\'post_type\' => \'listing\',
\'meta_key\' => \'geocraft_listing_type\',
\'meta_value\' => \'free, pro\',
\'meta_compare\' => \'IN\',
\'posts_per_page\' => -1,
];
$the_query = new WP_Query( $args );
$free = [];
$pro = [];
foreach ( $the_query->posts as $post ) {
$meta = get_post_meta( $post->ID, \'geocraft_listing_type\', true );
if ( \'free\' == $meta ) {
$free[] = $post;
}else{
$pro[] = $post;
}
}
unset($post);
shuffle($free);
unset($the_query->posts);
$the_query->posts = array_merge($pro, $free);
if ( $the_query->have_posts() ) {
echo \'<ul>\';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo \'<li>\' . get_post_meta( $post->ID, \'geocraft_listing_type\', true ). \'</br>\' . get_the_title() . \'</li>\';
}
echo \'</ul>\';
}
wp_reset_postdata();
您可以修改此代码以使用
pre_get_posts
和
the_posts
如果假设这是主查询,则进行筛选。
EDIT 1
如果假设这是在搜索页面上作为主查询完成的,那么您将使用pre_get_posts
更改搜索页面上的主查询。我不会详细解释每件事,因为它应该以与上面相同的方式工作WP_Query
在您的功能中。php,添加以下代码。这将仅更改搜索页面的主查询
add_action( \'pre_get_posts\', function ( $query ) {
if ( !is_admin() && $query->is_search() && $query->is_main_query() ) {
$query->set( \'post_type\', \'listings\' );
$query->set( \'meta_key\', \'geocraft_listing_type\' );
$query->set( \'meta_value\', \'free, pro\' );
$query->set( \'meta_compare\', \'IN\' );
$query->set( \'posts_per_page\', \'-1\' );
}
});
您现在要使用
the_posts
filter可筛选搜索页面上的排序顺序。
所以,还是在你的函数中。php,添加以下代码
add_filter( \'the_posts\', function ($posts, $query) {
if( $query->is_main_query() && $query->is_search() ) {
$free = [];
$pro = [];
foreach ( $posts as $post ) {
$meta = get_post_meta( $post->ID, \'geocraft_listing_type\', true );
if ( \'free\' == $meta ) {
$free[] = $post;
}else{
$pro[] = $post;
}
}
unset($post);
shuffle($free);
$posts = array_merge($pro, $free);
}
return $posts;
},
10, 2 );
在您的搜索中。php您不需要修改任何内容。这里只需要默认循环。