Editorial Flow Update, 1/18

Nacin and I chatted today about what we want to do about editorial flow in 3.6. At the crux of building any new features is completing the API for registering new post statuses.

There’s an existing patch in #12706 which solves some, but not all of the problems, which is probably why it’s been punted release after release. The problems can be understood as the following questions:

How are custom statuses related to post types? Are they global? Can they be assigned to only some types? Can they have different properties for different types?

How can we describe transitions from one status to another? How does the current status (and the state of the post in general) inform which statuses are available? How are capabilities used to affect which statuses are available? How do we describe the ability to access or affect a post based on its current status?

How do custom statuses factor into core UI?

How do we define and/or extract the special features of existing core statuses?

The most substantial question is the last one. It’s worth reading through the chatlog in understanding how we got there as there’s a fair amount of exploratory thinking:

The primary project right now is tracking down each of those special use cases. You can help out!

A “special use case” is a particular way the status (or statuses) manifests itself in core behavior. For instance, ‘draft’ and ‘pending’ appearing in a dropdown when editing an individual post is one manifestation of a special use case. When identifying these special use cases, please point to all relevant lines of code and indicate the core statuses affected.

The secondary project right now is identifying use cases for custom post statuses. For example, as Nacin and I got to in the chat, Edit Flow’s custom status support is used for essentially creating new, labeled versions of the ‘draft’ status; essentially, establishing a workflow before publication:

pitch -> assigned -> in-progress -> ready-edit

If you were building a ticketing system on WordPress, however, you might have all public statuses like this:

new -> assigned -> resolved -> verified -> closed -> rejected

It would be tremendously valuable to have a variety of established use cases to play with once we start poking at the API. The more details for each use case the better.

The next office hours will be Tuesday, January 22nd at 11 am PT / 2 pm ET / 1900 GMT.

Share this:

Is there somewhere to track the use cases for custom post stati? One custom post status that I use quite often is expired and canceled . I have a private plugin that I use but never released because of the clunky API and admin. Instead of deleting or moving a post to the trash, expired sets the post to expired (especially good for coupons post type). I’ve used expired and canceled with an Events plugin to control displaying past events that have happened (e.g. concerts) and events that were canceled and set to be rescheduled.

@Daniel – To answer your first question our experience is that status is like taxonomy; often status is specific to a post type but some status can be shared. Further and unlike taxonomy I think there are some status that are and should be universal across post types but not sure which ones as that depends on how you address question #4.

Your second question implies a state-based workflow system, one that I’d love to see in WordPress but one that is probably out-of-scope for 3.6 (or is it?)

As for both your third and fourth questions I’d think status should have properties like post types have properties so that we can have a status that has a “publish” property so more statuses than “publish” can be published, etc. Of course this will change a lot of assumptions, especially in themes and plugins so it’s likely something that would have to be phased in over many versions, at least the properties that would equal to the current statuses in core.

For example, our main client badly wanted us to change ‘private’ and ‘draft’ to just be ‘hidden’. So a post is either published or hidden in our system. That’s actually a nightmare to manage, but it’s what the client required. It would be so much better if we could assign the ‘hidden’ status to have both the properties of ‘private’ and of ‘draft’.

Could you explain the use cases you’ve found for a shared status? One issue I see with shared (and universal) statuses is that it would be difficult to have a status mean one thing in one post type, and another for another post type. Different flags, capabilities, transitions might be different.

While taxonomies feel like first-class objects by nature, statuses don’t (to me). It would feel weird for two independent plugins to cause a problem after defining their own post types, both with “active” and “inactive” statuses. Why should statuses be so restrictive? I’m leaning toward them being keyed internally by post type. If you wanted to assign a status to multiple types, it would be granted to each individual type, rather than being in some kind of shared pool.

I am not sure whether a state-based workflow system is in or out of scope. One reason why #12706 has seen little movement over the years is it seems to bring very little to the table. The result is a fairly rigid, weak API that pretty much means you can create new status labels. That’s not particularly helpful.

I would look over #12706 — core already does quite a bit of status property handling (public, protected, etc), and the older patches on that ticket work to leverage more of them in more areas of core. I’d be interested to see what ideas a review could spark.

How are custom statuses related to post types? Are they global? Can they be assigned to only some types? Can they have different properties for different types?

I think that each status should be unique to a post type. If three plugins do custom statuses for their own post types, I don’t want to see those statuses when viewing or editing posts and pages.

Also, as you mentioned, same names might mean different things in different contexts. A cancelled ticket/attendee might be private, since you don’t want them to show up in the list of people attending an event, but a cancelled concert/event should be public, since you want everyone to know that the concert has been cancelled.

How can we describe transitions from one status to another? How does the current status (and the state of the post in general) inform which statuses are available? How are capabilities used to affect which statuses are available? How do we describe the ability to access or affect a post based on its current status?

I think that transitions should be like capabilities, but for posts, and a way to ask whether the current post, with its current post status, can transition to a different post status, provided that the current user has the caps to transition to that status.

A good example is the trac ticket workflow: even though the current user has permission to set a ticket to the “reopened” status, a ticket has to be “closed” in order to do so. You can not reopen new, assigned and accepted tickets.

The UI should be built based on these (and current user’s) capabilities.

The visibility part is tricky, especially if we want any custom status to be able to act like any of the core statuses. Perhaps statuses can add themselves to existing hooks, like pre_get_posts, to make a status public or private on the front end, or hide from the edit posts screen like Trash.

How do custom statuses factor into core UI?

If the special features are defined or extracted from core statuses, then custom statuses will be no different.

How do we define and/or extract the special features of existing core statuses?

Good question. I think statuses should have (actually they already have some) flags for things like show on front end, show in edit posts, show in status dropdown, a list of capabilities and so on. Other things like “transition status based on timestamp” could be a simple cron job that transitions a post from one status to another based on some criteria. It can be future to publish, but it can also be pending to trash. I don’t think this should be part of the statuses API.