I am working on a wordpress site with theme name flozo . It has a custom post type named work
.
I wanted to display the works in my template based on each category.
Here is the code:
<?php
$args = array( 'post_type' => 'work', 'posts_per_page' => 15 );
$loop = new WP_Query( $args );
$count = 0;
echo '<ul>';
while ( $loop->have_posts() ) : $loop->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>';
?>
I've added
$args = array( 'post_type' => 'work', 'tag_ID' => 15 ,'posts_per_page' => 15 );
where 15
is the id of my category, but it didn't work
I've also tried
<?php
$catquery = new WP_Query( 'cat=15&posts_per_page=3' );
while($catquery->have_posts()) : $catquery->the_post();
?>
<ul class="last-cat">
<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_post_thumbnail(); ?> <p><?php the_title(); ?></p><span><?php echo get_the_date(); ?></span></a></li></ul>
<?php endwhile; ?>
which also didn't help.
Edit:
The category url is
The post type registration code is :
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,
'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' => 'work', 'with_front'=> false )));
}
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.
You have a couple of flaws here
For your custom post type to have an archive, you need to set the has_archive
parameter to true
in your custom post type registration arguments. See register_post_type()
If you are not going to use your custom post type like pages, set the hierarchical
parameter to false
. 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 pages
Never 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 as WP_Query
as the main query uses WP_Query
to fetch posts. This is all explained in the linked post above
Your 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 to true
. If you want, set the hierarchical
parameter to false
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 this
if( 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
or taxonomy-{$taxonomy}-{$term}.php
template. Check the Template Hierarchy for more info
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' );
}
});
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