Friday, August 3, 2012

Show all post from custom post type's categories using wp_dropdown_categories() function in Wordpress

Wordpress's custom post type is great way to add content to the site. It gives logical sections to insert different posts instead of using traditional post categories.



In this section, we'll discuss on how to create drop down showing all the categories from a custom post type. And, on selecting particular category from the drop down menu we'll display all the post from that category on the same page. 

Well, I'm not going to use Ajax to display the page. Instead an iframe will work good in our case. You can use Ajax if you want.


First, create a custom post type called 'Projects' and custom taxonomy for 'Projects' called 'Project type'.

1. Copy the code given below inside your functions.php (Alternatively, you can paste the code in a separate file and call inside your functions.php using PHP's include() function. )
<?php


add_action('init', 'projects_init');

  function projects_init() 

  {

  $project_labels = array(

  'name' => _x('Project', 'post type general name'),

  'singular_name' => _x('Project', 'post type singular name'), 

  'all_items' => __('All projects'),

  'add_new' => _x('Add New project', 'director'),

  'add_new_item' => __('Add New project'),

  'edit_item' => __('Edit project'),

  'new_item' => __('New project'),

  'view_item' => __('View projects'),

  'search_items' => __('Search in project'),

  'not_found' =>  __('No project found'),

  'not_found_in_trash' => __('No project found in trash'), 

  'parent_item_colon' => ''

  );

  $args = array(

  'labels' => $project_labels,

  'public' => true,

  'publicly_queryable' => true,

  'show_ui' => true, 

  'query_var' => true,

  'rewrite' => true,

  'capability_type' => 'post',

  'hierarchical' => false,

  'menu_position' => 5,

  'supports' => array('title', 'editor','thumbnail'),

  'has_archive' => 'project'

  ); 

  register_post_type('projects',$args);

  }


add_action( 'init', 'project_type_fx', 0 );


function project_type_fx() {


$project_category = array(

  'name' => _x( 'Project type', 'taxonomy general name' ),

  'singular_name' => _x( 'Project type', 'taxonomy singular name' ),

  'search_items' =>  __( 'Search in project type' ),

  'all_items' => __( 'All project types' ),

  'most_used_items' => null,

  'parent_item' => null,

  'parent_item_colon' => null,

  'edit_item' => __( 'Edit project type' ), 

  'update_item' => __( 'Update project type' ),

  'add_new_item' => __( 'Add new project type' ),

  'new_item_name' => __( 'New project type' ),

  'menu_name' => __( 'Project type' ),

  );

  register_taxonomy('project-type', 'projects',array(

  'hierarchical' => true,

  'labels' => $project_category,

  'show_ui' => true,

  'query_var' => true,

  'rewrite' => array('slug' => 'project-type' )

  ));

  }


?>

This will create a custom post type called project just below the default 'Posts'.



2. Now, add few categories and posts in each custom taxonomies.




3. Add the following code inside your functions.php
class my_Walker_CategoryDropdown extends Walker_CategoryDropdown {

function start_el(&$output, $category, $depth, $args) {
$pad = str_repeat(' ', $depth * 3);

$cat_name = apply_filters('list_cats', $category->name, $category);
$output .= "\t\n";
}
}

The above code will extend the class Walker_categoryDropdown to modify the wp_dropdown_categories() . This will output the value in 'category slug' instead of category id. Well, I tried to get the posts form custom taxonomy using the category id but couldn't do it. The credit for the above code goes to 'numer'. He just saved my day.

4. Create a page template called 'Display Post Iframe' and a page called 'Display Post Iframe'. And, assign 'Display Post Iframe' template to this page. Paste the following code inside 'display-post-iframe.php'.
<?php
  /*
  Template Name: Display Post Iframe
  */
  $loop = new WP_Query( 'project-type='.$_GET['category'].'&post_type=projects' );
  echo '<table>';
  while ( $loop->have_posts() ) : $loop->the_post(); 
  ?>
  <tr>
  <td><?php
  the_time('l, F jS, Y'); ?></td>
  <td><a target="_blank" href="<?php the_permalink(); ?>"><?php the_title(); ?></a></td>
  </tr>
  <?php endwhile;
  echo '</table>';
  wp_reset_query();
?>

3. Create a page called 'Custom Post types' and assign the template what we are going to create in step 6.

6. Create a page template called 'Display posts template'.

Under your theme folder create a file called 'display-posts-template.php'.

and, add the following code to it.
<?php 
  /*
  Template Name: Display posts template
  */
get_header(); ?>
<div id="container">
  <div id="content" role="main">
  <?php
  /* Run the loop to output the page.
  * If you want to overload this in a child theme then include a file
  * called loop-page.php and that will be used instead.
  */
  
  ?>
  <?php 
  $taxonomy     = 'project-type';
  $orderby      = 'name';
  $show_count   = 0;      // 1 for yes, 0 for no
  $pad_counts   = 0;      // 1 for yes, 0 for no
  $hierarchical = 1;      // 1 for yes, 0 for no
  $title        = '';
  $empty        = 0;
$args = array(
  'taxonomy'     => $taxonomy,
  'orderby'      => $orderby,
  'show_count'   => $show_count,
  'pad_counts'   => $pad_counts,
  'hierarchical' => $hierarchical,
  'title_li'     => $title,
  'hide_empty'   => $empty,
  'style'    => 'none',
  'walker' => new my_Walker_CategoryDropdown
  );

wp_dropdown_categories( $args );
?>
  <div style="clear:both;" id="display_taxonomies"></div>
  <script type="text/javascript">
  jQuery('.postform').change(function(){
  var value = jQuery(this).val();
  jQuery("#display_taxonomies").html("<iframe width='850' height='450' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='<?php bloginfo('url'); ?>/display-post-iframe?category="+value+"'></iframe>");
  });
</script>
  <div id="display_taxonomies"></div>
  </div>
  </div>
  </div>
  </div>
  <!-- #content -->
  </div>
  <!-- #container -->
  <?php get_sidebar(); ?>
  <?php get_footer(); ?>
  ?> 

The above code is sending a query via the url to next template. And is extracted using PHP's $_GET variable (see step 5).
The URL will append something like '/display-post-iframe/?category=websites' 

7. Finally, add the following code to header.php to load first category's post by default.

<script type="text/javascript">
jQuery(document).ready(function(){
var select_first = jQuery('.postform:first').val();
jQuery("#display_taxonomies").html("<iframe width='850' height='450' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='<?php bloginfo('url'); ?>/display-post-iframe?category="+select_first+"'></iframe>");
});
</script>

Finally, you will get a drop down of custom taxonomies.
FINAL RESULT
Select any category and the respective post will display under it. Cool! isn't it. I'm displaying only post date and the title. But, it's up-to your imagination to display any  post related data, either custom fields or the content.

Don't forget to share your thoughts!

2 comments:

  1. any chance of an update to this script to see how to do this via ajax?

    I've been trying to learn how to utilize ajax lately, and I'm not quite sure how to modify this script properly

    ReplyDelete
    Replies
    1. Hi sgaffney, you could try jQuery Post. Right now, I don't have any updates on ajax version. If you have any update please share it here.

      Delete