I'm simply trying to display a list of categorised posts (with the custom post type of 'project') on the default category.php page. I can't get it to work!

If I simply use the base theme category.php template I get a 'No posts available' message as it is looking for standard WP posts with a specified category (and there are none). However once I try and get the template to use my custom post type instead it simply prints a list of ALL the projects - no matter what category they are assigned to.

My current code is as follows:

'post_type' => 'project'
<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
    <h2>Project: <?php the_title(); ?></h2>
    <?php the_content(); ?>    
    <?php endwhile; ?>

The template should 'know' what category it is supposed to be displaying by default. If I'm on www.mysite.co.uk/category/client-x then it should be showing only those projects that have the category 'client x'. I'm sure this can't be too hard!

Any help would be greatly appreciated.



1 Answer 1


Your problem is your use of query_posts(). Don't use query_posts(), ever.

Filter pre_get_posts instead. For example:

function wpse74093_filter_pre_get_posts( $query ) {
    // First, make sure we target only the main query
    if ( is_main_query() ) {
        // Target the category index archive,
        // and only for the category "client-x"
        if ( is_category( 'client-x' ) ) {
            // Set the post-type to "project"
            $query->set( 'post-type', 'project' );
    return $query;
add_action( 'pre_get_posts', 'wpse74093_filter_pre_get_posts' );

I'm assuming the appropriate category term is client-x, based on the category archive index URL in your question. If that's not the right category, replace as appropriate.

  • +1 and as a further explanation to Dan: Yes, category.php should "know" the category in question. Not if you overwrite the main query with query_posts though. Before you do that, it "knows" it. Then you tell it to forget it. Commented Nov 27, 2012 at 17:35
  • 1
    Thanks for the responses @chip-bennet and @johannes-Pille! So I get the impression that query_posts() is not recommended then ;-) One thing I don't really understand is the 'wpse74093_filter_' element of the pre_get_posts() query. Would you mind clarifying what that bit does?
    – Dan Dineen
    Commented Nov 29, 2012 at 15:55
  • 1
    @Dan That's simply a function name. You can make that 'fgoqfohiofiof' for all we care. Crucial to the above is only, that the name of the function in the first line is the same as the callback parameter (2nd paramter) of add_action( 'pre_get_posts', 'fgoqfohiofiof' ). Commented Nov 29, 2012 at 16:23
  • @DanDineen I missed your comment edit. See updated answer. I forgot to declare function there. As Johannes Pille indicated: it's simply a function name, that gets passed as a callback to the add_action() call. The function name itself is arbitrary, but it is important that it 1) Is unique in the namespace, which is the reason for the wpse prefix, and 2) Is identical to the callback name passed to add_action(). Commented Nov 29, 2012 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.