WordPress Dynamic Post filter by custom field
Hi to all,
I have recently developed Dynamic post filter as per category with admin section.
Plugin part:
Step 1: Create folder name: category-filters
Step 2: Create php file name: category-filters.php under category-filters folder
Step 3: Add plugin detail in category-filters.php
<?php /* Plugin Name: Category-filters Plugin URI: https://www.tejasrana.com Description: A filter for post by category using custom field. Author: Tejas Rana Twitter: @tejasrana95 Author URI: https://www.tejasrana.com Version:.1.8.2 License: GPL Copyright: Tejas Rana */
After this add this section. Please read complete code to understand as you are good developer.
class tejasrana_Categoryfilters /** * Holds the values to be used in the fields callbacks */ private $options; /** * Start up */ public function __construct() { add_action( 'admin_menu', array( $this, 'add_plugin_page' ) ); add_action( 'admin_init', array( $this, 'page_init' ) ); } /** * Add options page */ public function add_plugin_page() { // This page will be under "Settings" add_options_page( 'Settings Admin', 'Category wise filters', 'manage_options', 'category-wise-filters', array( $this, 'create_admin_page' ) ); } /** * Options page callback */ public function create_admin_page() { // Set class property $this->options = get_option( 'category_wise_filters' ); ?> <div class="wrap"> <h2>Category Wise filters</h2> <form method="post" action="options.php"> <?php // This prints out all hidden setting fields settings_fields( 'category_filter_group' ); do_settings_sections( 'category_filter_group' ); submit_button(); ?> </form> </div> <?php } /** * Register and add settings */ public function page_init() { register_setting( 'category_filter_group', // Option group 'category_filter_group', // Option name array( $this, 'sanitize' ) // Sanitize ); add_settings_section( 'setting_section_id', // ID 'Category Wise filters', // Title array( $this, 'print_section_info' ), // Callback 'category_filter_group' // Page ); add_settings_field( 'category', // ID 'Category:', // Title array( $this, 'category_id_callback' ), // Callback 'category_filter_group', // Page 'setting_section_id' // Section ); } /** * Sanitize each setting field as needed * * @param array $input Contains all settings fields as array keys */ public function sanitize( $input ) { $new_input = array(); if( isset( $_POST['category_filter'] ) ) $new_input['category_filter'] = ( $_POST['category_filter'] ); return $new_input; } /** * Print the Section text */ public function print_section_info() { print 'Select filters below for category'; } /** * Get the settings option array and print one of its values */ public function category_id_callback() { $cate_args = array( 'orderby' => 'name', 'parent' => 18 ); $parent_category=get_categories($cate_args); ?> <?php $saved_value = get_option( 'category_filter_group' ); $saved_value=$saved_value['category_filter']; foreach($parent_category as $parent_category){ $my_query = new WP_Query('category_name='.$parent_category->name.'&showposts=1'); while ($my_query->have_posts()) : $my_query->the_post(); $random_post_id[]=get_the_ID(); endwhile; $all_fields = get_fields( $random_post_id[0]); $menu_order=array(); foreach($all_fields as $all_field => $all_field_value){ $field_data=get_field_object($all_field ); $menu_order[$all_field] = $field_data["menu_order"]; } //array_multisort($menu_order, SORT_ASC, $all_fields); echo '<strong>'.$parent_category->name.':</strong>'; ?> <table> <?php $i=1; foreach($all_fields as $all_field => $all_field_value){ $field_data=get_field_object($all_field ); if($i==1){ echo '<tr>'; } ?> <td width="300"><label><input type="checkbox" name="category_filter[<?php echo $parent_category->term_id ?>][<?php echo $all_field ?>][field]" value="1" <?php if($saved_value[$parent_category->term_id][$all_field]['field']==1){echo 'checked="checked"';} ?>><?php echo $field_data['label'] ?></label></td> <td width="300"><label><input type="number" name="category_filter[<?php echo $parent_category->term_id ?>][<?php echo $all_field ?>][order]" value="<?php if(isset($saved_value[$parent_category->term_id][$all_field]['order'])){echo $saved_value[$parent_category->term_id][$all_field]['order'];} ?>" style="width:50px;"></label></td> <?php if($i==3){ echo '</tr>'; $i=0; } $i++; } ?> <td><label><input type="checkbox" name="category_filter[<?php echo $parent_category->term_id ?>][sub_category_filter][field]" value="1" <?php if($saved_value[$parent_category->term_id]['sub_category_filter']['field']==1){echo 'checked="checked"';} ?>>Sub Category Selection</label></td> <td width="300"><label><input type="number" name="category_filter[<?php echo $parent_category->term_id ?>][sub_category_filter][order]" value="<?php if(isset($saved_value[$parent_category->term_id]['sub_category_filter']['order'])){echo $saved_value[$parent_category->term_id]['sub_category_filter']['order'];} ?>" style="width:50px;"></label></td> </table> <hr/> <?php } } } if( is_admin() ) $tejasrana_Categoryfilters = new tejasrana_Categoryfilters();
backend part done.
Now move to frontend part:
On frontend:
First of all we need to create a page and assign a template to that page. After we have to write following code in that template.
First we need to get category id:
$cat_id = $cat_id_is->term_id;
After that we need to get one post id for that category so that we can get all custom fields which applied on that post.
$args = array( 'posts_per_page' => -1,//12, 'offset' => 0, 'cat' => $cat_id, 'orderby' => 'date', 'order' => 'DESC', 'post_type' => 'post', 'post_status' => 'publish', ); //$prod_array = get_posts( $prod_list ); $wp_query = new WP_Query($args); $product_ids=array(); if($wp_query->have_posts()) { while ( $wp_query->have_posts() ) : $wp_query->the_post(); $product_ids[]=get_the_ID(); endwhile; }
If we are in sub category then we need parent category:
$get_top_parent= get_top_parent($cat_id);
Now we will fetch all the option for textbox and dropdown:
$saved_value = get_option( 'category_filter_group' ); $saved_values=$saved_value['category_filter']; $saved_values=$saved_values[$get_top_parent]; //end tejas code $saved_values=array_filter($saved_values); $filtered_saved_value=array(); if(!empty($saved_values) && isset($saved_values)){ foreach($saved_values as $saved_key => $saved_value ){ if(!empty($saved_value['order']) && !empty($saved_value['field'])){ $filtered_saved_value[$saved_key]=$saved_value; $menu_order[$saved_key]=$saved_value['order']; } } } array_multisort($menu_order, SORT_ASC, $filtered_saved_value); if(!empty($filtered_saved_value) && isset($filtered_saved_value)){ foreach($filtered_saved_value as $saved_key => $saved_value ){ $field = get_field_object($saved_key,$product_ids[0]); } }
Now we will generate form with dropdown
<div class="filter_box"> <form action="" method="get"> <?php $count_filters=count($filtered_saved_value); if($count_filters>=6){ $class="col-md-2"; } elseif($count_filters==5){ $class="col-md-2"; } elseif($count_filters==4){ $class="col-md-3"; } elseif($count_filters==3){ $class="col-md-4"; } elseif($count_filters==2){ $class="col-md-6"; } elseif($count_filters==1){ $class="col-md-12"; } ?> <div class=""> <?php if(!empty($filtered_saved_value) && isset($filtered_saved_value)){ foreach($filtered_saved_value as $saved_key => $saved_value ){ $field = get_field_object($saved_key,$product_ids[0]); $category_filter_custom=null; if(!empty($field)){ if($field['type']=="text"){ $field_value_texts=array(); foreach($product_ids as $product_id){ $field_value=get_field( $field['name'],$product_id ); if($field_value!=""){ $field_value_texts[$field['name']][]=$field_value; } } $field_value_texts[$field['name']]=array_unique($field_value_texts[$field['name']]); } //check if value has meta tag or not $filter_args = array( 'posts_per_page' => -1,//12, 'offset' => 0, 'cat' => $cat_id, 'orderby' => 'date', 'order' => 'DESC', 'post_type' => 'post', 'post_status' => 'publish', 'meta_query' => array( 'relation' => 'AND', array( 'key' => $field['name'], 'value' => null, 'compare' => '!=', ), ), ); $filter_wp_query = new WP_Query($filter_args); $post_have_meta=false; if($filter_wp_query->have_posts()) { $post_have_meta=true; } } else{ $field['name']=$saved_key; $category_slugs=explode('/', $current_page_url); $category_slug=$category_slugs[count($category_slugs)-2]; $cate_id = get_category_by_slug($category_slug); //print_r($cate_id); $get_child_cat = array( 'type' => 'post', 'child_of' => $cate_id->term_id, 'orderby' => 'id', 'order' => 'ASC', 'taxonomy' => 'category', 'hide_empty' => 0, 'hierarchical' => 0, 'exclude' => array(1,4,10,18), 'pad_counts' => false, 'number' => 3 ); $categories = get_categories( $get_child_cat ); foreach($categories as $single_cat) { $cat_title = $single_cat->name; $split = explode(' ', $cat_title); $last_elem = count($split); $cate_title = $split[$last_elem-1]; $field['choices'][get_category_link($single_cat->term_id)]=$cate_title; } $field['choices'][get_category_link( $cate_id->term_id )]="Browse All"; $field['type']="select"; //current_category $current_category=$category_slugs[count($category_slugs)-1]; $category_filter_custom=$current_category; } ?> <?php if(isset($post_have_meta) && $post_have_meta!="" && !empty($post_have_meta)){ ?> <div class="<?php echo $class ?>"> <select name="<?php echo $field['name'] ?><?php if(empty($category_filter_custom)){ ?>[]<?php } ?>" multiple class="filter_dropdown" id="<?php echo $field['name'] ?>" onchange="this.form.submit()"> <?php $selected_value=array(); if($field['type']=="text"){ foreach($field_value_texts[$field['name']] as $field_value_text){ echo '<option value="'.$field_value_text.'"'; if(isset($_GET[$field['name']])){ if(is_array( $_GET[$field['name']])) { if(in_array($field_select_value, $_GET[$field['name']])) { $selected_value[$_GET[$field['name']][0]]=$field_select_value; echo 'selected'; }elseif($field_select_value==$_GET[$field['name']]){ $selected_value[$_GET[$field['name']][0]]=$field_select_value; echo 'selected'; } } $selected_value[$_GET[$field['name']][0]]=$field_value_text; echo 'selected';} $selected_value[$_GET[$field['name']][0]]=$field_value_text; echo '>'.$field_value_text.'</option>'; } }elseif($field['type']=="select"){ foreach($field['choices'] as $field_select_value=>$field_select_label){ echo '<option value="'.$field_select_value.'" '; if(isset($_GET[$field['name']]) && empty($category_filter_custom)){ if(is_array( $_GET[$field['name']])) { if(in_array($field_select_value, $_GET[$field['name']])) { $selected_value[$_GET[$field['name']][0]]=$field_select_value; echo 'selected'; }elseif($field_select_value==$_GET[$field['name']]){ $selected_value[$_GET[$field['name']][0]]=$field_select_value; echo 'selected'; } } } elseif(!empty($category_filter_custom) && strtolower($field_select_label)==strtolower($category_filter_custom)){ echo 'selected'; } $selected_value[$_GET[$field['name']][0]]=$field_select_value; echo ' >'.$field_select_label.'</option>'; } } ?> </select> <?php if((!isset($_GET[$field['name']]) || empty($_GET[$field['name']])) && empty($category_filter_custom)){ $no_selected_value="no_selected_value"; }else{ $no_selected_value="";} ?> <div class="selected_value <?php echo $no_selected_value; ?>"> <?php if(!empty($category_filter_custom)){ $remove_link_parent=str_replace($category_filter_custom,'',$current_page_url); ?> <div class="selected_value_with_cross"> <?php echo ucfirst($category_filter_custom); ?><a href="<?php echo $remove_link_parent ?>" class="remove_selected_value">x</a> </div> <?php }elseif(!empty($_GET[$field['name']])){ foreach($_GET[$field['name']] as $selected_field){ $remove_link_parent=home_url( $wp->request ); $query_string=urldecode($_SERVER['QUERY_STRING']); $query_string=str_replace($field['name'].'[]='.$selected_field.'&',"",$query_string); ?> <div class="selected_value_with_cross"> <?php echo $field['choices'][$selected_field]; ?><a href="<?php echo $remove_link_parent.'?'.$query_string ?>" class="remove_selected_value">x</a> </div><?php } } ?> </div> </div> <?php } } } ?> <input type="hidden" name="filter" value="filter"> </div> </form> </div>
After that we will generate dynamic wordpress query with meta tag which passed in query string:
wp_reset_query(); $post_per_page=12; $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = array( 'posts_per_page' => $post_per_page,//12, 'offset' => 0, 'cat' => $cat_id, 'orderby' => 'date', 'order' => 'DESC', 'post_type' => 'post', 'post_status' => 'publish', 'paged' => $paged, ); if(@$_GET['filter']=="filter"){ $args['meta_query']['relation']="AND"; foreach($saved_values as $saved_key => $saved_value ){ $field = get_field_object($saved_key,$product_ids[0]); if(@$_GET[$field['name']]!="" && !empty($_GET[$field['name']])){ $args['meta_query'][]=array('key'=> $field['name'],'value'=>$_GET[$field['name']],'compare'=> 'IN',); } } } //$prod_array = get_posts( $prod_list ); $wp_query = new WP_Query($args);
And now finally output generate
if($wp_query->have_posts()) { ?> <div class="row"> <?php //foreach ( $prod_array as $post ) : setup_postdata( $post ); while ( $wp_query->have_posts() ) : $wp_query->the_post(); /* $cat_title = $single_cat->name; $split = explode(' ', $cat_title, 2); $maincate_title = $split[1]; */ $image_path = wp_get_attachment_url( get_post_thumbnail_id() ); /* echo "<br/>".$image_path."<br/>"; echo "<br/>".the_title(); echo "<br/>".$page_title."<br/>"; */ ?> <div class="col-md-3 cat-pro-box"> <div class="cat-img-box"><img src="<?php echo $image_path; ?>" class="img-responsive" /></div> <div class="cat-pro-desc text-center"> <div class="cat-title"><?php echo the_title() ." ". get_field("product_number"); ?></div> <div class="cat-content"><?php echo $parent_page_title; ?></div> <div class="cat-btn-box"><a href="<?php echo the_permalink(); ?>" class="sm-red-btn">Learn More</a></div> </div> </div> <?php //endforeach; endwhile; //wp_reset_postdata(); ?> </div> <?php } ?>