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

在WordPress主题中添加带筛选与搜索功能的新内容类型

实现带筛选和搜索功能的WordPress自定义内容类型

1. 注册自定义内容类型

首先在主题的functions.php中添加代码,注册你需要的自定义内容类型(示例以「产品」为例):

function register_custom_post_type() {
    $args = array(
        'public' => true,
        'label'  => '产品',
        'supports' => array('title', 'editor', 'thumbnail'),
        'has_archive' => true,
        'rewrite' => array('slug' => 'products'),
    );
    register_post_type('product', $args);
}
add_action('init', 'register_custom_post_type');

注册完成后,刷新WordPress后台的「固定链接」设置(设置→固定链接,点击保存),确保归档页能正常访问。

2. 添加筛选所需的分类/自定义字段

注册自定义分类(用于分类筛选)

如果需要按分类筛选,继续在functions.php中添加:

function register_custom_taxonomy() {
    $args = array(
        'hierarchical' => true,
        'public' => true,
        'label' => '产品分类',
        'rewrite' => array('slug' => 'product-category'),
    );
    register_taxonomy('product_category', 'product', $args);
}
add_action('init', 'register_custom_taxonomy');

添加自定义元字段(用于属性筛选,比如价格)

以添加「产品价格」字段为例:

// 添加后台编辑框
function add_product_price_meta_box() {
    add_meta_box(
        'product_price_meta',
        '产品价格',
        'render_product_price_meta_box',
        'product',
        'side',
        'default'
    );
}
add_action('add_meta_boxes', 'add_product_price_meta_box');

// 渲染编辑框内容
function render_product_price_meta_box($post) {
    $price = get_post_meta($post->ID, '_product_price', true);
    ?>
    <input type="number" name="product_price" value="<?php echo esc_attr($price); ?>" placeholder="输入价格">
    <?php
}

// 保存字段数据
function save_product_price_meta($post_id) {
    if (isset($_POST['product_price'])) {
        update_post_meta($post_id, '_product_price', sanitize_text_field($_POST['product_price']));
    }
}
add_action('save_post', 'save_product_price_meta');

3. 实现前端筛选与搜索表单

在自定义内容类型的归档页模板(比如archive-product.php)中添加筛选表单:

<form method="get" action="<?php echo esc_url(get_post_type_archive_link('product')); ?>">
    <!-- 分类筛选下拉框 -->
    <select name="product_category">
        <option value="">所有分类</option>
        <?php
        $categories = get_terms(array(
            'taxonomy' => 'product_category',
            'hide_empty' => true,
        ));
        foreach ($categories as $cat) {
            $selected = (isset($_GET['product_category']) && $_GET['product_category'] == $cat->slug) ? 'selected' : '';
            echo '<option value="' . esc_attr($cat->slug) . '" ' . $selected . '>' . esc_html($cat->name) . '</option>';
        }
        ?>
    </select>

    <!-- 价格区间筛选 -->
    <input type="number" name="min_price" placeholder="最低价格" value="<?php echo isset($_GET['min_price']) ? esc_attr($_GET['min_price']) : ''; ?>">
    <input type="number" name="max_price" placeholder="最高价格" value="<?php echo isset($_GET['max_price']) ? esc_attr($_GET['max_price']) : ''; ?>">

    <!-- 搜索框 -->
    <input type="text" name="s" placeholder="搜索产品" value="<?php echo isset($_GET['s']) ? esc_attr($_GET['s']) : ''; ?>">

    <button type="submit">筛选/搜索</button>
</form>

4. 修改查询逻辑处理筛选参数

在functions.php中添加pre_get_posts动作,根据前端提交的参数修改主查询:

function filter_custom_post_type_query($query) {
    if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
        // 处理分类筛选
        if (isset($_GET['product_category']) && !empty($_GET['product_category'])) {
            $query->set('tax_query', array(
                array(
                    'taxonomy' => 'product_category',
                    'field' => 'slug',
                    'terms' => $_GET['product_category'],
                )
            ));
        }

        // 处理价格区间筛选
        $meta_query = array();
        if (isset($_GET['min_price']) && !empty($_GET['min_price'])) {
            $meta_query[] = array(
                'key' => '_product_price',
                'value' => $_GET['min_price'],
                'type' => 'numeric',
                'compare' => '>=',
            );
        }
        if (isset($_GET['max_price']) && !empty($_GET['max_price'])) {
            $meta_query[] = array(
                'key' => '_product_price',
                'value' => $_GET['max_price'],
                'type' => 'numeric',
                'compare' => '<=',
            );
        }
        if (!empty($meta_query)) {
            $query->set('meta_query', $meta_query);
        }

        // 确保搜索只针对当前自定义内容类型
        if (isset($_GET['s'])) {
            $query->set('post_type', 'product');
        }
    }
}
add_action('pre_get_posts', 'filter_custom_post_type_query');

5. 前端展示筛选后的内容

在archive-product.php中循环展示筛选后的内容:

<?php if (have_posts()) : ?>
    <div class="products-grid">
        <?php while (have_posts()) : the_post(); ?>
            <div class="product-item">
                <?php if (has_post_thumbnail()) : ?>
                    <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('medium'); ?></a>
                <?php endif; ?>
                <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                <p>价格: <?php echo esc_html(get_post_meta(get_the_ID(), '_product_price', true)); ?> 元</p>
                <?php the_excerpt(); ?>
            </div>
        <?php endwhile; ?>
    </div>
    <?php the_posts_navigation(); ?>
<?php else : ?>
    <p>没有找到匹配的产品。</p>
<?php endif; ?>

注意事项

  • 所有输出内容使用esc_*系列函数转义,避免XSS安全漏洞。
  • 如果需要AJAX无刷新筛选,可以基于上述逻辑扩展,添加AJAX处理函数和前端JS代码。
  • 测试前确保已发布若干带分类和价格字段的自定义内容类型条目。

内容的提问来源于stack exchange,提问作者CodeCodeCodon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:01:25