WordPress 3.0 custom queries, post types and taxonomies

There’s been a few really great articles recently published about the new custom posts features in the WordPress 3 Beta, most notably Justin Tadlock’s excellent article and an equally enlightening post on wpengineer.com. I’ve had some fun experimenting a little with the new possibilities opened up to me with this new functionality but I very quickly came up with a problem that took quite a bit of head scratching to solve, namely how to filter my query to a custom post type by taxonomy – akin to displaying all the blog posts within a specific category, I wanted to be able to display all my custom posts in my custom taxonomy (read category).

Using code grabbed from the above articles and the codex I had successfully created a new custom post type. Here’s the code for your functions.php file. As per the codex example, let’s call it ‘books’.

function new_post_type() {
register_post_type( 'books',
array(
'labels' => array(
'name' => __( 'Books' ),
'singular_name' => __( 'Book' )
),
'public' => true,
)
);
}
add_action( 'init', 'new_post_type' );

All of this functionality is clearly explained in either of the articles I mentioned (as well as a more detailed discussion of the various options - the purpose of this article is just to demonstrate how to perform a custom query on a new custom post type with a custom taxonomy.

Right, now I can retrieve my new post type by passing the following parameter to the query. This code should be placed outside of the loop (it’s a loop itself!) in whichever page you’d like it to appear.

<?php
$yell = new WP_Query(array('post_type' => 'books'));
while ($yell->have_posts()) : $yell->the_post();
?>

<h2><?php the_title(); ?></h2>

<?php the_content(); ?>

<?php endwhile; wp_reset_query(); ?>

Now, I want to add a custom taxonomy to my custom post type: I want to do is to be able to categorize books by genre. I can do this by adding the following code to my functions.php file:

function create_book_taxonomies() {
// Add new taxonomy, make it hierarchical (like categories)
$labels = array(
'name' => _x( 'Genres', 'taxonomy general name' ),
'singular_name' => _x( 'Genre', 'taxonomy singular name' ),
'search_items' => __( 'Search Genres' ),
'popular_items' => __( 'Popular Genres' ),
'all_items' => __( 'All Genres' ),
'parent_item' => __( 'Parent Genres' ),
'parent_item_colon' => __( 'Parent Genre' ),
'edit_item' => __( 'Edit Genre' ),
'update_item' => __( 'Update Genre' ),
'add_new_item' => __( 'Add New Genre' ),
'new_item_name' => __( 'New Genre Name' ),
);
register_taxonomy('Genres',array('books'), array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'genres' )
));
}
add_action( 'init', 'create_book_taxonomies', 0 );

Awesome – now I can add a new ‘genre’ to my books – this is akin to adding a new category to your posts. Let’s say that I now add 2 genres: ‘sci fi’ and ‘thriller’. I can now filter my query to query one of my newly created genres.

<?php
$yell = new WP_Query(array('post_type' => 'books', 'genres' => 'sci fi'));
while ($yell->have_posts()) : $yell->the_post();
?>

<h2><?php the_title(); ?></h2>

<?php the_content(); ?>

<?php endwhile; wp_reset_query(); ?>

At the moment it seems that you can’t filter the query further (as you can for posts) by adding an equivalent to:

'category__in' => array(2,6)

Namely:

'genres__in' => array(2,5)

Which seems – to me at least – a real missed opportunity (it never made it into the core, I’m told), but there may yet be some crafty plug-in authors with a work-around. Here’s hoping!

15 thoughts on “WordPress 3.0 custom queries, post types and taxonomies”

  1. Took me a couple of days to find this article. I wonder if I missed the correct search terms with Google, but there seems not to be a lot of info about custom queries from custom post types.

    Thanks for the great post!

  2. Ok, this is also just what I needed. Thanks very much. I am trying to create pagination on a page with excerpts using this. Any suggestion?

  3. Hi Larry, I think pagination should work the same way as with regular posts. At least I don’t see why it wouldn’t!

  4. Can any tell me how to make a site like imdb.com in which all links are cross referenced you can arrange movies by actor, director etc.

    I am searching for this for past 15 days there are lot of articles on Custom Post Types and Taxonmies but after implementing every article I still not able to make because there is no complete article on this!

    Plz help

  5. Thank a lot! I´ve been working with WordPress for a couple of years now, but I´m just getting to know Custom Post and advanced queries, you made it pretty simple so thanks !! Cheers!

  6. Can you write something about multiple post queries?
    I’d like to allow the visitor to “select” a few posts to open in “expanded” view, but I can’t find anything about WP generating permalinks (so they can share them) with multiple posts.

    E.g. to get an url like mysite.com/selection/2,45,98,12,44 which displays those posts? (by id)

    I can imagine a redirect to convert those numbers to something wp understands… like ?p=23, but I don’t know how wp expects a query for multiple posts. I tried ?p=23, 44,55 and it doesn’t work. (wp guesses some post)

    Some light for me to google the rest will be appreciated.

  7. Hi Sergio. You can use

    $query = new WP_Query( array( 'post__in' => array( 1, 2, 3, 4, 5 ) ) );

    to filter a query by post ID. I’m not sure how your site is setup, but if you passed the IDs as get paramaters in the URL you could build your query using those.

    For example: If your URL looked like this: http://richardsweeney.com/?post-id=1,2,3,4,5

    $post_IDs = $_GET['post-id'];
    $post_IDs = explode(',', $post_IDs);
    $query = new WP_Query( array( 'post__in' => $post_IDs) );
    while($query->have_posts()): $query->the_post();
    // Do stuff
    endwhile;
    

    Hope that helps!

  8. This is really great, thanks! However, it seems to be limiting to 6 posts. How can I set it to unlimited? Thanks in advance!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>