用自定义字段做文章多重筛选

文章筛选功能以前写过一个教程wordpress进阶教程(四十):文章筛选功能,通过加多个分类法来实现。

过了这么久,经常有人找我要定制文章筛选功能,现再放出代码使用自定义字段实现,而且用自定义字段实现文章筛选,比用分类法应该更简单,更强大。

以阿树自己建立的一个网站作为例子:游炎陵,这是为了推广家乡旅游建立的。示例页面:http://youyanling.com/destinations

前台效果:通过url传递参数。

01

后台效果:使用自定义字段。范例中使用自己的ashuwp_framework框架添加的自定义字段,都是复选框。

02

 

一、添加自定义字段

添加自定义字段的方法不再赘述,可以使用我们的框架,也可以使用自己的方法添加。

范例网站添加的两个自定义字段的名称分别为:destination_location和destination_season。

自定义字段是复选框,所以值也是固定的,当然可能是字符串也可能是数组。

地域的值可能是center、east、west、south,若多选了,保存的值是数组。

季节的值可能是spring、summer、autumn、winter,若多选了,保存的值四号数组。

二、前台输出筛选地址

筛选列表各个项的url有多种可能:

刚打开页面时,筛选列表的url,只需要一个参数。

西片->http://youyanling.com/destinations?area=west

南片->http://youyanling.com/destinations?area=south

...

春季->http://youyanling.com/destinations?season=spring

夏季->http://youyanling.com/destinations?season=summer

...

若点击了其中一项,比如点击了“西片”之后,此时筛选项目中地域的url不需要改变,但是季节的所有url都需要加上已经选中的area=west。如下

西片->http://youyanling.com/destinations?area=west

南片->http://youyanling.com/destinations?area=south

...

春节->http://youyanling.com/destinations?area=west&season=spring

夏季->http://youyanling.com/destinations?area=west&season=summer

...

同理,两种筛选都点击之后,此时每个筛选项目的url都需要带两个参数,且互相加上对方已经选中的参数。比如点击了“西片”,“春季”两项之后。

西片->http://youyanling.com/destinations?season=spring&area=west

南片->http://youyanling.com/destinations?season=spring&area=south

...

春节->http://youyanling.com/destinations?area=west&season=spring

夏季->http://youyanling.com/destinations?area=west&season=summer

...

而上面这种格式的url都是用add_query_arg函数输出。

用法范例(输出我们需要的带两个参数的url)

  1. <?php
  2. $base = 'http://youyanling.com/destinations';
  3. $params = array(
  4.   'area'=>'west',
  5.   'season'=>'spring',
  6. );
  7. //下面代码将会输出http://youyanling.com/destinations?area=west&season=spring
  8. echo esc_url( add_query_arg( $params, $base ) );
  9. ?>

不管懂没懂,反正前台输出筛选列表得用如下代码(下面代码是范例的真实代码加了注释),在需要出现筛选列表的位置加入如下代码。

  1. <?php
  2. $base = get_post_type_archive_link('destination'); //筛选页面的地址
  3. $area_sort = get_query_var('area'); //从url中获取地域参数
  4. $season_sort = get_query_var('season'); //从url中获取季节参数
  5. //注意,由于本筛选有两个参数,季节和地域,所以要将地域参数让如季节筛选的url中,季节的参数放入地域筛选的url中
  6. //检测获取到的季节参数是否正常
  7. $area_params = array(); //地域的参数数组
  8. if(in_array($season_sort,array('all','spring','summer','autumn','winter'))){
  9.   $area_params['season'] = $season_sort//若季节正常,将季节参数放入地域筛选的url中
  10. }
  11. //检测获取到的地域参数是否正常
  12. $season_params = array(); //季节的参数数组
  13. if(in_array($area_sort,array('all','center','east','west','south'))){
  14.   $season_params['area'] = $area_sort//若地域正常,将地域参数放入季节筛选的url中
  15. }
  16. $selected = 'class="selected"';
  17. ?>
  18. <div class="group clearfix">
  19.   <div class="group_title">位置:</div>
  20.   <div class="list clearfix">
  21.     <?php
  22.     //将地域数组的地域设置为all
  23.     $area_params['area'] = 'all';
  24.     ?>
  25.     <a <?php if($area_sort=='all') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $area_params, $base ) ); ?>">全境</a>
  26.     <?php
  27.     //将地域数组的地域设置为center
  28.     $area_params['area'] = 'center';
  29.     ?>
  30.     <a <?php if($area_sort=='center') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $area_params, $base ) ); ?>">城区周边</a>
  31.     <?php $area_params['area'] = 'west'; ?>
  32.     <a <?php if($area_sort=='west') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $area_params, $base ) ); ?>">西片</a>
  33.     <?php $area_params['area'] = 'south'; ?>
  34.     <a <?php if($area_sort=='south') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $area_params, $base ) ); ?>">南片</a>
  35.     <?php $area_params['area'] = 'east'; ?>
  36.     <a <?php if($area_sort=='east') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $area_params, $base) ); ?>">东片</a>
  37.   </div>
  38. </div>
  39. <div class="group clearfix">
  40.   <div class="group_title">季节:</div>
  41.   <div class="list clearfix">
  42.     <?php $season_params['season'] = 'all';?>
  43.     <a <?php if($season_sort=='all') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $season_params, $base ) ); ?>">全部</a>
  44.     <?php $season_params['season'] = 'spring';?>
  45.     <a <?php if($season_sort=='spring') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $season_params, $base ) ); ?>">春季</a>
  46.     <?php $season_params['season'] = 'summer';?>
  47.     <a <?php if($season_sort=='summer') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $season_params, $base ) ); ?>">夏季</a>
  48.     <?php $season_params['season'] = 'autumn';?>
  49.     <a <?php if($season_sort=='autumn') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $season_params, $base ) ); ?>">秋季</a>
  50.     <?php $season_params['season'] = 'winter';?>
  51.     <a <?php if($season_sort=='winter') echo $selected; ?> href="<?php echo esc_url( add_query_arg( $season_params, $base ) ); ?>">冬季</a>
  52.   </div>
  53. </div>

三、增加可查询变量

前台输出地址和等下后台都要用到从url中获取参数,都使用了get_query_var这个函数,不过这个函数获取参数还需要将你要查询的变量加入到“公共可查询变量中”,这个我也不知道怎么翻译。

 使用如下代码使得area和season两个参数可用(在functions.php文件中加入如下代码)。
  1. function ashu_query_vars($public_query_vars) {
  2.   $public_query_vars[] = 'area';
  3.   $public_query_vars[] = 'season';
  4.   return $public_query_vars;
  5. }
  6. add_action('query_vars', 'ashu_query_vars');

当然,你也可以使用$_GET方法来获取变量。

四、按条件输出文章

有了前面三步,至少在前台显示的url是可以正常工作。

第四步也就是最后一步,让前台的文章输出我们想要的。

要点:1. 使用pre_get_posts钩子来改变文章查询的参数  2. 如何使用自定义字段查询文章。
(在functions.php文件中加入如下代码)
  1. add_action('pre_get_posts','ashuwp_custom_posts_per_page'); //使用pre_get_posts钩子来改变查询文章的参数
  2. function ashuwp_custom_posts_per_page($query){
  3.   //范例中的页面是destination的归档页面,所以使用is_post_type_archive来判断页面
  4.   if(is_post_type_archive('destination') && $query->is_main_query() && !is_admin()){
  5.     $relation = 0//用来计数有几个参数
  6.     $area_sort = get_query_var('area'); //获取地域参数
  7.     $season_sort = get_query_var('season'); //获取季节参数
  8.     $meta_query = array(
  9.       'relation' => 'OR',
  10.     );
  11.     //判断季节是否合法,此处就不需要all了,因为all就是所有
  12.     if(in_array($season_sort,array('spring','summer','autumn','winter'))){
  13.       $meta_query[] = array(
  14.             'key'=>'destination_season', //自定义字段的名称
  15.         'value'=> $season_sort,
  16.         'compare'=>'LIKE', //因为自定义字段值可能保存为数组,所以按字段查询文章时使用LIKE
  17.           );
  18.       $relation++;
  19.     }
  20.     //判断地域是否合法
  21.     if(in_array($area_sort,array('center','east','west','south','center'))){
  22.       $meta_query[] = array(
  23.             'key'=>'destination_location',
  24.         'value'=> $area_sort,
  25.         'compare'=>'LIKE',
  26.           );
  27.       $relation++;
  28.     }
  29.     //如果有两个参数,relation要设置为AND,即两个条件都要满足
  30.     if($relation){
  31.       if($relation==2){
  32.         $meta_query['relation'] = 'AND';
  33.       }
  34.       $query->set('meta_query',$meta_query);
  35.     }
  36.   }
  37. }

END。

本篇教程之前的几篇教程是

本篇教程之后的几篇教程是

没有找到你要找的内容?你可以通过搜索你要找的内容,或者给我们留言。

已有3条评论

  1. 墨城
    墨城 : 回复

    请问这个怎么循环输出内容

  2. 天天
    天天 : 回复

    博主,想问下如果这个要分页的话,是怎么弄

    • 阿树工作室
      阿树工作室 回复天天: 回复

      正常分页即可。

发表评论