我有一个网站,列出出售的财产。我有一个自定义的wp\\u查询,并创建了一个排序下拉列表。此下拉列表按日期、价格(低-高&高-低)和床位(低-高&高-低)对帖子查询进行重新排序。价格和床位是自定义字段,仅包含数值。(无货币/逗号)。
更改时,AJAX会在下拉列表下方重新组织帖子。这一切都非常有效。
但是,有些房产没有价格(而是显示“按需价格”)。问题是,如果我将它们的价格设置为“0”,或者将这些属性的价格字段留空,那么它们将以0的价格按排序顺序出现。因此,当我按从低到高的价格对房产进行排序时,它们首先出现在列表中。
我需要正常运行排序,但如果属性价格==0,则将它们移到排序顺序的末尾,而不管选择的排序是什么。
这可能吗?可能是pre\\u get\\u帖子?
这是我的代码:
<select name="sort_by" class="sort_by_dropdown">
<option value="dateposted-desc">Sort by Newest</option>
<option value="price-desc">Sort by Price (High to Low)</option>
<option value="price-asc">Sort by Price (Low to High)</option>
<option value="bedrooms-desc">Sort by Beds (Most to Least)</option>
<option value="bedrooms-asc">Sort by Beds (Least to Most)</option>
</select>
<ul id="main_posts" class="item-listings">
<?php
// Build the inital Loop
$args = array(
\'posts_per_page\' => 9,
\'paged\' => $paged
);
query_posts( $args );
if( have_posts() ) :
while( have_posts() ): the_post();
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile;
endif;?>
</ul>
还有AJAX:
// AJAX Stuff for filters
/*
* Filter
*/
$(\'#filter\').change(function(){
$.ajax({
url : prop_loadmore_params.ajaxurl,
data : $(\'#filter\').serialize(),
dataType : \'json\',
type : \'POST\',
success : function( data ){
// reset current page to 1 when filters on
prop_loadmore_params.current_page = 1;
prop_loadmore_params.posts = data.posts;
// set max page
prop_loadmore_params.max_page = data.max_page;
$(\'#main_posts\').html(data.content);
$(".price-txt").digits(); // Add the commas!
// If not enough posts for 2nd page, hide loadmore
if ( data.max_page < 2 ) {
$(\'#prop_loadmore\').hide();
} else {
$(\'#prop_loadmore\').show();
}
}
});
return false;
});
。。。
add_action(\'wp_ajax_prop_filters\', \'property_filters\');
add_action(\'wp_ajax_nopriv_prop_filters\', \'property_filters\');
function property_filters(){
//*
// Sort by Args
//*
if( isset( $_POST[\'sort_by\'] ) && $_POST[\'sort_by\'] == \'price-desc\' ) {
$orderby = \'meta_value_num\';
$order = \'DESC\';
$meta_key = \'price\';
}
elseif( isset( $_POST[\'sort_by\'] ) && $_POST[\'sort_by\'] == \'price-asc\' ) {
$orderby = \'meta_value_num\';
$order = \'ASC\';
$meta_key = \'price\';
}
elseif( isset( $_POST[\'sort_by\'] ) && $_POST[\'sort_by\'] == \'bedrooms-desc\' ) {
$orderby = \'meta_value_num\';
$order = \'DESC\';
$meta_key = \'bedrooms\';
}
elseif( isset( $_POST[\'sort_by\'] ) && $_POST[\'sort_by\'] == \'bedrooms-asc\' ) {
$orderby = \'meta_value_num\';
$order = \'ASC\';
$meta_key = \'bedrooms\';
}
else {
$orderby = \'date\';
$order = \'DESC\';
$meta_key = \'\';
}
if (!is_user_logged_in()) {
$args = array(
\'posts_per_page\' => 9,
\'post_status\' => \'publish\',
\'paged\' => $_POST[\'page\'],
\'meta_key\' => $meta_key,
\'orderby\' => $orderby,
\'order\' => $order
);
}
else {
$args = array(
\'posts_per_page\' => 9,
\'meta_key\' => $meta_key,
\'orderby\' => $orderby,
\'order\' => $order,
\'post_status\' => array(\'publish\', \'private\'),
\'paged\' => $_POST[\'page\']
);
}
query_posts( $args );
global $wp_query;
if( have_posts() ) :
ob_start();
while( have_posts() ): the_post();
get_template_part( \'template-parts/post/content\', get_post_format() );
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = \'<p>Nothing found for your criteria.</p>\';
endif;
echo json_encode( array(
\'posts\' => json_encode( $wp_query->query_vars ),
\'max_page\' => $wp_query->max_num_pages,
\'found_posts\' => $wp_query->found_posts,
\'content\' => $posts_html
) );
die();
}
(旁注:之所以使用查询帖子,是因为ajax分页与此相结合,但我已经删除了这部分代码,因为我试图保持请求的简单!):)
最合适的回答,由SO网友:HU ist Sebastian 整理而成
是的,所以:首先:你不应该使用query\\u帖子。不,即使需要ajax分页也不行。然而,这不是您当前的问题。
为了能够将“按需价格”属性排序到列表末尾,而不考虑价格排序,只需将“按需价格”信息保存在另一个元字段中即可。需要这样做的原因如下:分页。假设你有20处房产,其中10处是“按需定价”或“0”。当您按从低到高的顺序对价格进行排序时,您的数据库请求将只返回请求时的价格属性,即使有些属性具有价格。
因此,您需要做的是在数据库查询中对它们进行排序。
步骤1:将“按需定价”信息保存在另一个元字段中。让我们称之为“priceonrequest”。我建议在后端使用复选框,但我不知道如何构建元输入,并且复选框元字段可能很棘手,所以假设您使用文本输入。输入0表示“普通”属性,输入1表示“按需定价”属性。
步骤2:抛出meta\\u键属性。meta\\u查询是您想要使用的东西。将函数的上部更改为:
function property_filters(){
//*
// Sort by Args
//*
$args = array(
\'posts_per_page\' => 9,
\'post_status\' => is_user_logged_in() ? array(\'publish\', \'private\') : array(\'publish\'),
\'paged\' => $_POST[\'page\']
);
if(isset($_POST[\'sorty_by\'])){
$sortby = $_POST[\'sort_by\'];
switch($sortby){
case "price-desc":
$ascdesc = \'DESC\';
$meta_query = array(
\'price_on_request\' => array(
\'key\' => \'priceonrequest\',
\'compare\' => \'EXISTS\',
),
\'price\' => array(
\'key\' => \'price\',
\'compare\' => \'EXISTS\',
),
);
$args[\'meta_query\'] = $meta_query;
$args[\'orderby\'] = array(
\'price_on_request\' => \'ASC\',
\'price\' => $ascdesc
);
case "price-asc":
$ascdesc = \'ASC\';
$meta_query = array(
\'price_on_request\' => array(
\'key\' => \'priceonrequest\',
\'compare\' => \'EXISTS\',
\'type\' => \'numeric\',
),
\'price\' => array(
\'key\' => \'price\',
\'compare\' => \'EXISTS\',
\'type\' => \'numeric\',
),
);
$args[\'meta_query\'] = $meta_query;
$args[\'orderby\'] = array(
\'price_on_request\' => \'ASC\',
\'price\' => $ascdesc
);
break;
case "bedrooms-desc":
$ascdesc = \'DESC\';
$meta_query = array(
\'bedrooms\' => array(
\'key\' => \'bedrooms\',
\'compare\' => \'EXISTS\',
\'type\' => \'numeric\',
),
);
$args[\'meta_query\'] = $meta_query;
$args[\'orderby\'] = array(
\'bedrooms\' => $ascdesc
);
break;
case "bedrooms-asc":
$ascdesc = \'ASC\';
$meta_query = array(
\'bedrooms\' => array(
\'key\' => \'bedrooms\',
\'compare\' => \'EXISTS\',
\'type\' => \'numeric\',
),
);
$args[\'meta_query\'] = $meta_query;
$args[\'orderby\'] = array(
\'bedrooms\' => $ascdesc
);
break;
default:
break;
}
}
query_posts( $args );
//...
您的结果将首先按“priceonrequest”字段ASC排序(因此,“Price on Request”属性将是最后一个属性,无论发生什么情况),然后按Price字段排序(现在将很好地排序)。
您可以在此处阅读有关元查询的更多信息:https://developer.wordpress.org/reference/classes/wp_meta_query/
关于这里的订购:https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/
免责声明:我没有测试此代码。从Wordpress 4.2开始就应该可以了,也许我在那里的某个地方输入了错别字。
快乐的编码!