WordPress

How to Group your WordPress Posts in Series

This is a quick post to explain how to group your posts in the form of series. I’ll explain how to use a custom taxonomy to group them as well as how to show all posts belonging to the series.

Introduction

If you like to post more than one post about a subject, in different parts, this is a very useful tip. You can achieve this by using a plugin, as there are several plugins for this purpose, or you can implement this directly into your theme. That’s the path I’m taking here…

Implementation

Open your theme’s functions.php file. First thing we need to do is to register a new custom taxonomy, which we will use to aggregate different posts together.

Custom Taxonomy

function oscardias_series_register() {
	register_taxonomy('series', 'post', array(
		'hierarchical' => false, 'label' => __('Series', 'oscardias'),
		'query_var' => true, 'rewrite' => true));
}
add_action('init', 'oscardias_series_register');

In this code we use the function register_taxonomy to create a new taxonomy called ‘series’. As we are creating our taxonomy with ‘rewrite’ as true, we will need to go to the Permalinks settings and save it again. There is no need to change anything, just save it again. WordPress will refresh it pretty links. The function created (in my case oscardias_series_register()) is added to the init action using the add_action function.

Display Posts in the Series

The next step is display the posts that belong to the same series as the current post. We will display the list of posts after the post’s content.

function oscardias_series_print($content) {
	global $post;

    if(is_single()) {

		$series = get_the_terms($post->ID, 'series');

		if($series) {

			foreach($series as $serie) {

				$series_text = '<p class="previousnote"><strong>' . __('This Post is Part of the ', 'oscardias') .
					'<a href="' . get_term_link($serie, 'series') . '" title="'.$serie->name.'" rel="tag">' . $serie->name . '</a>' .
					__(' Series', 'oscardias').'</strong><br />';

				$posts_array = get_posts(array(
				'tax_query' => array(
					array(
						'taxonomy' => 'series',
						'field' => 'ID',
						'terms' => $serie->term_id
					)
				),
				'order' => 'ASC',
				'orderby' => 'ID'));

				foreach( $posts_array as $entry ) {
					$series_text .= '<a title="'.$entry->post_title.'" href="'.get_permalink( $entry->ID ).'">'.$entry->post_title.'<br />';
				}
				$series_text .= '</p>';

			}

			return $content.$series_text;
		}

    }

	return $content;

}

add_filter('the_content', 'oscardias_series_print');
add_filter('the_content_feed', 'oscardias_series_print');

First thing we need it is to get the $post global, in order to identify which post we are currently dealing with. With this information available, we can check if we are in a single post (using is_single()). If you want to show it everywhere, you won’t need this validation. After that, we get the terms for the current post ID and for the taxonomy we created before. If it returns something, we continue with the logic. Otherwise the function will return the $content without changes.

The $series variable returned by the function get_the_terms is an array of objects. You can have your post attached to as many series as you want. Then, for each of the series we will create a text which to be appended to the post content – this way the series text will appear in the end of the post. First, we add a link to the series taxonomy. Next, we use the get_posts() function to fetch all posts associated to the current series. We do this by using an array with the taxonomy name, the field and the term ID.┬áThe result will be another array, but this time an array of posts. For each entry in this array we create a text with a link to the post.

This is what you can achieve with the solution presented in this tutorial:

Other Posts in the Series Result

Other Posts in the Series Result

Conclusion

This is a simple solution to a common problem. There are several plugins capable of doing the same thing, with different features. Some are hard to customize, that’s why I’m sharing this solution. From this code you can create additional things, like widgets or you can simply use another function to print the series in different places other than the end of the content.