You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:24:22