Table of Contents
Usually the archive pages in WordPress leave a lot to be desired and sometimes you want to list posts by category so users have a much nicer way of interacting with your content so it can be useful to have access to a list posts by category shortcode.
What we’re aiming for is a post listing by category similar to:
While you can modify the archive page template in your theme to have this listing, it would be a lot simpler to just have a list posts by category shortcode that you can use anywhere you want. And that’s what we’re going to build.
Create a new plugin
Creating a new plugin is really straight forward, we just need to create a new file and add these php commets to the top of the file:
<?php /** * Plugin Name: Taxonomy Archive Shortcode * Plugin URI: https://www.cozmoslabs.com * Description: A simple shortcode to list a taxonomy archive and the posts for each term ex: [list_taxonomy_archive cpt="book" tax="genre"] * Version: 1.0 * Author: Cristian Antohe * Author URI: https://www.cozmoslabs.com * License: GPL2 */ /* Copyright 2016 Cristian Antohe This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // Start writing code after this line!
Create a new shortcode
We’ll need code to register a new shortcode: [list_taxonomy_archive]
By default this shortcode will create a listing with all the categories and the posts found inside those categories. However, you can also define a custom taxonomy or custom post type like so: [list_taxonomy_archive cpt=”book” tax=”genre”]
add_shortcode('list_taxonomy_archive', 'wckc_list_taxonomy_archive'); function wckc_list_taxonomy_archive($atts){ $a = shortcode_atts( array( 'cpt' => 'post', 'tax' => 'category', ), $atts ); }
So far our shortcode doesn’t do anything. Next we’ll need to look into querying all the taxonomy terms and the posts that have them assigned.
Query all taxonomy terms and the posts
$terms = get_terms( array('taxonomy' => $a['tax'], 'hide_empty' => false) ); if( $terms ){ $output .= '<div class="list_tax_archive">'; foreach ($terms as $term) { if ( is_array($term) && isset($term['invalid_taxonomy']) ) return; $args = array ( 'post_type' => $a['cpt'], $a['tax'] => $term->slug, 'posts_per_page' => '-1', ); // The Query $posts = get_posts($args); if( empty($posts)){ return; } $output .= "<h4> {$term->name} </h4>"; $output .= '<ul class="term_archive">'; foreach($posts as $post){ $output .= '<li><a href="'.get_permalink( $post ).'">'.get_the_title( $post ).'</a></li>'; } $output .= '</ul>'; } $output .= '</div>'; }
What we’re doing is:
- Get all the terms of our taxonomy using get_terms
- For each term that is assigned to at least 1 post, query for those particular posts using get_posts
The code for the list posts by category shortcode
/* * Create a shortcode that lists all cpt's ordered by taxonomy term */ add_shortcode('list_taxonomy_archive', 'wckc_list_taxonomy_archive'); function wckc_list_taxonomy_archive($atts){ $a = shortcode_atts( array( 'cpt' => 'post', 'tax' => 'category', ), $atts ); $output = ''; $terms = get_terms( array('taxonomy' => $a['tax'], 'hide_empty' => false) ); if( $terms ){ $output .= '<div class="list_tax_archive">'; foreach ($terms as $term) { if ( is_array($term) && isset($term['invalid_taxonomy']) ) return; $args = array ( 'post_type' => $a['cpt'], $a['tax'] => $term->slug, 'posts_per_page' => '-1', ); // The Query $posts = get_posts($args); if( empty($posts)){ return; } $output .= "<h4> {$term->name} </h4>"; $output .= '<ul class="term_archive">'; foreach($posts as $post){ $output .= '<li><a href="'.get_permalink( $post ).'">'.get_the_title( $post ).'</a></li>'; } $output .= '</ul>'; } $output .= '</div>'; } return $output; }
You can also download the List Posts by Category Shortcode plugin below:
Related Articles
WordPress Creation Kit – a sparkling new custom field, taxonomy and post type creator
WordPress Creation Kit consists of three brand new modules that can help you with the tough task of creating and maintaining custom post types, custom taxonomies and most importantly, custom fields and metaboxes for your posts, pages or CPT's. Why another plugin for this? We've actually started working on this more then a year ago, […]
Continue ReadingSwift Templates – a straight forward alternative to WordPress templates hell
I'm not a programmer... I do know some basic html and css, but I was nervous about messing with any of the templates in fear of making a bigger mess than where I started. That's a quote from one of our customers. We hear this quite a lot, not everybody is a developer. Most WordPress […]
Continue ReadingWordPress 4.4 “Clifford” explained
WordPress 4.4 “Clifford” (named for jazz musician Clifford Brown) was released with over 2,000 contributions by 471 contributors. That's the largest number of contributors to a point release by far. Here's the short launch video for this version. As you can see, there are a lot of great things in this release like: REST API […]
Continue Reading
Just what I was looking for! Except, using the default shortcode ([list_taxonomy_archive]) I get all posts under each category. Or, when I try the other option ([list_taxonomy_archive cpt=”book” tax=”genre”]) using a category slug I get nothing. Any thoughts? Thank you!
Hi I tried this php code on wordpress4.9.6 and I can not see it in plu-in how come? …. let you know thanks
Hello,
Open a ticket on our website: https://www.cozmoslabs.com/support/open-ticket/
Regards.
Hi – is it possible to create this code to pick up a particular tag as opposed to catagories?
Thank you!
It already does that. For example, you use the shortcode like so: [list_taxonomy_archive cpt=”book” tax=”genre”]
you can then replace it with
[list_taxonomy_archive cpt=”post” tax=”tag”]
Hi!
Would appreciate any help with this question.
How do I display only specific terms like [list_taxonomy_archive cpt=”book” tax=”genre” myterms=”romance,science-fiction”] ?
Now it loops through all the terms of genre. How do I make it loop only through the terms specified in $a[‘myterms’]?
If anyone needs to do the same:
Managed to do it by using the value from $a[‘myterms’] in
foreach ($a[‘myterms’] as $term)
and extending the post query with
‘tax_query’ => array(
array(
‘taxonomy’ => $a[‘tax’],
‘field’ => ‘slug’,
‘terms’ => $term,
‘operator’ => ‘IN’,
)
)
Thank you for the code. Really helped me in my project!