Add categories to custom post type and display based on categories
Both of the other answers are incorrect, specially the one from the OP. query_posts
should NEVER EVER be used, it is even stated in the codex, so please, read the codex. Also, you should never replace the main query with custom queries.
The solution is simple as I have described below and it is the correct way of doing it.
ORIGINAL ANSWER
You have a couple of flaws here
For your custom post type to have an archive, you need to set the
has_archive
parameter totrue
in your custom post type registration arguments. Seeregister_post_type()
If you are not going to use your custom post type like pages, set the
hierarchical
parameter tofalse
. Setting this to true will considerably slow down your backend as your posts increase as Wordpress will try to build a tree for each post like it does for pagesNever use custom queries in place of the main query. It is always more troublesome and a waste of resources. See this post for a full explanation on where and when to use custom queries correctly.
This point is an extension of the previous one. If you need to change the main query, use
pre_get_posts
to do so. It uses the same exact parameters asWP_Query
as the main query usesWP_Query
to fetch posts. This is all explained in the linked post aboveYour main flaw in your custom query is your lack of understanding what the difference is between categories, tags and custom taxonomies. I have written a complete post ( which you can read here ) on this and actually entered it into the codex as well. You are making use of a custom taxonomy, so the category parameters won't work. You need to use a
tax_query
for custom taxonomies
To solve your issue, follow the following steps
Add the
has_achive
parameter to your arguments when registering your custom post type and set it totrue
. If you want, set thehierarchical
parameter tofalse
as well in your custom post type. (Do not set this for your custom taxonomy, this will make your taxonomy behave like normal tags)After this, flush your rewrite rules by visiting the permalink page under "Settings" and clicking "Update"
Visit your homepage just to make sure your new rules is saved
Delete your custom query and go back to the default loop. Your
archive-work.php
should look like thisif( have_posts() ) { while( have_posts() ) { the_post(); // Your custom markup and template tags }}
If you need to display posts from a specific term, create a
taxonomy.php
,taxonomy-{$taxonomy}.php
ortaxonomy-{$taxonomy}-{$term}.php
template. Check the Template Hierarchy for more info
EDIT 1
If you only need to show a specific term on your custom post type archive term, after you have done the above, use pre_get_posts
to alter the main query the correct way
add_action( 'pre_get_posts', function ( $q ) { if( !is_admin() && $q->is_main_query() && is_post_type_archive( 'work' ) ) { $q->set( 'categories', 'slides' ); }});
EDIT 2
Here is code to solve this
Copy and paste the following code in place of your code where you register your post type. I have added the has_archive
parameter. I have also changed the rewrite rule for your taxonomy to categories
. It is really troublesome to have the same slug for both custom post type and taxonomy. This does not work by default and completely throws everything off target
add_action( 'init', 'work_register' ); function work_register() { $labels = array( 'name' => _x('Work', 'post type general name'), 'singular_name' => _x('Work Item', 'post type singular name'), 'add_new' => _x('Add New', 'work item'), 'add_new_item' => __('Add New Work Item'), 'edit_item' => __('Edit Work Item'), 'new_item' => __('New Work Item'), 'view_item' => __('View Work Item'), 'search_items' => __('Search Work'), 'not_found' => __('Nothing found'), 'not_found_in_trash' => __('Nothing found in Trash'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'menu_icon' => get_stylesheet_directory_uri() . '/article16.png', 'rewrite' => array( 'slug' => 'work', 'with_front'=> false ), 'capability_type' => 'post', 'hierarchical' => true, 'has_archive' => true, 'menu_position' => null, 'supports' => array('title','editor','thumbnail') ); register_post_type( 'work' , $args ); register_taxonomy( 'categories', array('work'), array( 'hierarchical' => true, 'label' => 'Categories', 'singular_label' => 'Category', 'rewrite' => array( 'slug' => 'categories', 'with_front'=> false ) ) ); register_taxonomy_for_object_type( 'categories', 'work' ); // Better be safe than sorry}
In your archive-work.php, replace your custom query with this code
<?php$count = 0;echo '<ul>';while ( have_posts() ) : the_post(); $count++; $class = ($count % 3 == 1) ? 'first' : ''; echo '<li class="'.$class.'">'; echo '<a href="'; the_permalink(); echo '">'; echo '<div class="overlay" style="background-color:'.ot_get_option( 'main_colour' ).';"></div>'; the_post_thumbnail('full'); echo '</a>'; echo '<br />'; echo '<h2><a href="'; the_permalink(); echo '">'; the_title(); echo '</a></h2>'; echo '<div class="entry-content">'; echo limit_words(get_the_excerpt(), '30'); echo '..</div>'; echo '</li>';endwhile;echo '</ul>';?>
VERY IMPORTANT -> OK, now visit Settings >> Permalinks in the back end (admin area) and click Save Changes. This will flush your permalinks and set your new permalink structure
You should now see all your post from your custom post type when you visit
<?phpquery_posts( array( 'post_type' => 'work', 'categories' => 'slides' ) );//the loop start hereif ( have_posts() ) : while ( have_posts() ) : the_post();?><h3><?php the_title(); ?></h3><?php the_content(); ?><?php endwhile; endif; wp_reset_query(); ?>
i finally got it from here perfect
Try with the below code,
<?php $args = array( 'posts_per_page' => 5,'post_type' => 'work','category' => 15 );$myposts = get_posts( $args );foreach ( $myposts as $post ):?><li> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li><?php endforeach; ?>