Category page only displaying the posts from a custom type

Situation

I have two cpt:

  1. Projects
  2. Works

In these two CPT I share the same taxonomy ‘Category’, and the same terms:

Read More
  1. Architecture
  2. Landscape
  3. Interior Design

I have URLs like

projects/architecture
works/architecture
so on...

Problem

Now the problem is that the two URL above are returning the same content, all the archives of the term architecture, whatever the cpt.

Is there a way that projects/architecture would only return all the post under projects with for term architecture?

Note

I’m using Custom Post Type Permalinks to use permalink formatted like /cpt/term/post_title

Edit

Here is my category template (category.php)

<?php get_header(); ?>
<!-- info about the category -->
<?php
  /* Queue the first post, that way we know
   * what date we're dealing with (if that is the case).
   *
   * We reset this later so we can run the loop
   * properly with a call to rewind_posts().
   */
  if ( have_posts() )
    the_post();
?>

          <h1 class="page-title"><?php
              _e( ucwords($post->post_type), 'boilerplate' );
          ?></h1>
<?php
  /* Since we called the_post() above, we need to
   * rewind the loop back to the beginning that way
   * we can run the loop properly, in full.
   */
  rewind_posts();
  /* Run the loop for the archives page to output the posts.
   * If you want to overload this in a child theme then include a file
   * called loop-archives.php and that will be used instead.
   */
  ?>
  <ul class='large-block-grid-4 small-block-grid-3 listWrap'>
    <?php
   get_template_part( 'loop', 'category' );
   ?>
 </ul>
   <?php
?>

<?php get_footer(); ?>

Here is my category loop (loop-category.php)

<?php while ( have_posts() ) : the_post(); ?>
  <?php
  $attachments = get_posts( array(
    'post_type' => 'attachment',
    'post_parent' => $post->ID,
    'orderby' => 'menu_order',
    'order' => 'ASC',
    'numberposts'     => 1
    ) );
    ?>
    <?php $img = wp_get_attachment_image_src($attachments[0]->ID, 'full');?>
    <li class='listwp equalize'>
      <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>" class='th'>
        <img src='<?php echo $img[0]; ?>'>
        <?php $categories = get_the_terms($post->ID, 'category'); ?>
        <div>
          <span>
            <?php foreach($categories as $category): ?>
            <?php echo $category->name; ?>
          <?php endforeach; ?>
        </span>
      </div>
    </a>
    <h2><?php the_title(); ?></h2>

  </li>
<?php endwhile; ?>

Related posts

Leave a Reply

1 comment

  1. Ok I found a solution by following the recommandation of s_ha_dum to use pre_gets_posts.

    All the following code goes to functions.php

    1 Create a new rewrite rule

    function rewrite_clean()
    {
      // my CPTs
      $types = array('projects', 'works');
      foreach($types as $type)
      {
        add_rewrite_rule('^'.$type.'/([^/]*)/?$', 'index.php?post_type='.$type.'&term=$matches[1]','top');
      }
    }
    
    add_action('init', 'rewrite_clean');
    

    transform the following format

    ?post_type=projects&term=architecture

    to the following format

    projects/architecture

    2 Overwrite the post query

    // check the vars in url and if there is term then only display from this term
    function add_cat_cpt_filter($query)
    {
      if($query->is_archive() && get_query_var( 'term' )  && get_query_var( 'post_type' ))
      {
        // get the id of the category by using the slug
        $id = get_category_by_slug(get_query_var( 'term' ))->term_id;
        if($id){
          // add a filter to the query
          $query->set('cat', $id);
        }
        else{
          // redirect if the term doesn't exist
          wp_redirect( '/'.get_query_var( 'post_type' ));
          exit;
        }
        return;
      }
    }
    add_action( 'pre_get_posts', 'add_cat_cpt_filter' );
    

    The code above will filter the current archive page with the term used in the URL.

    Gotcha

    Then I got an issue due to Custom Post Type Permalinks plugin, it kept displaying a category template while I wanted to keep my CPT archive template and just add a filter on it.

    The solution is simply to disable and reenable the plugin, it did the trick for me.