Building a WordPress Series Plugin: Risky Business

By Sol in Lab

What is the best way to organize entries in a series? I’ve been turning this question around in my head (and in my notes) for a while now. Each option has their merits as well as some very real pitfalls. In one moment, the answer seems clear and obvious and in the next, the very same answer seems absurd.

Option 1: Entries are Posts

The Rundown

Currently, entries are standard posts. Ultimately, options would be used allow the user to select which post types can be part of a series.

URI Structure

  • Series: site.com/series/series-name/
  • Entry: site.com/post-name/ (based on the site’s permalink settings)

Entry Management

  • Existing management page for the entry’s post type
  • Custom UI for listing/managing entries of a series

Good News

Flexibility

Flexibility is the star quarterback when any post type can be a series entry. Entries can be easily selected from existing and new content alike.

Series content could be as varied as the custom post types that are defined on your site. An image gallery here, a podcast there, and finish it off with a normal post! Anything is possible!

Bad News

Of course, there are some downsides to using any old post type as series entries.

Organization

Organization definitely suffers in this option. For example, our series about “Awesome Things” may have a URI such as:

site.com/series/awesome-things/

However, the URI of each entry in this series will be completely unrelated. For example, the URI for the “Kittens” entry would be:

site.com/kittens/

There’s no connection between the URI for a series and the URIs of its entries.

This is just one example of an organizational issue I refer to as Weak Links. In addition to URIs, an entry’s slug, taxonomies (e.g. tags, categories, etc.), etc. have no connection to the series it is part of. In fact, the only connection entries have to a series is a simple metadata value indicating the entry’s series.

Of course, there are ways to work around this. For example, we can prefix entry slugs with the series’ slug (manually or automatically). It’ll do, but it’s not ideal.

Simply wrangling all of a series’ entries could be an issue as well. Each post type in WordPress has it’s own admin page, so entries for a single series could be strewn about in multiple admin sections. Though this plugin will have its own UI for managing a series’ entries, the fact that an entry is accessible in multiple places in the admin creates a real management issue.

Metadata

Since any post type can be an entry in a series, there is also no good way to implement fields for entry-specific metadata on the post editor, making it difficult to identify specific entries within the context of a series. It would be pretty straightforward to display entry-specific fields once a post has been added to a series, but that would create an inconsistency between when a post is first assigned to a series (no entry-specific fields) and after that post is saved (entry-specific fields displayed).

Option 2: Entries are a Custom Post Type

The Rundown

Entries are fully-fledged custom post types in this scenario, just like the series that they belong to.

URI Structure

  • Series: site.com/series/series-name/
  • Entry: series-uri/entry-name (e.g. site.com/series/series-name/entry-name)

Entry Management

  • Entries are explicit children of a Series (set using post_parent)
  • Entries are managed via Series editor/management page
    • No specific menu item for general entry management
    • Series must first be selected to view its entries
    • Example: Series editor has “Add Entry” and “View Entries” buttons

Good News

Organized

Organization is vastly improved in this option.

URI structures are logical and hackable. Our “Kittens” entry in the “Awesome Things” series the following URI:

site.com/series/awesome-things/kittens/

Removing the kittens/ segment from the URI will bring us up one level to the series’ main page:

site.com/series/awesome-things/

When a user looks at the URI of a series or an entry, they will know exactly where they are in the context of a series.

In addition, this option creates the strongest possible link between a series and its entries using WordPress’ post_parent data. A post can have only one post parent, so there is zero confusion about what series an entry belongs to.

Simple

The workflow for creating entries for a series is clear and straightforward. Instead of creating a post and assigning it a series from the post editor (thus making it a series), an entry is created for a series. In this case, the chicken (series) always comes before the egg (entry).

This workflow also isolates series and entry management from other administration tasks. There is no way for entries to be modified (e.g. deleted, edited, etc.) via actions taken in other pages.

Basically, a structured workflow keeps things simple. Too many options and configuration makes things overly complex when the ultimate goal is simply to create content.

Metadata

As entries are a custom post type, they can have all the fields for entry-specific metadata we want. It would be dead simple to valuable data to an entry in the context of the series that it belongs to (e.g. milestones, final entries, etc.).

In addition, as all entries are explicit children of a series, we can let an entry inherit the series’ metadata (taxonomies, etc.) dynamically. This means you don’t have to type the same tags for each entry (only the tags that are unique to that entry).

Bad News

Flexibility

Though we gain a lot of ground in terms of organization and simplicity, we also lose ground in terms of flexibility.

For one, we can no longer add any type of post to a series. Entries can only be the custom post type created specifically for this purpose. This means that a series cannot be a grab bag of different types of content, but must fit within the constraints of what this custom post type allows.

One thing that I’ll be looking into is whether custom post types can take advantage of post formats. This would at least provide some additional variability in the type of content you can add to a series.

Obviously, there will be a way to convert existing posts to entries so that previously-created content can be integrated into series. This is no small task however, as there are several factors to account for (e.g. redirection from the entry’s old URI), so this functionality may be added in a later update.

As always, there are workarounds to allow other custom post types to be used as series entries, but as they all circumvent WordPress’ default behavior, it may be more of a hassle than it’s worth.

Visibility

Finally, as custom post types, series and entries would not show up in standard post queries (home, feeds, etc.) by default.

Depending on how you look at it, this actually might be a good thing since it means that you can keep series content separate from the rest of the site’s content if desired.

In any case, it is a fairly simple matter to integrate custom post types into default post queries, so this will likely be made available as a user option.

Decisions

As you can see, there are good and bad things about each option. Nonetheless, there are always tradeoffs with any decision, so I’m making the decision on which option to choose today. I’d be glad to hear any thoughts you may have as well.

I’m going to go for a ride. Maybe some fresh air will make things clearer.