我一直在使用本教程,该教程将分类法过滤器添加到存档中。php和它的工作原理,但输出是一个新的WP查询,与帖子标题相呼应。如何修改函数以使其应用于主查询,而不是创建新查询?是否有此过滤器?我知道pre\\u get\\u帖子,但由于它使用ajax,我不知道如何将其组合在一起。
Html form on archive.php
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<?php
if( $terms = get_terms( array( \'taxonomy\' => \'genre\', \'orderby\' => \'name\' ) ) ) :
echo \'<select name="genrefilter"><option value="">Select category...</option>\';
foreach ( $terms as $term ) :
echo \'<option value="\' . $term->term_id . \'">\' . $term->name . \'</option>\'; // ID of the category as the value of an option
endforeach;
echo \'</select>\';
endif;
?>
<?php
if( $terms = get_terms( array( \'taxonomy\' => \'language\', \'orderby\' => \'name\' ) ) ) :
echo \'<select name="languagefilter"><option value="">Select category...</option>\';
foreach ( $terms as $term ) :
echo \'<option value="\' . $term->term_id . \'">\' . $term->name . \'</option>\'; // ID of the category as the value of an option
endforeach;
echo \'</select>\';
endif;
?>
<input type="text" name="price_min" placeholder="Min price" />
<input type="text" name="price_max" placeholder="Max price" />
<label>
<input type="radio" name="date" value="ASC" checked="checked" /> Date: Ascending
</label>
<label>
<input type="radio" name="date" value="DESC" selected="selected" /> Date: Descending
</label>
<label>
<input type="checkbox" name="featured_image" /> Only posts with featured images
</label>
<button>Apply filter</button>
<input type="hidden" name="action" value="myfilter">
<input type="hidden" name="post_type" value="<?php echo get_post_type();?>">
</form>
<div id="response"></div>
<script>
jQuery(function($){
$(\'#filter\').submit(function(){
var filter = $(\'#filter\');
$.ajax({
url:filter.attr(\'action\'),
data:filter.serialize(), // form data
type:filter.attr(\'method\'), // POST
beforeSend:function(xhr){
filter.find(\'button\').text(\'Processing...\'); // changing the button label
},
success:function(data){
filter.find(\'button\').text(\'Apply filter\'); // changing the button label back
$(\'#response\').html(data); // insert data
}
});
return false;
});
});
</script>
functions.php
add_action(\'wp_ajax_myfilter\', \'misha_filter_function\'); // wp_ajax_{ACTION HERE}
add_action(\'wp_ajax_nopriv_myfilter\', \'misha_filter_function\');
function misha_filter_function(){
$args = array(
\'post_type\' => $_POST[\'post_type\'],
\'orderby\' => \'date\', // we will sort posts by date
\'order\' => $_POST[\'date\'] // ASC or DESC
);
// for taxonomies / categories
if( isset( $_POST[\'genrefilter\'] ) && isset( $_POST[\'languagefilter\'] ) ) {
$args[\'tax_query\'] = array(
\'relation\' => \'AND\',
array(
\'taxonomy\' => \'genre\',
\'field\' => \'id\',
\'terms\' => $_POST[\'genrefilter\']
),
array(
\'taxonomy\' => \'language\',
\'field\' => \'id\',
\'terms\' => $_POST[\'languagefilter\']
),
);
}
// create $args[\'meta_query\'] array if one of the following fields is filled
if( isset( $_POST[\'price_min\'] ) && $_POST[\'price_min\'] || isset( $_POST[\'price_max\'] ) && $_POST[\'price_max\'] || isset( $_POST[\'featured_image\'] ) && $_POST[\'featured_image\'] == \'on\' )
$args[\'meta_query\'] = array( \'relation\'=>\'AND\' ); // AND means that all conditions of meta_query should be true
// if both minimum price and maximum price are specified we will use BETWEEN comparison
if( isset( $_POST[\'price_min\'] ) && $_POST[\'price_min\'] && isset( $_POST[\'price_max\'] ) && $_POST[\'price_max\'] ) {
$args[\'meta_query\'][] = array(
\'key\' => \'_price\',
\'value\' => array( $_POST[\'price_min\'], $_POST[\'price_max\'] ),
\'type\' => \'numeric\',
\'compare\' => \'between\'
);
} else {
// if only min price is set
if( isset( $_POST[\'price_min\'] ) && $_POST[\'price_min\'] )
$args[\'meta_query\'][] = array(
\'key\' => \'_price\',
\'value\' => $_POST[\'price_min\'],
\'type\' => \'numeric\',
\'compare\' => \'>\'
);
// if only max price is set
if( isset( $_POST[\'price_max\'] ) && $_POST[\'price_max\'] )
$args[\'meta_query\'][] = array(
\'key\' => \'_price\',
\'value\' => $_POST[\'price_max\'],
\'type\' => \'numeric\',
\'compare\' => \'<\'
);
}
// if post thumbnail is set
if( isset( $_POST[\'featured_image\'] ) && $_POST[\'featured_image\'] == \'on\' )
$args[\'meta_query\'][] = array(
\'key\' => \'_thumbnail_id\',
\'compare\' => \'EXISTS\'
);
// if you want to use multiple checkboxed, just duplicate the above 5 lines for each checkbox
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo \'<h2>\' . $query->post->post_title . \'</h2>\';
endwhile;
wp_reset_postdata();
else :
echo \'No posts found\';
endif;
die();
}
最合适的回答,由SO网友:Krzysiek Dróżdż 整理而成
如果使用AJAX,则不能修改主查询,因为在AJAX请求期间根本没有创建主查询。
另一方面,使用AJAX执行此搜索表单并不是最好的主意,例如,您无法获取筛选列表的URL。
因此,我将删除AJAX部分并这样做:
<form action="" method="GET" id="filter">
<?php
if( $terms = get_terms( array( \'taxonomy\' => \'genre\', \'orderby\' => \'name\' ) ) ) :
echo \'<select name="genrefilter"><option value="">Select category...</option>\';
foreach ( $terms as $term ) :
echo \'<option value="\' . $term->term_id . \'">\' . $term->name . \'</option>\'; // ID of the category as the value of an option
endforeach;
echo \'</select>\';
endif;
?>
<?php
if( $terms = get_terms( array( \'taxonomy\' => \'language\', \'orderby\' => \'name\' ) ) ) :
echo \'<select name="languagefilter"><option value="">Select category...</option>\';
foreach ( $terms as $term ) :
echo \'<option value="\' . $term->term_id . \'">\' . $term->name . \'</option>\'; // ID of the category as the value of an option
endforeach;
echo \'</select>\';
endif;
?>
<input type="text" name="price_min" placeholder="Min price" />
<input type="text" name="price_max" placeholder="Max price" />
<label>
<input type="radio" name="date" value="ASC" checked="checked" /> Date: Ascending
</label>
<label>
<input type="radio" name="date" value="DESC" selected="selected" /> Date: Descending
</label>
<label>
<input type="checkbox" name="featured_image" /> Only posts with featured images
</label>
<button>Apply filter</button>
<input type="hidden" name="action" value="myfilter">
<input type="hidden" name="post_type" value="<?php echo get_post_type();?>">
</form>
<div id="response">
<?php
if ( have_posts() ) :
while( have_posts() ): the_post();
echo \'<h2>\' . get_the_title() . \'</h2>\';
endwhile;
else :
echo \'No posts found\';
endif;
?>
</div>
在你的功能中。php
add_action( \'pre_get_posts\', function ( $query ) {
if ( ! is_admin() && is_archive() && $query->is_main_query() ) {
// modify the $query according to your needs
if ( isset( $_GET[\'genrefilter\'] ) && isset( $_GET[\'languagefilter\'] ) ) {
$query->set( \'tax_query\', array(
\'relation\' => \'AND\',
array(
\'taxonomy\' => \'genre\',
\'field\' => \'term_id\',
\'terms\' => $_GET[\'genrefilter\']
),
array(
\'taxonomy\' => \'language\',
\'field\' => \'term_id\',
\'terms\' => $_GET[\'languagefilter\']
),
) );
}
}
// put your other filters here
} );
附言:你不应该使用
<?php echo site_url() ?>/wp-admin/admin-ajax.php
. 应该是这样的
<?php echo esc_attr( admin_url( \'admin-ajax.php\' ) ); ?>