• Can anyone please tell me how can I show multiple CPT by category in archive page. Lets say I have CPT “product” and another CPT “news”. I managed to get the CPT product to list on my archive page but I can’t list news page. I renamed archive-news.php. I tried this code to list my both product and news but it only shows my product page which is on my archive page. It doesn’t show archive-news.php.

    //add multi custom post type to tags and categories
    function add_custom_types_to_tax( $query ) {
    // Return right away if in admin or not working on the main frontend query
    if ( is_admin() || ! $query->is_main_query() ) {
    return;
    }
    
    // Check if we're on a category or tag archive. If so, add our post type
    if( ( $query->is_category() || $query->is_tag() ) ) {
    // Get all your post types
    $post_types = array('post' , 'product' , 'news');
    $query->set( 'post_type', $post_types );
    }
    }
    add_action( 'pre_get_posts', 'add_custom_types_to_tax' );

    My archive page code is:

    <?php
    if ( have_posts() ) :
    the_archive_title( '', false );
    the_archive_description( '<div class="taxonomy-description">', '</div>' );
    
    while ( have_posts() ) : the_post(); ?>
    
    <h3><?php the_title(); ?> </h3>
    
    <?php endwhile;
    
    the_posts_pagination( array(
    'prev_text' => __( '<<', 'twentysixteen' ),
    'next_text' => __( '>>', 'twentysixteen' ),
    'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( '', 'twentysixteen' ) . ' </span>',
    ) );
    
    else :
    get_template_part( 'template-parts/content', 'none' );
    
    endif;
    ?>

Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    The key is the ‘pre_get_posts’ hook. It is expanding the post types queried correctly, but it is only applying this to actual category and tag requests, not any other archive requests. Try changing
    if( ( $query->is_category() || $query->is_tag() ) ) {

    to this:
    if( ( $query->is_archive ) ) {

    This will possibly need further adjustment to screen out other conditions, but any archive pages should now show both post types.

    The real challenge is sorting by category. Category is not an orderby option when using WP_Query, the default query method. Doing so would require a more complex SQL query that I’m unsure how to write. If you can determine how one is written, using the query means completely replacing the WP query with yours using the ‘posts_request’ filter.

    The ‘posts_request’ filter can be added within the conditional in ‘pre_get_posts’ so that it is not applied to other queries.

    A very poor PHP alternative to a custom SQL query is to get all the categories and do a separate query for each category.

    Moderator bcworkz

    (@bcworkz)

    The question of how to sort by categories seems to keep coming up, so I challenged my SQL skills to come up with a functional SQL query for this. I ended up with this:

    //query for all posts, products, & news w/ categories ordered by category name
    global $wpdb;
    $query = $wpdb->get_results( "SELECT * FROM $wpdb->posts AS p
    	LEFT JOIN $wpdb->term_relationships AS r ON (p.ID = r.object_id)
    	INNER JOIN $wpdb->term_taxonomy AS x ON (r.term_taxonomy_id = x.term_taxonomy_id)
    	INNER JOIN $wpdb->terms AS t ON (r.term_taxonomy_id = t.term_id)
    	WHERE p.post_type IN ('post', 'product', 'news') 
    	AND p.post_status = 'publish'
    	AND x.taxonomy = 'category'
    	ORDER BY t.name ASC, p.post_date DESC" 
    );

    Anything without a category will not be returned. Posts with multiple categories will appear once for each category.

    As I mentioned previously, you can use the ‘posts_request’ filter to replace the default query with this one, but only do so under certain conditions.

    Alternately, put this query on a template and run a custom loop to handle the output.

    Thread Starter jklyn

    (@jklyn)

    Thanks bcworkz for your concern. But the problem still remains the same. I can view cpt “Product” but for the cpt “news” it is not showing the content of archive-news.php.

    I’ve also changed as you mentioned.
    if( ( $query->is_archive ) ) {

    At least it should display archive-news.php. It’s just displaying the same page (archive.php). May be my archive page contains error. Just please check it out I’ve pasted as it is on my archive.php. Maybe you could figure out the problem.

    <h2 class="page-title"><?php if ( have_posts() ) : ?><span><?php the_archive_title( '', false ); ?></span> <?php the_archive_description( '<div class="taxonomy-description">', '</div>' ); ?></h2>
    				
    <div class="clear"></div>
    
    <div class="grids_of_3">
    <?php
    // Start the Loop.
    while ( have_posts() ) : the_post();
    ?>
    
    <div class="grid1_of_3">
    <?php
    $id = get_the_id(); //Get Post ID
    $featured_image_id = get_post_meta($id, '_thumbnail_id', 1); //Retrieve the featured image id, having key as _thumbnail_id
    if($featured_image_id !=''){
    $attachment = wp_get_attachment_image_src($featured_image_id, 'medium', false); // it gives array having first parameter source, second parameter width and third parameter height with image sizes: thumbnail, medium, large and full. 
    if(count($attachment) > 0) {
    ?>
    <a href="<?php the_permalink(); ?>"> 
    <img class="img-responsive" src="<?php echo $attachment[0]; ?>" width="<?php echo $attachment[1]; ?>" height="<?php echo $attachment[2]; ?>" />
    <h3><?php the_title(); ?> </h3>
    </a>								
    </div>
    <div class="clearfix"></div>
    <?php
    }
    }
    ?>
    <?php
    // End the loop.
    endwhile;
    // Previous/next page navigation.
    echo"<div style='clear:both'>&nbsp;</div>";
    echo '<div class="clearfix"></div>';
    // Previous/next page navigation.
    the_posts_pagination( array(
    'prev_text'          => __( '<<', 'twentysixteen' ),
    'next_text'          => __( '>>', 'twentysixteen' ),
    'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( '', 'twentysixteen' ) . ' </span>',
    'screen_reader_text'          => __( '&nbsp;', 'twentysixteen' ),
    ) );
    // If no content, include the "No posts found" template.
    else :
    get_template_part( 'template-parts/content', 'none' );
    endif;
    ?
    • This reply was modified 8 years, 2 months ago by jklyn.
    • This reply was modified 8 years, 2 months ago by jklyn.
Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘How to show multiple CPT by category in custom archive page?’ is closed to new replies.