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');
        $post_type = $post_type;
        $post_type = array('post','portfolio','nav_menu_item');
        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...

$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="<?php echo get_permalink(get_the_ID()); ?>"><?php the_title(); ?></a>
<?php endwhile; // end of the loop.

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.


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() {
        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' => '',
  • When I remove function query_post_type() it works, but default posts disappeared... So my guess is I have to separate template...
    – norixxx
    Jul 21, 2014 at 8:36
  • I don't fully understand what you are trying to get. Do you want a archive of some post types tagged with a term of the core tag taxonomy? or an archive of your custom post type tagged with a term of your custom taxonomy? When you say "when user clicks a tag photo", is "photo" a term of the core tag taxonomy or is it a term of you custom portfolio_category taxonomy?
    – cybmeta
    Jul 21, 2014 at 9:17
  • @cybmeta This has nothing to do with custom taxonomy. Sorry to have you confused by describing custom taxonomy. I just wondered if I can have a tag template for specific CPT. Tag photo is just a tag attached to a post in CPT portfolio.
    – norixxx
    Jul 21, 2014 at 9:35
  • "Just a tag" says little to my question. Is photo from the core tag taxonomy? It is very important to know that. When you register a custom post type, it doesn't support core taonoxmies by default. Can you post the code that register your custom post type and custom taxonomy?
    – cybmeta
    Jul 21, 2014 at 9:51
  • Just try portfolio_category-tags.php. Jul 21, 2014 at 9:52

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.

  • Thanks! I added your code to my function.php and then I just put basic loop in my tag.php. It successfully shows posts under my CPT and excluded posts from standard post. OK now I need a unique template for that. Let's roughly say, if I type something like http://mysite.com/portfolio/tag/photo pulls posts from portfolio CPT.
    – norixxx
    Jul 21, 2014 at 10:42
  • I've edited my answer several times, maybe you missed the information about templates at the end of hte answer.
    – cybmeta
    Jul 21, 2014 at 10:51
  • Yep. I saw edited answer too. But what if I made other tags like paintings, illustration, etc. Do I have to make template every time I add new tags? Can't I just have a single template like tag-{myCPT}.php to cover all?
    – norixxx
    Jul 21, 2014 at 11:26
  • There is no tag-{myCPT} as it is a incorrect approach of taxonomy (tag is a taxonomy). See edited answer. And it is answer your question, please mark it as accepted answer. It has been help, vout it up. Thank you.
    – cybmeta
    Jul 21, 2014 at 12:16
  • 1
    Thanks a lot! Now I fully understand what taxonomy is. My final step was to make portfolio_tag taxonomy which just acts like standard tag taxonomy but exclusively for my CPT portfolio.
    – norixxx
    Jul 21, 2014 at 12:49

Just to add to this since I personally also have a reason to have certain post types excluded from my tag pages.

We have a search bar that retrieves ALL results, but when you click a tag archive link from a blog post, you get blog posts on the tag page and when you click it from another post type you get tagged posts from that post type.

I am actually using a referrer to determine where the person is coming from and then using an if statement to provide options of which post type will be shown based on where they came from in the website.

 query_posts( array( 'post_type' => array('post', 'portfolio') ) );

which shows both normal posts and posts inside portfolio type, or


in my experience if i am searching amazon for a product, i really don't want results containing the keyword in the amazon developers code section, I want a list of products... or in this case post type = product

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.