Editorial flow is making progress and hitting interesting questions to answer. Our two primary tickets right now are #12706 and #23314.

For the first, we’re waiting on feedback on the approach from @nacin. Once we’ve gotten confirmation it’s the right direction, I’ll continue working to make the patch commit-ready.

For the second, the biggest question was how we should handle revisions for post meta and taxonomy terms. In the interest of getting to a committable patch, we’ll be dropping post meta / custom taxonomy support in favor of just being able to stage edits for the title and body content. Furthermore we’ve decided it would be worthwhile to add a new post type property so this functionality is opt-in. Posts and Pages in core will receive this by default.

Our primary goals are to have commit-ready patches for both tickets by the beginning of next week. Konstantin’s secondary goal is to chat with @westi and @ethitter and see whether revisions for post meta is within scope for 3.6. My secondary goal is to go through other editorial flow tickets and touch base with where each is at.

Initially I was disheartened that you guys were dropping metadata support, but read the irclogs and it makes sense and I’m glad their are still advocates for adding it back in later.

All of which I share only to say, THANK YOU, for such an open and transparent process. Really all the teams are doing a fabulous job and all the communication is hugely appreciated, so thank you for that and all the great work.

While the relevant tickets (#20564 and #20299) marked as 3.6, we’ve spent a good deal of time on UI/UX, and that will likely continue to be the bulk of our focus for this iteration. @nacin marked both as 3.6 because they block #23314, but we (@westi, @adamsilverstein, @karmatosed, and I) don’t have the availability to address them at this time.

1) Writer puts text in WordPress and saves as “pending review” so the editor knows its ready.
2) An editor goes in and edits the text in WordPress and schedules the post to publish, or publishes immediately if breaking news.
3) The post goes live.
4) A producer goes in and updates the appropriate fields, if they are not already filled out (category, social text, SEO headline etc). Also could fix any typos found post-launch. Probably wouldn’t need approval before going live.
5) A photo editor goes in and adds a featured image (these changes could go live without approval) and updates the post.

Revisions:

Occasionally they post corrections after a story is published and those changes would need approval.

Occasionally they do rolling posts where they update the text or photos as an event goes on. Those updates may or may not need to be reviewed before publish.

Often they have rolling photo galleries where they add a photo each day as more photos come from the wire. Those changes they’d want an editor to review before updating the post.

Suggestions:

It would be nice to have the ability to delete a revision without deleting the live post.

It would be nice to have the ability to schedule a revision to go live, so that an update can push without a person waiting around.

Kovshenin and I held office hours today but we didn’t discuss too much. Both of us have a pretty good understanding of what work needs to be done — we just need to do it.

One thing that’s come up is that #20299 (Preview changes on a published post makes all post meta “live”) is a blocker for editing already published posts. So we’ll have to figure out what we’re going to do for that.

I’d like for us to have demoable code by the next office hours: Tuesday, February 5th at 10 am PT / 1 pm ET / 1800 UTC.

The handling of meta on posts was discussed briefly in relation to post formats as well — if we start saving standardized meta data for post formats, then having those versioned becomes more important.

I’ve been working on some mockups over the weekend of possible UI implementations for revising published content. Still very draft and a bunch of unanswered questions, nonetheless here are some pictures:

So the agenda for today’s office hours is to discuss these, and maybe pick a direction (even if it’s totally different from the list above). Since there’s an overlap with the Revisions team, would appreciate if @westi and/or @ethitter popped in.

1. Overall the first option seems simplest (assuming these are 4 alternative designs). Only question is why the last screen is needed. It seems each of the options that show under the ‘More’ dropdown is already present. (UI redundancy can be ok, but not sure why it’s needed here)

2. In the first design details of the publishing status disappear on the 3rd screen. Saying “This version is unpublished” expresses less information than the previous state, where it says “Published on Jan 1st. 12:54″.

That loss in detail might be fine if we’re certain the user knows they’re working on a revision of something already published and the time it happened is irrelevant. But ideally we’d find an elegant way to tell them both info about when the original was published, *and* info that the current revision is unpublished.

We could say:

This version is unpublished
Last version published at 1/21 12:45

There’s a small can of worms here in how the schedule field behaves. It’s the only place the last published time appears, yet it goes away depending on what options the user has set.

Cool, thanks for the feedback Scott! We discussed this briefly in IRC, everybody seemed to like the first version, or at least the direction. We’ll be working on it in #23314 if you’re interested. From the mockup, “view published version” actually links to the same Edit Post screen, only of the published version, so it isn’t really the preview changes button, but yes, all other options are redundant

The publish metabox is already a bit unwieldy without these updates for the standard blogger. What do we think about simplifying the metabox (even more than it currently is) but add functionality in the form of a click to expand type of UI?

i was thinking the same thing, as were also talking about trying to cram a ‘revisions’ link in there on the revisions refresh.

i like the idea of hiding with a click to expand functionality, and also the idea of really simplifying the publish box – all most users need is publish or update; move the other functionality to another box called ‘Drafts & Revisions’…

I’m not sure this is the proper time/place to discuss this, but I like the idea of a post status bar? Like a bar above title/metaboxes that displays info like published date, publish status, revision status, post-format, etc (think browser status bars). Then that info can be removed from the publish metabox and other metabox displaying post info (or hidden in a click-to-expand section of the metabox) and give the user a high-level overview of the post’s status.

i created a new ticket (#23352) to track proposed changes to the publish box from the revisions team that relate to your workflow mockups. what do you think of simplifying publish and moving functionality to a new publish options box?

Kovshenin, Nacin and I chatted today in IRC about scope for editorial flow in 3.6. To help narrow things down, we’re now focusing on two things:

1) “Finishing” the existing API such that you can register new post statuses with expected results (no bugs, etc.).

Last week, Nacin and I had a long conversation about how enhancing the post status API in various ways could lead to complex, fully-featured workflows. We discussed again yesterday after the core IRC chat, and decided these enhancements still need more conceptual development. Instead, we’ll be focusing on the extent of #12706’s description:

A developer should be able to register a custom post status using register_post_status(). The admin UI (including post submit box and quick edit) should reflect this new custom post status. Furthermore, there are many hard-coded references to ‘draft’ and ‘pending’ statuses in core that should properly use the post status API.

All existing arguments to register_post_status() should be fully implemented, should also support per-post-type arguments. As things get implemented across core, there will likely be a need for supporting capabilities and bits of API.

I hope to have a working, testable implementation of this by next week, using existing patches and maybe some new code.

2) Allowing already published posts to be revised without being updated immediately.

We discussed a few possible implementations of this. Our conclusion is to go with the simplest possible implementation, as there are already a few plugins to handle more complex implementations.

Right now, it’s looking like this: a ‘draft revision’ can be created of an already published post. If a ‘draft revision’ of a post exists, it will appear in the post editor (instead of the published content). Anyone with appropriate permissions can make edits to the ‘draft revision’ without having those changes go live. Then, at some future point, the ‘draft revision’ can be pushed live to take the place of the original published post.

Kovshenin will be working on wireframes for this over the weekend.

We want your help!

What use cases do you have for the second, user-facing feature? The more details you can provide, the better.

Have you come across software which does the second piece well? Notably, it would let users easily choose between pushing their update live immediately, or continuing to work on and save their changes as draft.

The next office hours will be Tuesday, January 22nd at 10 am PT / 1 pm ET / 1800 UTC.

One example would be updates to breaking news, especially inside a larger news organization where there’s a review process. As news becomes more real-time (for better or worse), the space between updating a single post and live blogging will become more populated.

Sorry I missed your question here. It’d seem the second feature would be the ideal way to handle it—instead of the post, as a whole, being set to ‘Pending Review’ (or whatnot) and staying private until a reviewer publishes, an already published post could stay that way while a revision itself could be set to ‘Pending Review’ and be updated at will.

This ‘draft revision’ will be available for pages, too. I presume. For sites that need to update their more or less static content, this will provide a clean way to update, instead of creating a new page with a new permalink.

I have had a few sites where the client needs updates for any content to be run through several groups of people before it can be safely deployed. Having a “Revised Draft” status that could be viewed by specific user groups when they’re logged in would be very helpful. Perhaps a status indicator in the ribbon bar would be a good way to show what version you’re currently looking at.

Currently the review approval is handled via email and the changes are posted to staging environment for review. Once they are approved, the site admin goes in and publishes the update. But, just having the ability to show a preview version on the live site would cut out the need for the staging site entirely which would be a big improvement.

I’m not sure having a system that would actually be able to deploy content only after specific users/groups have approved the content would be worthwhile to implement in the core. That would most likely still fall into the realm of a plugin. Just having the ability to save a Revised Draft which can be previewed would be something useful across the board.

Permissions for publish_revisions and edit_post/page_revisions vs publish_posts/pages and edit_posts/pages could take care of this. Let plugins / devs / members plugin take care of roles, other than defaults for editor / author, etc.

Triggering an email for when a revision gets sent to a pending status to the published post author would be awesome too.

I worked with a few companies before where “bosses” were very sensitive about what information goes out there, so they had to sign off each piece. It was easy with posts and drafts, but published pages for sections like “our mission”, “about the company”, etc was a huge pain, because changes went in Microsoft Word first, signed off and then copy-pasted into WordPress.

Also, contributors wanting to make changes to their published posts is another obvious one.

Use case for no2: we’ll still need to keep the option to edit the ‘live’ post, even if there is a revision in draft.

You can imagine: you might be mid-way through a substantial edit of a published post, or maybe you’re awaiting approval from someone. You suddenly realise there’s a factual error in the already published version. You aren’t ready to publish the new version in its entirety, but you can’t leave the error on the live site.

We’re almost talking about Git-style branching, in effect – a ‘master’ version (live), and a ‘development’ version (revision in draft). Maybe there’s a UI lesson there?

It looks those have an “approve” button next to revisions newer than the current published one, which I think could work. Perhaps if we add a new side metabox that lists revisions newer than the last published revision with approval and diff links.

(Ideally, the way this would work is that posts would be mere pointers to a revision, and publishing would bump the post pointer to the latest revision. This is similar to git branches, where “master” e.g. is just a pointer to a specific commit, and committing to that branch makes a new commit and then bumps the branch. For WordPress, we could do similar but basically make the approve button sync the post to the revision.)

Use case for 2) involves what is currently [imho] a bug: when you edit images, featured or attachments, custom fields or any other changes that are made at the db level through ajax to the original post, they are reflected on the front end immediately, without even needing to hit Update.

One thing we did in a custom CMS platform a few years ago to avoid this is that all editing is actually done to a copy of the post, and then when saving the copy is saved back to the original. I would strongly suggest we take advantage of this new feature to fix this current bug. Then, if you change images or custom fields, and then abandon the edit, we just throw away the duplicated ‘draft’ post + meta + attachments. This means a major rework because when deleting images from a post, the deleted images must be a copy so that they are not lost if we decide to stop editing or not go through with the changes.

I haven’t seen this exactly expressed yet, so tossing it out there. More conceptual, but also related to dealing with the current status stuff in core.

It seems that the current core post statuses (draft, pending, publish, future, private, trash) are pretty good indicators of a post’s current state in the system.

Most (all?) of the use cases for custom post statuses appear to fit under the umbrella of one of these post states, though with nomenclature that describes different parts of a custom worlkflow.

Would it be plausible to introduce the idea of attaching a post state to a post status when it is registered? This could allow current parts of core relying on these states to stay useful – though status/state naming is confusing – while also accounting for new workflows.

It would also be nice to see the ability for multiple post statuses to be assigned at once, which a structure based around states should allow for.

Correct me if I’m wrong, but I believe what you’re talking about is actually something Nacin and I discussed on 1/18: abstraction of post status special capabilities. For instance, ‘future’ has a special capability of transitioning between two statuses at a specific point in the future.

We made the determination that the idea needs fleshing out conceptually before we can dive into it practically, so that type of enhancement is now out of scope for 3.6

It would also be nice to see the ability for multiple post statuses to be assigned at once, which a structure based around states should allow for.

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.

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.

I’m really excited to see our editorial flow get some love in the 3.6 cycle! We always want to be as extensible as possible and post statuses are one of those places where we’re not near as good as we should be. The plan goes something like this:

Fully support the existing register_post_status() API in core

Make sure things don’t break when you add your own custom statuses

Update the metabox UI to show any newly registered statuses in the drop down, etc.

Add a ‘moderation’ flag so that unpublished statuses can be explicitly identified

Support for non-standard public post statuses

Enhance the existing API

Add support for registering post statuses to specific post types

Allow for caps checks on different post statuses

New remove_post_status() function for removing an already-registered post status

Editing workflow for already published content

Additionally, we hope to address some issues around post meta for revisions, which is tightly related to the workflow for already published content.

@markjaquith and I have chosen Daniel Bachhuber to lead this. If you’re not sure why, just Google WordPress Edit Flow and it’ll all make sense. There’s a lot of heavy-duty under the hood work here, so please leave a comment if you’re interested in lending a hand.

Automatic tagging and related posts will both continue to be in plugin territory for now. I know there are some good ones out there, but the usecase is still too small to justify having that functionality in core.

As for the desktop apps, WordPress as an XMLRPC API that they can use to post to it (the same one the mobile apps use). I don’t personally use any of those tools, but the capability is definitely there.

Everyone has a different definition of ‘enterprise level’. It’s probably not sensible to try to tie that definition down. Instead, I’ll describe the sort of website I’m talking about:

Anywhere from 3,000 to 10,000 pages (and let’s not talk about PDFs!)
Anywhere from 3 to 7 levels deep: the site I’m currently working on will be 7 levels deep minimum
The majority of content not chronologically based
Several hundred distributed authors, located around the state, spread throughout maybe 60 business areas, each with their own signoff processes.
Centralised editorial quality assurance
Complex workflows:
One piece of content may need to go through 5 levels of approvals
Another may only need to go through 2 levels
There will be different approval steps and different users for different content types and different categories
Example: Content author -> Manager -> Communications -> Web Editor -> Tech QA -> Publish.
Note: It’s not about traffic. We all know WordPress can scale, for example as in the case of WordPress.com. Rather it is about complexity and the ability of WordPress to handle this sort of site out of the box.”

So, the workflow and QA things you mention are kind of where this is going. Not building that into core directly, but making it easier for a plugin like Edit Flow to implement custom post statuses and a more complex posting workflow.

Looking forward to watching how this pans out! This has been a pain point for larger organisations for a while.

Happy to give the perspective of the requirements for a large site (up to 5 levels of approvals, different approval steps / user groups for different content, based on content types, categories, even individual pages, etc), if catering for that sort of site is within scope.

One thing where I’d really love to see a solution is about that freaky thing that happens when switching “visibility” from “public” to “private”. When doing so, the “Save as (draft/etc.)” button disappears. It doesn’t come back when switching to “public” anymore. Ticket incl. several patches that cover different scenarios is here https://core.trac.wordpress.org/ticket/21563

Any way we can also figure out a way for published content to remain published when a user submits updates for review? One of the trickest things to work around is to allow users without publish rights to submit updates to content with out taking that content offline. Seems like we could serve up the last published revision, assuming we have all metadata and taxonomy selection attached to the revision, rather than taking the main page off line. Right now I’m using a customized version of Boston Universities Versions Plugin, which does an OK job, but would be nice if this was built into core.

The way it works now is “ok” for posts and news style items, but really seems to break down when dealing with pages.