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; ?>
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).