Almost every time I use Custom post types i find myself using a custom taxonomy or two and lately i found the need of filtering the custom post type posts on the admin edit list by these custom taxonomy and since I don't like to write the same code over and over here is a simple class that gets the job done.
Screenshot
The code
<?php if (!class_exists('Tax_CTP_Filter')){ /** * Tax CTP Filter Class * Simple class to add custom taxonomy dropdown to a custom post type admin edit list * @author Ohad Raz <admin@bainternet.info> * @version 0.1 */ class Tax_CTP_Filter { /** * __construct * @author Ohad Raz <admin@bainternet.info> * @since 0.1 * @param array $cpt [description] */ function __construct($cpt = array()){ $this->cpt = $cpt; // Adding a Taxonomy Filter to Admin List for a Custom Post Type add_action( 'restrict_manage_posts', array($this,'my_restrict_manage_posts' )); } /** * my_restrict_manage_posts add the slelect dropdown per taxonomy * @author Ohad Raz <admin@bainternet.info> * @since 0.1 * @return void */ public function my_restrict_manage_posts() { // only display these taxonomy filters on desired custom post_type listings global $typenow; $types = array_keys($this->cpt); if (in_array($typenow, $types)) { // create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list $filters = $this->cpt[$typenow]; foreach ($filters as $tax_slug) { // retrieve the taxonomy object $tax_obj = get_taxonomy($tax_slug); $tax_name = $tax_obj->labels->name; // output html for taxonomy dropdown filter echo "<select name='".strtolower($tax_slug)."' id='".strtolower($tax_slug)."' class='postform'>"; echo "<option value=''>Show All $tax_name</option>"; $this->generate_taxonomy_options($tax_slug,0,0,(isset($_GET[strtolower($tax_slug)])? $_GET[strtolower($tax_slug)] : null)); echo "</select>"; } } } /** * generate_taxonomy_options generate dropdown * @author Ohad Raz <admin@bainternet.info> * @since 0.1 * @param string $tax_slug * @param string $parent * @param integer $level * @param string $selected * @return void */ public function generate_taxonomy_options($tax_slug, $parent = '', $level = 0,$selected = null) { $args = array('show_empty' => 1); if(!is_null($parent)) { $args = array('parent' => $parent); } $terms = get_terms($tax_slug,$args); $tab=''; for($i=0;$i<$level;$i++){ $tab.='--'; } foreach ($terms as $term) { // output each select option line, check against the last $_GET to show the current option selected echo '<option value='. $term->slug, $selected == $term->slug ? ' selected="selected"' : '','>' .$tab. $term->name .' (' . $term->count .')</option>'; $this->generate_taxonomy_options($tax_slug, $term->term_id, $level+1,$selected); } } }//end class }//end if
Usage
Once you have the class in place it's easy to use as a single line of code:
new Tax_CTP_Filter(array('CUSTOM_POST_TYPE_NAME' => array('CUSTOM_TAXONOMY_NAME1','CUSTOM_TAXONOMY_NAME2')));
Now lets break it down: CUSTOM_POST_TYPE_NAME is the name of my custom post type, CUSTOM_TAXONOMY_NAME1 and CUSTOM_TAXONOMY_NAME2 are the name of my custom taxonomies.
So lets say for example i have a custom post type "Book" with a "genre" and "author" taxonomies all i have to do is:
new Tax_CTP_Filter(array('book' => array('genre','author')));
Also if you you can use one instance of the class to add taxonomy filters to multiple post type:
new Tax_CTP_Filter(array( 'book' => array('genre','author'), 'movie' => array('genre','actors'), 'task' => array('task_status'), ));
If you get the idea, enjoy.