Australia's Leading Digital Marketing Experts. T. 1300 235 433  |  Aggreagtion Enquires Welcome

Create a Series Reading List with WordPress Shortcode

This article will show you how to include a list of posts in a series based on WordPress tags. An older version of this shortcode included both a series list and related list in the same function. However, because of the perceived attribute confusion and associated complexity we've sensibly split them into two.

A tag, not unlike a social hashtag, can often be unique to tie a specific sub-group of articles together. This article will tie these distinct hashtags into a reading list - not unlike an article split into chapters of a book.

WordPress tags must be the most misunderstood and underutilized feature of WordPress. They should normally be used to tie posts together into a sub-set of associated or connected articles. They're often used, however, in a haphazard way with tagged words that are rarely connected and seldom structured.

Since we don't have any series posts (yet) we'll bundle all the posts tagged with wp_query into a series (in reality the posts are better served by a related reading list). The shortcode of [series tags="108"] returns the following:

  1. Display a List of Child Pages With WordPress ShortcodeMay 28, 2017
  2. Display Future Scheduled Posts in WordPressJune 1, 2017
  3. Display the Total Number of Scheduled, Draft, or Published Posts (or by Author) with WordPress ShortcodeJune 24, 2017
  4. Display Random Posts in WordPressJune 27, 2017
  5. Create a Series Reading List with WordPress ShortcodeJuly 2, 2017
  6. WordPress Post & Page Dropdown MenuJuly 7, 2017

Scheduled (and unlinked) articles may be included in the list with an icon and text indicating their status. Shortcode of [series tags="108" status="publish,future"] returns the following list. The screenshot was taken when most articles were scheduled and, as such, this article shows as both a future article and the current page.

Create a Series Reading List with WordPress Shortcode

WordPress Shortcode

Copy and paste the WordPress function into your theme's functions.php file or, if you sensibly have one installed, your custom functions plugin. You may optionally download and install our plugin from the bottom of of the page.

1
<?php 
2
/*
3
    Display WordPress Post Series
4
    http://www.beliefmedia.com/wordpress-series
5
*/
6
 
7
 
8
function beliefmedia_series_posts($atts) {
9
 
10
  $atts = shortcode_atts(array(
11
    'tags' => false,
12
 
13
    /* Status */
14
    'status' => 'publish',
15
 
16
    /* Future Posts Image */
17
    'image' => '', 
18
    'align' => '-2', 
19
 
20
    /* Optional */
21
    'format' => false, /* jS F Y, g:iA */
22
    'description' => false,
23
    'remove' => false,
24
    'words' => 15,
25
    'number' => false,
26
    'numbered' => true,
27
 
28
    /* Rarely used .. */
29
    'author' => false,
30
    'category' => false,
31
    'orderby' => 'date',
32
    'order' => 'ASC',
33
 
34
    /* Style */
35
    'headingstyle' => false,
36
    'datestyle' => false,
37
    'textstyle' => false,
38
    'currentpagestyle' => false,
39
 
40
    /* Cache */
41
    'cache' => 3600 * 2,
42
 
43
  ), $atts);
44
 
45
 $transient = 'bmfp_' . md5(serialize($atts));
46
 $cachedposts = get_transient($transient);
47
 
48
 if ($cachedposts !== false) {
49
 return $cachedposts;
50
 
51
 } else {
52
 
53
    /* A tag is required.. */
54
    if ($atts['tags'] === false) return '<p><ul><li>No series tag provided.</li></ul></p>';
55
 
56
    global $post;
57
 
58
    /* Current page */
59
    $the_current_page = $post->ID;
60
 
61
    /* If Image empty use a HTML entity */
62
    if ($atts['image'] == '') $atts['clock'] = '&#9202';
63
 
64
    /* If styles aren't defined */
65
    if ($atts['headingstyle'] === false) $atts['headingstyle'] = 'font-weight: bold;';
66
    if ($atts['datestyle'] === false) $atts['datestyle'] = 'font-size: 0.9em;';
67
    if ($atts['textstyle'] === false) $atts['textstyle'] = 'font-size: 0.9em;';
68
    if ($atts['currentpagestyle'] === false) $atts['currentpagestyle'] = 'text-decoration: none; font-weight: normal;';
69
 
70
    /* Generally use this shortcode for series posts */
71
    $post_status = explode(',', $atts['status']);
72
 
73
    $args = array(
74
        'post_type' => 'post',
75
        'post_status' => $post_status,
76
        'orderby' => $atts['orderby'],
77
        'order' => $atts['order'],
78
    );
79
 
80
    /* Get user ID from login username */
81
    if ($atts['author'] !== false) {
82
 
83
      /* Array of authors */
84
      $atts['author'] = explode(',', $atts['author']);
85
 
86
        /* If not numeric, get ID */
87
        foreach ($atts['author'] AS $authors) {
88
          if (!is_numeric($authors)) {
89
            $author_ob = get_user_by( 'login', $authors );
90
            $author .= $author_ob->ID . ',';
91
          } else {
92
            $author .= $authors . ',';
93
          }
94
        }
95
 
96
     /* Return string of authors */
97
     $atts['author'] =  rtrim($author, ',');
98
    }
99
 
100
    /* Limit authors? */
101
    if ($atts['author'] !== false) $args['author'] = $atts['author'];
102
 
103
    /* Specific categories? */
104
    if ($atts['category'] !== false) $args['cat'] = $atts['category'];
105
 
106
    /* Specific tags? */
107
    if ($atts['tags'] !== false) $args['tag_id'] = $atts['tags'];
108
 
109
    /* Limit number of posts? */
110
    $args['posts_per_page'] = ($atts['number'] !== false) ? $atts['number'] : '-1';
111
 
112
    /* Query */
113
    $pages = new WP_query($args);
114
 
115
    /* Build result */
116
    if ( $pages->have_posts() ) :
117
 
118
         while ($pages->have_posts()) : $pages->the_post();
119
 
120
            /* By default your WP time format is used */
121
            $date = ($atts['format'] !== false) ? get_the_date($format = $atts['format']) : get_the_date();
122
 
123
            /* If displaying excerpt */
124
            if ($atts['description'] !== false) $excerpt = trim(str_replace($atts['remove'], '', get_the_excerpt()));
125
 
126
            /* Trim excerpt if required */
127
            if ( ($atts['words'] !== false) && ($atts['description']) ) $excerpt = wp_trim_words($excerpt, $num_words = $atts['words'], $more = null);
128
 
129
            /* The current Post Status */
130
            $poststatus = $pages->post->post_status;
131
 
132
            /* Don't link the current page */
133
            if (get_the_ID() == $the_current_page) {
134
              $output .= '<li><span style="' . $atts['currentpagestyle'] . '">' . get_the_title() . '</span> — <span style="' . $atts['datestyle'] . '">' . $date . '</span>';
135
             } elseif ($poststatus == 'future') {
136
              $output .= '<li><span style="' . $atts['headingstyle'] . '">' . get_the_title() . '</span> — <span style="' . $atts['datestyle'] . '">' . ($image = ($atts['image'] != '') ? '<img src="' . $atts['image'] . '" style="vertical-align: ' . $atts['align'] . 'px">' : $atts['clock']) . ' Scheduled: ' . $date . '</span>';
137
             } elseif ( (get_the_ID() != $the_current_page) && ($poststatus == 'publish') ) {
138
              $output .= '<li><a href="' . get_permalink() . '" title="' . get_the_title() . '"><span style="' . $atts['headingstyle'] . '">' . get_the_title() . '</span></a> — <span style="' . $atts['datestyle'] . '">' . $date . '</span>';
139
             } else {
140
              $output .= '<li><span style="' . $atts['headingstyle'] . '">' . get_the_title() . '</span> — <span style="' . $atts['datestyle'] . '">' . $date . '</span>';
141
            } 
142
 
143
            /* Display excerpt if description required */
144
            if ($atts['description'] !== false) $output .= '<p><span style="' . $atts['textstyle'] . '">' . $excerpt  . '</span></p>';
145
            $output .= '</li>';
146
     
147
        endwhile;
148
        $output = ($atts['numbered'] !== false) ? '<ol>' . $output . '</ol>' : '<ul>' . $output . '</ul>';
149
 
150
        /* Reset query */
151
        wp_reset_postdata();
152
 
153
    else :
154
 
155
        $output = '<p><ul><li>No additional published articles in this series.</li></ul></p>';
156
 
157
    endif;
158
 
159
   /* Set transient data */
160
   set_transient($transient, $output, $atts['cache']);
161
   return $output;
162
  }
163
}
164
add_shortcode('series', 'beliefmedia_series_posts');

If you require shortcode to work in a sidebar widget, you'll have to enable the functionality with a filter. If you're using our custom functions plugin, you'll have that feature enabled by default.

Shortcode Attributes

While there are a quite a few attributes, very few are required other than tags.

tags

The only required attribute is tags. While a comma-delimited list of tags is permitted, it's best-practice to only use a specific tags that will tie your content together.

status

By default the posts returned will have a status of publish. To include future posts (to give readers an indication of the rest of the scheduled series), use status="publish,future".

image

If the image value is empty, we'll use the HTML entity to render a clock (⏲).

align

The align attribute is used to position the image defined above. Use it if the image doesn't center correctly.

description

To render an excerpt under each post, use description="1".

format

After the title we'll print the date. If you want to use anything other than the default WP formatting (defined by you in your control panel), format the date with PHP's date() formatting.

remove

If you're required to remove leading text from the description excerpt, use remove="the text".

words

The excerpt is truncated to 15 words by default. Alter it with words="25".

number

In almost all circumstances you will return the series in a numbered list. To use an unordered list, use number="1".

headingstyle

The headingstyle is the default style applied to your post title. Defaults to font-weight: bold;.

datestyle

The datestyle is the default style applied to your post date. Defaults to font-size: 0.9em;.

textstyle

The textstyle is the default style applied to your post description (excerpt). Defaults to font-size: 0.9em;.

currentpagestyle

The currentpagestyle is the default style applied to the current page title. Defaults to text-decoration: none; font-weight: normal;.

cache

To avoid repeated queries we'll cache the results for 2 hours by default. If you don't plan on regular updates to your series, increase this value.

Considerations

  • Using a textbox or some other means of formatting you can jazz up the result a little.

  • Our blind shortcode will hide the series until clicked. It won't result in the same page-view conversions, but it will clear up the clutter.

[ Click for the WP_Query Series ]

  • While the shortcode can be used to return any number and type of post, this isn't the intended use. Instead, we've built purpose shortcodes to reduce the complexity.

Download

Title: Create a Series Reading List (WP Plugin)
Description: Create a Series Reading List with WordPress Shortcode. Renders a WP series of posts based on tag.
  Download • Version 0.2, 2.6K, zip, Category: WordPress Plugins (General)
WordPress Shortcodes, (1.9K)    

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Leave a comment

READY TO HAVE A CHAT? CALL US ANYTIME ON 1300 235 433