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="<?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' => '',
)
)
);
}
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="<?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' => '',
)
)
);
}
Share
Improve this question
edited Jul 21, 2014 at 10:02
norixxx
asked Jul 21, 2014 at 8:24
norixxxnorixxx
3651 gold badge3 silver badges15 bronze badges
13
|
Show 8 more comments
2 Answers
Reset to default 3If 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.
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
query_posts('post_type=portfolio');
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
function query_post_type()
it works, but default posts disappeared... So my guess is I have to separate template... – norixxx Commented Jul 21, 2014 at 8:36photo
", is "photo" a term of the core tag taxonomy or is it a term of you customportfolio_category
taxonomy? – cybmeta Commented Jul 21, 2014 at 9:17photo
is just a tag attached to a post in CPTportfolio
. – norixxx Commented Jul 21, 2014 at 9:35photo
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 Commented Jul 21, 2014 at 9:51portfolio_category-tags.php
. – Bindiya Patoliya Commented Jul 21, 2014 at 9:52