In an earlier tutorial, I demonstrated how to create a taxonomy archive which lists posts by taxonomy term.
This tutorial is similar in that it shows you how to separate out posts in your archives, but it uses a different structure and a different template file. What I'll show you how to do here is to create an archive template for a taxonomy which lists posts by post type.
This might be useful if you have registered a post type which you want to keep separate from normal posts or from another post type, but have a taxonomy which applies to both. For example, if you're listing books and articles as different post types, but will have common topics as your taxonomy (e.g. WordPress!).
In the example I'll use here, I'll work with the 'animals' post type as I did in the previous tutorial, but this time I'll also be working with normal posts. I'll list animals with the queried term first and then I'll list blog posts with that term.
1. Getting Started: Creating the Theme
I'll create a theme which is a child theme of twentyfourteen, so if you're using the source files for this tutorial you'll also need that theme installed in your site. In my theme's stylesheet, I add the following:
/* Theme Name: WPTutsPlus Creating a Taxonomy Archive to List Posts by Post Type Theme URI: http://rachelmccollin.co.uk/wptutsplus-tax-archive-by-post-type/ Description: Theme to support WPTutsPlus tutorial on creating a custom taxonomy archive. Child theme for the Twenty Fourteen theme. Author: Rachel McCollin Author URI: http://rachelmccollin.co.uk/ Template: twentyfourteen Version: 1.0 */ @import url("../twentyfourteen/style.css");
That's all I need to add to create my child theme. If you're using your own theme, you can skip this step.
2. Registering the Post Type and Taxonomy
Note: If you followed my other tutorial about creating a custom post type archive template, you can use the theme you created for that as it uses the same post types and taxonomy. You'll just need to make one tweak which I'll highlight in this section, and add a new template file for the taxonomy archive.
The next step is to register the 'animal' post type and a 'animal family' taxonomy. Create a functions.php
file for your theme and firstly add the function to register the post type:
// register a custom post type called 'animals' function wptp_create_post_type() { $labels = array( 'name' => __( 'Animals' ), 'singular_name' => __( 'animal' ), 'add_new' => __( 'New animal' ), 'add_new_item' => __( 'Add New animal' ), 'edit_item' => __( 'Edit animal' ), 'new_item' => __( 'New animal' ), 'view_item' => __( 'View animal' ), 'search_items' => __( 'Search animals' ), 'not_found' => __( 'No animals Found' ), 'not_found_in_trash' => __( 'No animals found in Trash' ), ); $args = array( 'labels' => $labels, 'has_archive' => true, 'public' => true, 'hierarchical' => false, 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail', 'page-attributes' ), 'taxonomies' => array( 'post_tag', 'category'), ); register_post_type( 'animal', $args ); } add_action( 'init', 'wptp_create_post_type' );
Next below that step, register the aminal family taxonomy.
If you're working with the theme created in the earlier tutorial, you'll need to add array('animal,'post')
to your arguments for the function, intend of just 'animal'
.
// register a taxonomy called 'Animal Family' function wptp_register_taxonomy() { register_taxonomy( 'animal_cat', array( 'animal', 'post' ), array( 'labels' => array( 'name' => 'Animal Families', 'singular_name' => 'Animal Family', 'search_items' => 'Search Animal Families', 'all_items' => 'All Animal Families', 'edit_item' => 'Edit Animal Families', 'update_item' => 'Update Animal Family', 'add_new_item' => 'Add New Animal Family', 'new_item_name' => 'New Animal Family Name', 'menu_name' => 'Animal Family', ), 'hierarchical' => true, 'sort' => true, 'args' => array( 'orderby' => 'term_order' ), 'rewrite' => array( 'slug' => 'animal-family' ), 'show_admin_column' => true ) ); } add_action( 'init', 'wptp_register_taxonomy' );
Save your functions file and you'll find your new post type and taxonomy appear in your site admin.
Now add some data - I've added some animals and posts to the 'Canines' family.
3. Creating the Archive Template
Now create a file called taxonomy-animal_cat.php
. This will be the archive template for the new taxonomy.
Copy the wrapper code from your theme to this file so it has elements and classes in common with the rest of your theme. I'm copying from twentyfourteen - if you're using your own theme, copy from that. Copy everything except the heading and the loop, and add some comments at the top to remind you what this file is for:
<?php /* WpTutsPlus tutorial for creating archive to display posts by taxonomy term Archive template for animal_cat taxonomy */ ?> <?php get_header(); ?> <div id="main-content" class="main-content"> <div id="primary" class="content-area"> <div id="content" class="site-content" role="main"> </div><!-- #content --> </div><!-- #primary --> <?php get_sidebar( 'content' ); ?> </div><!-- #main-content --> <?php get_sidebar(); get_footer();
4. Identifying the Queried Object
So that you can display the name of the term being queried and define your queries in the two loops you'll be creating, you need to identify the queried object and save it as a variable.
Add the following somewhere near the top of your archive template (I'm adding it below the get_header()
call):
<?php // get the currently queried taxonomy term, for use later in the template file $term = get_queried_object(); ?>
You'll be using that in the next step.
5. Outputting the Archive Heading
Before adding your loops, you need to output a heading for your archive page. Inside the opening of the #content
div, add the code below:
<header class="archive-header"> <h1 class="archive-title"> <?php echo $term->name; ?> <?php //post_type_archive_title(); ?> </h1> </header><!-- .archive-header -->
6. The First Loop
Below the heading, you need to add your first loop, using WP_Query
as you'll need to define the arguments.
First define the query:
// Define the query $args = array( 'post_type' => 'animal', 'animal_cat' => $term->slug ); $query = new WP_Query( $args );
Note that this uses the$term
variable you've already defined.
And then add the loop, outputting a link to each animal in an unordered list:
if ($query->have_posts()) { // output the term name in a heading tag echo'<h2>Animals in the ' . $term->name . ' Family</h2>'; // output the post titles in a list echo '<ul>'; // Start the Loop while ( $query->have_posts() ) : $query->the_post(); ?> <li class="animal-listing" id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </li> <?php endwhile; echo '</ul>'; } // end of check for query having posts // use reset postdata to restore orginal query wp_reset_postdata(); ?>
It's important to include two things here:
- A check that the query has posts - you don't want to output a heading with no list beneath it.
-
wp_reset_postdata()
to reset the query - you must always use this withWP_Query
.
7. The Second Loop
The second loop is almost identical to the first loop except for the query arguments:
<?php //second query - posts // Define the query $args = array( 'post_type' => 'post', 'animal_cat' => $term->slug ); $query = new WP_Query( $args ); if ($query->have_posts()) { // output the term name in a heading tag echo'<h2>Blog Posts About the ' . $term->name . ' Family</h2>'; // output the post titles in a list echo '<ul>'; // Start the Loop while ( $query->have_posts() ) : $query->the_post(); ?> <li class="animal-listing" id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </li> <?php endwhile; echo '</ul>'; } // end of check for query having posts // use reset postdata to restore orginal query wp_reset_postdata(); ?>
Now save your template file and preview the archive. You should see two lists, one of animals and the other of posts:
Summary
That's how you create a taxonomy archive to list posts by post type. You could extend this technique to make your archive pages more interesting:
- Varying the loops so that different content is output for each one, for example outputting a featured image or excerpt for some post types.
- Adding different styling for each post type.
- Changing the layout so the archives are side by side or in a grid. You can see and example of a site where I did this at http://type-academy.co.uk/temperament-intro/
- Adapting this technique to category or tag archives by altering your query arguments.
I'm sure you can think of more possibilities!
Comments