WordPress同页实现厨房列表按分类与搜索关键词筛选
问题诊断
- 表单未阻止默认提交事件,点击提交会触发原生页面跳转,走WordPress默认搜索路由,所以会跳到其他页面只显示文章标题
- 仅定义了AJAX的本地化函数,未注册对应前端JS、未编写AJAX请求处理逻辑,筛选功能没有实际生效
wp_dropdown_categories()参数中name设为空,后端无法接收到分类筛选参数- 自定义查询
$args数组语法错误,混入了变量赋值语句,且未对接筛选参数做条件过滤 - 列表渲染逻辑没有做复用封装,AJAX请求无法返回和初始页结构一致的内容
完整实现方案
1. 替换主题functions.php中的相关代码
把原来的AJAX筛选相关代码替换成下面的内容,包含JS注册、AJAX接口、表单渲染、列表渲染复用逻辑:
add_image_size('header-image', 1200, 360, true); add_action('wp_enqueue_scripts', function () { wp_dequeue_style('bootstrap4'); wp_dequeue_style('bootstrap-basic4-main'); wp_enqueue_style('webfont-roboto', get_stylesheet_directory_uri() . '/webfont/roboto/stylesheet.css'); wp_enqueue_style('nelga-bootstrap', get_stylesheet_directory_uri() . '/assets/css/bootstrap.css'); wp_enqueue_style('font-lato', get_stylesheet_directory_uri() . '/assets/fonts/stylesheet.css'); wp_enqueue_script('nelga-block-map', get_stylesheet_directory_uri() . '/block/interactive-map/map.js'); // 注册筛选功能JS,依赖jQuery wp_enqueue_script('my_ajax_filter_search', get_stylesheet_directory_uri() . '/assets/js/ajax-filter.js', ['jquery'], '1.0', true); wp_localize_script('my_ajax_filter_search', 'ajax_url', admin_url('admin-ajax.php')); }, 11); add_action('wp_enqueue_scripts', function () { wp_dequeue_style('wpuf-css'); wp_register_style('wpuf-css', WPUF_ASSET_URI . '/css/frontend-forms.css'); }); add_action('init', function () { register_block_type(__DIR__ . '/block/icon-with-text'); register_block_type(__DIR__ . '/block/interactive-map'); }); // 抽离厨房列表渲染逻辑,初始加载和AJAX返回复用 function render_kitchen_list($cat_id = 0, $search_keyword = ''){ ob_start(); // 构建查询参数 $args = [ 'post_type' => 'kitchen', 'post_status' => 'publish', 'posts_per_page' => -1, ]; // 分类筛选 if($cat_id > 0){ $args['cat'] = $cat_id; } // 关键词搜索 if(!empty($search_keyword)){ $args['s'] = sanitize_text_field($search_keyword); } $the_query = new WP_Query($args); ?> <div class="container"> <div class="row card-kitchens-title"> <h3>Top Küchen</h3> </div> <div class="row card-kitchens"> <?php if ($the_query->have_posts()) : ?> <?php while ($the_query->have_posts()) : $the_query->the_post(); $postID = get_the_ID(); ?> <?php if (get_field('featured', $postID)) : ?> <div class="col-sm-4"> <a class="card" href="<?php echo get_permalink(); ?>"> <?php if (has_post_thumbnail()) { the_post_thumbnail(); } ?> <?php if (get_field('price', $postID)) : ?> <p class="price1"><?php the_field('price', $postID); ?></p> <?php endif; ?> <div class="card-body"> <h2 class="card-title"><?php the_title(); ?></h2> <p class="card-text"><?php the_field('state', $postID); ?></p> </div> </a> </div> <?php endif; ?> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php else : ?> <p><?php _e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?> </div> </div> <div class="container"> <div class="row card-kitchens-title"> <h3>Empfohlene Küchen</h3> </div> </div> <div class="container p-0"> <div class="row second-box"> <?php if ($the_query->have_posts()) : ?> <?php while ($the_query->have_posts()) : $the_query->the_post(); $postID = get_the_ID(); ?> <div class="col-sm-3 cards pb-4"> <a class="card" href="<?php echo get_permalink(); ?>"> <?php if (has_post_thumbnail()) { the_post_thumbnail(); } ?> <?php if (get_field('price', $postID)) : ?> <p class="price"><?php the_field('price', $postID); ?></p> <?php endif; ?> <div class="card-body"> <h2 class="card-title"><?php the_title(); ?></h2> <p class="card-text"><?php the_field('state', $postID); ?></p> </div> </a> </div> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php else : ?> <p><?php _e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?> </div> </div> <?php return ob_get_clean(); } // 筛选表单短代码 function my_ajax_filter_search_shortcode(){ ob_start(); ?> <div id="my-ajax-filter-search" class="filter"> <div class="container p-0"> <form id="kitchen-filter-form"> <div class="d-inline-flex mb-2 mb-lg-0"> <div class="position-relative first-input"> <svg class="position-absolute" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve"> <style type="text/css"> .st0 { fill: none; stroke: #3C3C3C; stroke-width: 2; stroke-miterlimit: 10; } .st1 { fill: none; stroke: #3C3C3C; stroke-width: 2; stroke-miterlimit: 9.9999; } </style> <g> <circle class="st0" cx="21" cy="21" r="20" /> <line class="st0" x1="35" y1="35" x2="41" y2="41" /> <rect x="46.3" y="37.1" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -20.9172 50.5006)" class="st1" width="8.5" height="26.9" /> </g> </svg> <label class="screen-reader-text" for="s">Search for:</label> <input value="<?php echo isset($_GET['s']) ? esc_attr($_GET['s']) : ''; ?>" name="s" id="s" class="form-control " placeholder="Diese Kuche such ich .."> </div> <?php wp_dropdown_categories( array( 'show_option_all' => 'All Kategorien', 'orderby' => 'id', 'order' => 'ASC', 'hide_empty' => 0, 'echo' => 1, 'selected' => isset($_GET['cat']) ? intval($_GET['cat']) : 0, 'hierarchical' => 0, 'name' => 'cat', 'id' => 'custom-cat-drop', 'class' => 'form-select', 'depth' => 0, 'taxonomy' => 'category', 'hide_if_empty' => false, 'value_field' => 'term_id', ) ); ?> </div> <select class="form-select" name="state"> <option value="" selected>Ganzer Ort</option> <option value="Ganzer Ort1">Ganzer Ort1</option> <option value="Ganzer Ort2">Ganzer Ort2</option> </select> <div class="d-inline-flex mb-2 mb-lg-0 ml-lg-3"> <input type="submit" id="searchsubmit" class="btn" name="submit" value="Jetzt Kuche finden"> </div> </form> </div> </div> <?php return ob_get_clean(); } add_shortcode('my_ajax_filter_search', 'my_ajax_filter_search_shortcode'); // AJAX处理逻辑 function ajax_kitchen_filter(){ $cat_id = isset($_POST['cat']) ? intval($_POST['cat']) : 0; $search_keyword = isset($_POST['s']) ? sanitize_text_field($_POST['s']) : ''; echo render_kitchen_list($cat_id, $search_keyword); wp_die(); } add_action('wp_ajax_kitchen_filter', 'ajax_kitchen_filter'); add_action('wp_ajax_nopriv_kitchen_filter', 'ajax_kitchen_filter'); add_filter('doing_it_wrong_trigger_error', function () { return false; }, 10, 0);
2. 替换页面模板中的列表代码
原来写自定义查询的模板部分,直接替换成下面的代码,默认加载全部分类内容:
// 输出筛选表单 echo do_shortcode('[my_ajax_filter_search]'); // 列表容器,AJAX返回内容直接替换这个容器里的内容 echo '<div id="kitchen-list-wrapper">'; echo render_kitchen_list(0, ''); echo '</div>';
3. 新建前端JS文件
在主题目录下新建assets/js/ajax-filter.js文件,写入下面的逻辑,拦截表单提交,发送AJAX请求无刷新替换列表:
jQuery(function($){ $('#kitchen-filter-form').on('submit', function(e){ // 阻止表单默认提交跳转行为 e.preventDefault(); const formData = $(this).serialize(); $.ajax({ url: ajax_url, type: 'POST', data: formData + '&action=kitchen_filter', beforeSend: function(){ $('#searchsubmit').prop('disabled', true).val('加载中...'); }, success: function(res){ // 替换列表内容 $('#kitchen-list-wrapper').html(res); }, complete: function(){ $('#searchsubmit').prop('disabled', false).val('Jetzt Kuche finden'); } }) }) // 可选:分类下拉框选中后自动触发筛选,不用点提交按钮 $('#custom-cat-drop').on('change', function(){ $('#kitchen-filter-form').trigger('submit'); }) })
效果验证
- 页面初始加载默认显示全部分类下所有厨房内容
- 选择分类、输入搜索词点击提交后,页面不会跳转,直接局部刷新列表内容,只展示匹配筛选条件的结果
- 列表结构和初始加载完全一致,不会出现只显示标题的问题
内容的提问来源于stack exchange,提问作者marwa
相关产品推荐
相关产品推荐

