Is it possible to make tag archive page specific to Custom Post Type?

I want to create a tag archive page (or template) specific for some custom post type(CPT).

I am little new to PHP and WordPress, by the way.

In my environment, I have CPT portfolio and custom taxonomy portfolio_category.

I could make default tag archive page using the template tag.php that shows posts with specific tag from all post types. Here’s what I did to my functions.php.

add_filter('pre_get_posts', 'query_post_type');
function query_post_type($query) {
if( is_category() || is_tag() ) {
    $post_type = get_query_var('post_type');
    if($post_type)
        $post_type = $post_type;
    else
        $post_type = array('post','portfolio','nav_menu_item');
        $query->set('post_type',$post_type);
        return $query;
}
}

What I want to do:

For example, when user clicks a tag photo in a single page in CPT(portfolio), I want to serve the page(or template) only shows posts from CPT(portfolio) not from all post types.

I just played around with tag.php a bit, but no luck so far…

Here’s what I thought would work, but not…

<?php
$tag = get_query_var('tag');

$args = array(
    'post_type' => 'portfolio',
    'post_status' => 'publish',
    'posts_per_page' => 3,
    'caller_ get_ posts' => -1, // remove sticky post
    'paged' => $paged,
    'tag' => $tag
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) :

    if ( $my_query->have_posts() ) while ( $my_query->have_posts() ) :  $my_query->the_post(); 
?>
<a href="https://wordpress.stackexchange.com/questions/155252/<?php echo get_permalink(get_the_ID()); ?>"><?php the_title(); ?></a>
<?php endwhile; // end of the loop.
    endif;
wp_reset_query();
?>

This will end up with showing all posts from all post types.

Can anyone help me how to do it?

If this question is redundant, let me know.

Thanks.

My CPT and taxonomy:

// CPT for portfolio
add_action('init', 'regist_cpt');
function regist_cpt() {
    register_post_type('portfolio', array(
        'label' => 'Portfolio',
        'description' => 'My portfolio',
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'capability_type' => 'post',
        'map_meta_cap' => true,
        'hierarchical' => true,
        'taxonomies' => array('post_tag'),
        'rewrite' => array('slug' => 'portfolio', 'with_front' => 1),
        'query_var' => true,
        'has_archive' => true,
        'menu_position' => '5',
        'supports' => array('title','editor','excerpt','trackbacks','custom-fields','comments','revisions','thumbnail','author','page-attributes','post-formats'),
        'labels' => array (
            'name' => 'Portfolio list',
            'singular_name' => 'Portfolio',
            'menu_name' => 'Portfolio',
            'add_new' => 'Add new',
            'add_new_item' => 'Add new item',
            'edit' => 'Edit',
            'edit_item' => 'Edit item',
            'new_item' => 'New item',
            'view' => 'View',
            'view_item' => 'View item',
            'search_items' => 'Search item',
            'not_found' => 'Not found...',
            'not_found_in_trash' => 'Not found in trash',
            'parent' => 'Parent',
        )
    ));
}

// Custom Taxo for portfolio
add_action('init', 'regist_tax');
function regist_tax() {
    register_taxonomy(
        'portfolio_category',
        'portfolio',
        array( 'hierarchical' => true,
            'label' => 'Portfolio Category',
            'show_ui' => true,
            'query_var' => true,
            'rewrite' => array( 'slug' => 'portfolio' ),
            'show_admin_column' => true,
            'labels' => array (
                'search_items' => 'caetgory',
                'popular_items' => 'popular',
                'all_items' => 'all',
                'parent_item' => '',
                'parent_item_colon' => '',
                'edit_item' => '',
                'update_item' => '',
                'add_new_item' => 'Add new item',
                'new_item_name' => 'New item name',
                'separate_items_with_commas' => '',
                'add_or_remove_items' => '',
                'choose_from_most_used' => '',
            )
        )
    ); 
}

2 Answers
2

If I understood correctly, you want a archive template for terms of core tag taxonomy that includes only your portfolio custom post type. The best way is to use the pre_get_posts action hook to set post_type argument of the query to 'portfolio':

add_action('pre_get_posts', 'query_post_type');
function query_post_type($query) {
   //Limit to main query, tag queries and frontend
   if($query->is_main_query() && !is_admin() && $query->is_tag ) {

        $query->set( 'post_type', 'portfolio' );

   }

}

Then, any view of tag archive will include only your custom post type without need of a secondary WP_Query. Then, you can use any of the archive templates to display the results. Obviously, the standard post are not included.

I you want to limit this only for specific tag terms:

add_action('pre_get_posts', 'query_post_type');
function query_post_type($query) {
   //Limit to main query, tag queries and frontend
   if($query->is_main_query() && !is_admin() && $query->is_tag && $query->get('tag') == 'photo' ) {

        $query->set( 'post_type', 'portfolio' );

   }

}

About use specific template for a tag archive based on a custom post type, you can’t do it directly. But uou can use, for example, tag-photo.php as template file for the archive of photo tag. If you need to cover several tags and want to avoid creating several files with the same content, you can use the template_include filter. For example, create “portfolio_archive_template.php” file, put it your theme folder and:

add_filter( 'template_include', 'portfolio_tag_template' );

function portfolio_tag_template( $template ) {
    $portfolio_tag = array( 'photo', 'video' );
    if ( is_tag() && in_array( get_query_var( 'tag' ), $portfolio_tag )  ) {
        $new_template = locate_template( array( 'portfolio_tag_template.php' ) );
        if ( '' != $new_template ) {
            return $new_template ;
        }
    }

    return $template;
}

Anyway, I think what you are trying to do is against the concept of a taxonomy. Why tag a post (of any type) with a taxonomy term but exlude it from the term archive? It is like having “yellow cats” and “yellow dogs” but exclude “yellow dogs” from “yellow animals” archive.

From my point of view is definetly a incorrect approach. Instead, you should use a custom taxonomy associated exclusively with your custom post type; for example the ‘portfolio_category’ taxonomy you have already registered. Then, you can use taxonomy-portfolio_category.php template to customize the output. As portfolio_category is a exclusive taxonomy of portfolio items, you will have the correct archive page you want without any extra code or workarounds.

Leave a Comment