Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate through custom post type by custom taxonomy type? (Ordering wordpress posts by category, or displaying custom post type by taxonomy term)

I want to have a page that shows all posts, separated by category. The idea is to get the categories, and then iterate through all posts for each category. The problem is complicated by the fact that I want to iterate through all posts of a given custom type, using a custom taxonomy as the categories. (Running Wordpress 3)

In my functions.php, my custom post type is registered as "video" and the custom taxonomy as "video_types".

In my custom page template that is supposed to show all videos arranged by category, this is the code that isn't returning any posts (and they're there, I checked):

<?php 
  $categories = get_categories(array(
    'taxonomy' => 'video_types'
  )); 
  foreach ($categories as $cat):
?>
 <section id="<?php $cat->slug ?>" class="video-category">
     <?php
  query_posts(array(
      'cat' => $cat->cat_ID,
      'posts_per_page' => -1
         ));
     ?>
     <h2><?php single_cat_title(); ?></h2>
    <p class="description"><?php echo category_description($cat->cat_ID); ?></p>
  <?php while (have_posts()) : the_post(); ?>
      <?php
       $category = get_the_category(); 
            echo $category[0]->cat_name;
      ?>
      <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
      <article class="video">
        <h3><?php the_title(); ?></h3>
        <p>
          <?php the_content() ?>
        </p>
      </article>
  <?php endwhile; ?>
 </section>
<?php endforeach; ?>
like image 306
Diogenes Avatar asked Oct 03 '10 04:10

Diogenes


People also ask

What is custom post type and taxonomy in WordPress?

A WordPress taxonomy is a way to organize groups of posts and custom post types. The word taxonomy comes from the biological classification method called Linnaean taxonomy. By default, WordPress comes with two taxonomies called categories and tags. You can use them to organize your blog posts.

How do I display custom taxonomy in dropdown WordPress?

Add the following code into the “functions.$tax = get_taxonomy($taxonomy); $selected = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'ids')); $hierarchical = $tax->hierarchical; ?>


2 Answers

Jeez, once you figure out that each item of a custom taxonomy is called a term (not immediately obvious in the wordpress docs for the noob), its all much simpler to search for. This solution is easier to understand without all the custom query stuff.

<?php
// A term is an item of a taxonomy (e.g. "Promotional" could be a term for the taxonomy "video_type")
// ...so $categories could be $terms and it would still make sense
$categories = get_terms('taxonomy_name');
foreach( $categories as $category ):
?>
  <section class="category-<?php echo $category ?>">
    <h2><?php echo $category->name; // Print the cat title ?></h2>
    <p class="description"><?php echo $category->description ?></p>
    <div class="<?php echo $category->post_type ?>-list">
      <?php
      //select posts in this category (term), and of a specified content type (post type) 
      $posts = get_posts(array(
        'post_type' => 'custom_post_type_name',
        'taxonomy' => $category->taxonomy,
        'term' => $category->slug,
        'nopaging' => true, // to show all posts in this category, could also use 'numberposts' => -1 instead
      ));
      foreach($posts as $post): // begin cycle through posts of this category
        setup_postdata($post); //set up post data for use in the loop (enables the_title(), etc without specifying a post ID)
      ?>
        // Now you can do things with the post and display it, like so
        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
          <h3><?php the_title(); ?></h3>
          <?php 
            // Getting custom field data example
            echo get_post_meta($post->ID, 'field_key', true); 
          ?>
          <?php the_content() ?>
        </article>
      <?php endforeach; ?>
    </div>
  </section>
<?php endforeach; ?>

And then any gaps in understanding can be filled by searching the functions above in the wordpress codex. In the above code, for my specific application, custom_post_type_name would be video, and taxonomy_name would be video_type (or video_types, I forget).

like image 79
Diogenes Avatar answered Oct 13 '22 13:10

Diogenes


You might try another approach. Try using get_posts to get your posts sorted by your custom taxonomy, set up a variable that is initially an empty string (called $current_cat or something), and with each loop of the results, check the taxonomy and compare it with $current_cat - if different, print out a header for the new category and then the entry, if the same, print out an entry as usual.

A clear issue with your code (I believe) is that you're not properly querying your custom taxonomy. You should be using simply taxonomy_name => 'value' within your query, a custom taxonomy won't be touched by cat in a query.

Let me know if you need more detail.

edit: More detail!

// get a list of categories, in this case your custom taxonomy (your_taxonomy_name)
$querystr = "SELECT terms.* FROM $wpdb->term_taxonomy tax LEFT JOIN $wpdb->terms terms ON tax.term_id = terms.term_id WHERE tax.taxonomy = 'your_taxonomy_name'";

$categories = $wpdb->get_results($querystr, OBJECT);

foreach( $categories as $category ): // begin a loop through those terms (categories in your custom taxonomy)
    echo '<div class="category-header"><h3>'.$category->name.'</h3>'; // print the cat title
    echo '<p class="category-description">'.strip_tags(term_description($category->term_id,'your_taxonomy_name')).'</p></div>'; // cat description

    $posts = get_posts( array( 'your_taxonomy_name' => $category->name, 'post_type' => 'your_post_type' ) ) //select posts in this category, and of a specified content type
    foreach($posts as $post) : // begin cycle through posts of this category
        setup_postdata($post); //set up post data for use in the loop (enables the_title(), etc without specifying a post ID)

        [ ... ] // do things with your post (display it)

    endforeach;

endforeach;

That should do it - and this may be helpful for using get_posts.

like image 34
Gavin Avatar answered Oct 13 '22 12:10

Gavin