前幾天一網友找我寫一個篩選功能,他要做一個關於房產資訊的網站,希望訪客能在網頁上根據條件篩選符合條件的文章。
根據他的功能要求,我給他的建議是,給每個篩選條件建立自定義分類法。比如他需求是根據四個條件來篩選,省、市、型別、價格。
其次,篩選頁面我還是根據習慣使用了以前的偽靜態方法,使訪問的 url 地址型別為:www.ashuwp.com/sift/、 www.ashuwp.com/sift/0_0_0_0 、 www.ashuwp.com/sift/1_23_33_32/ 後面以下劃線分割的字元,就是我們要篩選的引數,分別為四個分類的 ID 。然後根據這四個 ID 值,來篩選符合條件的文章。最終效果:

要做這種功能,內容較多,文章最後面直接提供一個我已經寫好了此功能的極簡單主題,安裝即可用。
注意:本文內容僅僅在偽靜態狀態下可用,win 主機,不管你偽不偽靜態,,,都勿用。
步驟一:建立自定義分類法。
本教程講述的內容中用到了四個篩選條件:省、市、型別、價格。所以,我就給建立四個自定義分類法 (使用預設的 post) 。使用下述程式碼,你可以直接複製貼上到 functions.php 檔案中。關於自定義分類法,你也可以訪問 WordPress 進階教程 (三): 建立自定義分類法
下列程式碼存放在本教程提供的主題中的 include/taxonomy.php 檔案中
- //給 post 建立四個自定義分類法
- add_action('init', 'ashu_post_type');
- function ashu_post_type() {
- register_taxonomy(
- 'province',
- 'post',
- array(
- 'label' => '省',
- 'rewrite' => array( 'slug' => 'province' ),
- 'hierarchical' => true
- )
- );
- register_taxonomy(
- 'city',
- 'post',
- array(
- 'label' => '市',
- 'rewrite' => array( 'slug' => 'city' ),
- 'hierarchical' => true
- )
- );
- register_taxonomy(
- 'genre',
- 'post',
- array(
- 'label' => '型別',
- 'rewrite' => array( 'slug' => 'genre' ),
- 'hierarchical' => true
- )
- );
- register_taxonomy(
- 'price',
- 'post',
- array(
- 'label' => '價格',
- 'rewrite' => array( 'slug' => 'price' ),
- 'hierarchical' => true
- )
- );
- }
新增完程式碼,應該在後臺文章下面會多出四個自定義分類法:

步驟二:新增篩選預設,重寫規則。
1. 先在主題資料夾下面建立一個 page-sift.php 檔案 (檔名無要求,與下面程式碼中對應即可),這個檔案將作為篩選頁面的模板檔案。
2. 新增重寫規則,使得使用者訪問類似 www.ashuwp.com/sift 、 www.ashuwp.com/sift/0_0_0_0 型別 url 時,不會出現 404,而且能正確載入模板。
關於 WordPress 重寫規則,你也可以訪問 WordPress 進階教程 (16): 新增一個重寫規則,構建新頁面初試
下列程式碼存放在本教程提供的主題中的 include/rewrite.php 檔案中:
- //獲取篩選頁面的 Url
- function ashuwp_sift_link(){
- return home_url()."/sift";
- }
- /*
- *新增 query 變數
- */
- function ashuwp_query_vars($public_query_vars) {
- $public_query_vars[] = 'ashuwp_page';
- $public_query_vars[] = 'condition';
- return $public_query_vars;
- }
- /*
- *sift 頁面的重寫規則, 三種 url:
- *ashuwp.com/sift ashuwp.com/sift/0_0_0_0/ ashuwp.com/sift/0_0_0_0/page/2
- */
- function ashuwp_rewrite_rules( $wp_rewrite ){
- $new_rules = array(
- 'sift/?$' => 'index.php?ashuwp_page=sift',
- 'sift/([^/]+)/?$' => 'index.php?ashuwp_page=sift&condition='.$wp_rewrite->preg_index(1),
- 'sift/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?ashuwp_page=sift&condition='.$wp_rewrite->preg_index(1).'&paged='.$wp_rewrite->preg_index(2)
- );
- $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
- }
- /*
- *載入模板規則
- *用 page-sift.php 作為篩選頁面的模板檔案
- */
- function ashuwp_template_redirect(){
- global $wp,$wp_query,$wp_rewrite;
- if( !isset($wp_query->query_vars['ashuwp_page']) )
- return;
- $reditect_page = $wp_query->query_vars['ashuwp_page'];
- if ($reditect_page == "sift"){
- include(get_template_directory().'/page-sift.php');
- die();
- }
- }
- /*
- *更新重寫規則
- *啟用主題的時候
- */
- function ashuwp_flush_rewrite_rules() {
- global $pagenow, $wp_rewrite;
- if ( 'themes.php' == $pagenow && isset( $_GET['activated'] ) )
- $wp_rewrite->flush_rules();
- }
- add_action( 'load-themes.php', 'ashuwp_flush_rewrite_rules' );
- add_action('generate_rewrite_rules', 'ashuwp_rewrite_rules' );
- add_action('query_vars', 'ashuwp_query_vars');
- add_action("template_redirect", 'ashuwp_template_redirect');
由此,新增完程式碼後,你可以嘗試重新啟用你的主題,看訪問類似 www.ashuwp.com/sift 地址的時候是否會出現 404,如果是空白頁,那就對了,因為我們的篩選頁面模板 page-sift.php 還沒有新增內容,所以是空白頁。
步驟三、篩選頁面模板
前面步驟二中,我們已經為篩選頁面建立了頁面模板 page-sift.php,而且使用 WordPress 的 url 重寫使得我們的篩選 url 能正確載入模板。接下來就要完善篩選頁面的內容。
篩選頁面的內容較多,直接貼出,部分程式碼有註釋。大概思路就是:
1. 先獲取所有分類法的所有分類 ID,有兩個用途:判斷從 url 獲取的分類 ID 是否存在、輸出篩選頁面中篩選條件的 url 。
2. 從 url 中獲取四個 ID 引數。
3. 輸出篩選條件列表。注意判斷當前訪問、以及 「不限」 的條件
4. 根據條件查詢文章。
下面程式碼存在放本教程提供的主題的 page-sift.php 檔案中
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <title> 阿樹工作室--篩選頁面教程</title>
- <link rel='stylesheet' id='ashuwp-style-css' href='<?php echo get_stylesheet_uri(); ?>' type='text/css' media='all' />
- </head>
- <body>
- <div id="site-page">
- <div id="header">
- <h1 id="logo">
- <a href="http://www.treework.cn">treework.cn</a>
- </h1>
- <h2 class="align-cenetr"> 阿樹工作室--篩選頁面教程</h2>
- </div>
- <div class="container content">
- <?php
- //1.1 獲取所有 province 分類, 將 id 放入 $province_id 陣列
- $args = array(
- 'taxonomy'=>'province',
- 'orderby'=>'id',
- 'hide_empty'=>0
- );
- $province_ob = get_categories( $args );
- $province_id = array();
- foreach($province_ob as $province){
- $province_id[] = $province->term_id;
- }
- //1.2 獲取所有 city 分類, 將 id 放入 $city_id 陣列
- $args = array(
- 'taxonomy'=>'city',
- 'orderby'=>'id',
- 'hide_empty'=>0
- );
- $city_ob = get_categories( $args );
- $city_id = array();
- foreach($city_ob as $city){
- $city_id[] = $city->term_id;
- }
- //1.3 獲取所有 genre 分類, 將 id 放入 $genre_id 陣列
- $args = array(
- 'taxonomy'=>'genre',
- 'orderby'=>'id',
- 'hide_empty'=>0
- );
- $genre_ob = get_categories( $args );
- $genre_id = array();
- foreach($genre_ob as $genre){
- $genre_id[] = $genre->term_id;
- }
- //1.4 獲取所有 price 分類, 將 id 放入 $price_id 陣列
- $args = array(
- 'taxonomy'=>'price',
- 'orderby'=>'id',
- 'hide_empty'=>0
- );
- $price_ob = get_categories( $args );
- $price_id = array();
- foreach($price_ob as $price){
- $price_id[] = $price->term_id;
- }
- //2 引數處理
- //2.1 頁碼
- $wp_query->query_vars['paged'] > 1 ? $pagenum = $wp_query->query_vars['paged'] : $pagenum = 1;
- /*2.2 從 url 中獲取引數 即 url 中 0_0_0_0
- *將獲取到的四個引數放入 $cons 陣列中
- */
- global $wp_query;
- if( isset($wp_query->query_vars['condition']) && $wp_query->query_vars['condition']!='' ){
- $condition = $wp_query->query_vars['condition'];
- $conditions = explode('_',$condition);
- $cons = array();
- if(isset($conditions[0])){
- $conditions[0] = (int)$conditions[0];
- }else{
- $conditions[0]=0;
- }
- if(isset($conditions[1])){
- $conditions[1] = (int)$conditions[1];
- }else{
- $conditions[1]=0;
- }
- if(isset($conditions[2])){
- $conditions[2] = (int)$conditions[2];
- }else{
- $conditions[2]=0;
- }
- if(isset($conditions[3])){
- $conditions[3] = (int)$conditions[3];
- }else{
- $conditions[3]=0;
- }
- //從 url 中獲取到的各分類法分類 ID 是否真實存在
- if( in_array($conditions[0],$province_id) ){
- $cons[0]=$conditions[0];
- }else{
- $cons[0]=0;
- }
- if( in_array($conditions[1],$city_id) ){
- $cons[1]=$conditions[1];
- }else{
- $cons[1]=0;
- }
- if( in_array($conditions[2],$genre_id) ){
- $cons[2]=$conditions[2];
- }else{
- $cons[2]=0;
- }
- if( in_array($conditions[3],$price_id) ){
- $cons[3]=$conditions[3];
- }else{
- $cons[3]=0;
- }
- $sift_link = ashuwp_sift_link().'/'.$cons[0].'_'.$cons[1].'_'.$cons[2].'_'.$cons[3];
- }else{
- $cons = array(0,0,0,0);
- $sift_link = ashuwp_sift_link().'/0_0_0_0';
- }
- ?>
- <div class="sift_query">
- <div class="sift_cons">
- <div class="sift_li">
- <span> 省:</span>
- <a <?php if($cons[0]==0){ echo 'class="current"'; } ?> href="<?php echo ashuwp_sift_link(); ?>/0_<?php echo $cons[1];?>_<?php echo $cons[2];?>_<?php echo $cons[3];?>/"> 不限</a>
- <?php
- foreach( $province_ob as $province ){
- ?>
- <a href="<?php echo ashuwp_sift_link(); ?>/<?php echo $province->term_id; ?>_<?php echo $cons[1]; ?>_<?php echo $cons[2]; ?>_<?php echo $cons[3];?>" <?php if($cons[0] == $province->term_id){ echo 'class="current"'; } ?>><?php echo $province->name; ?></a>
- <?php } ?>
- </div>
- <div class="sift_li"><span> 市:</span><a <?php if($cons[1] == 0){ echo 'class="current"'; } ?> href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0];?>_0_<?php echo $cons[2]; ?>_<?php echo $cons[3];?>/"> 不限</a>
- <?php
- foreach( $city_ob as $city ){ ?>
- <a href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0]; ?>_<?php echo $city->term_id; ?>_<?php echo $cons[2]; ?>_<?php echo $cons[3];?>" <?php if($cons[1] == $city->term_id){ echo 'class="current"'; } ?>><?php echo $city->name; ?></a>
- <?php } ?>
- </div>
- <div class="sift_li"><span> 型別:</span><a <?php if($cons[2] == 0){ echo 'class="current"'; } ?> href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0];?>_<?php echo $cons[1]; ?>_0_<?php echo $cons[3];?>/"> 不限</a>
- <?php
- foreach( $genre_ob as $genre ){ ?>
- <a href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0]; ?>_<?php echo $cons[1]; ?>_<?php echo $genre->term_id; ?>_<?php echo $cons[3];?>" <?php if($cons[2] == $genre->term_id){ echo 'class="current"'; } ?>><?php echo $genre->name; ?></a>
- <?php } ?>
- </div>
- <div class="sift_li"><span> 價格:</span><a <?php if($cons[3] == 0){ echo 'class="current"'; } ?> href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0];?>_<?php echo $cons[1]; ?>_<?php echo $cons[2]; ?>_0/"> 不限</a>
- <?php
- foreach( $price_ob as $price ){ ?>
- <a href="<?php echo ashuwp_sift_link(); ?>/<?php echo $cons[0]; ?>_<?php echo $cons[1]; ?>_<?php echo $cons[2]; ?>_<?php echo $price->term_id; ?>" <?php if($cons[3] == $price->term_id){ echo 'class="current"'; } ?>><?php echo $price->name; ?></a>
- <?php } ?>
- </div>
- </div>
- <?php
- //將獲取到的引陣列合為 query_posts 的引數
- $tax_query = array(
- 'relation'=> 'AND',
- );
- //province
- if( $cons[0] != 0 ){
- $tax_query[] = array(
- 'taxonomy'=>'province',
- 'field'=>'id',
- 'terms'=>$cons[0]
- );
- }
- //city
- if( $cons[1] != 0 ){
- $tax_query[] = array(
- 'taxonomy'=>'city',
- 'field'=>'id',
- 'terms'=>$cons[1]
- );
- }
- //genre
- if( $cons[2] != 0 ){
- $tax_query[] = array(
- 'taxonomy'=>'genre',
- 'field'=>'id',
- 'terms'=>$cons[2]
- );
- }
- //price
- if( $cons[3] != 0 ){
- $tax_query[] = array(
- 'taxonomy'=>'price',
- 'field'=>'id',
- 'terms'=>$cons[3]
- );
- }
- $args = array(
- 'paged' => $pagenum,
- 'tax_query'=> $tax_query
- );
- global $ashuwp_query;
- $ashuwp_query = new WP_Query( $args );
- ?>
- <div class="query_count"> 共找到<?php echo $ashuwp_query->found_posts;?> 個符合條件的內容</div>
- </div>
- <?php
- if($ashuwp_query->have_posts()) : ?>
- <div id="post_list">
- <?php while($ashuwp_query->have_posts()) : $ashuwp_query->the_post(); ?>
- <div class="post">
- <a href="<?php the_permalink();?>"><?php the_title();?></a>
- </div>
- <?php endwhile;?>
- </div>
- <?php endif; ?>
- <div id="ashuwp_page">
- <?php
- $pagination = paginate_links( array(
- 'base' => $links.'/page/%#%',
- 'format' => '/page/%#%',
- 'prev_text' => '上一頁',
- 'next_text' => '下一頁',
- 'total' => $ashuwp_query->max_num_pages,
- 'current' => $pagenum
- ) );
- if ( $pagination ) {
- echo $pagination;
- }
- ?>
- </div>
- </div>
- </div><!--site-page-->
- <div id="footer">
- <div class="container">
- <p> 阿樹工作室,聯絡作者 admin@treework.cn</p>
- </div>
- </div>
- </body>
- </html>
檔案下載
下載的檔案為一個極簡單的主題,效果預覽步驟:
1. 下載主題並安裝,並設定好偽靜態
2. 新增幾篇文章到自定義分類法中
3. 直接訪問篩選頁面的 url,比如 www.ashuwp.com/sift 或者 www.ashuwp.com/sift/0_1_1_0 等等。
好了,阿樹只能幫網友們到這了。
阿樹工作室-篩選功能
以下內容為 2016 年 3 月增加:
有網友提到如何修改頁面的標題,這裡給出一個簡單粗暴的範例,如果你需要更自由的修改方式,請參考官閘道器於 wp_title 函式的介紹:
- //修改篩選頁面的標題
- add_filter('wp_title','ashuwp_sift_page_title',10,1);
- function ashuwp_sift_page_title($title){
- global $wp_query;
- //與載入模板的判斷類似
- if( isset($wp_query->query_vars['ashuwp_page']) && $wp_query->query_vars['ashuwp_page']=='sift' ){
- $title = '篩選頁面-阿樹工作室';
- }
- return $title;
- }