在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
相关产品推荐
相关产品推荐

