Skip to content

This WordPress plugin adds additional editorial workflow capabilities to WordPress.

License

Notifications You must be signed in to change notification settings

Automattic/vip-workflow-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


⚠️ This plugin is currently in Beta. It is designed to run on WordPress VIP. This beta release is not intended for use on a production environment.


WordPress VIP Workflow Plugin (Beta)

PHP TestsJS Tests

The WordPress VIP Workflow Plugin allows you to control your editorial workflow. You can set up custom statuses for every phase of your workflow, and transitions between statuses generate actions, like notifications.

This plugin is currently developed for use on WordPress sites hosted on WordPress VIP.

Try it out

Try out the VIP Workflow plugin in your browser with WordPress Playground:

Installation

The latest version of the plugin is available in the default trunk branch of this repository.

Install via git subtree

We recommend installing the latest plugin version via git subtree within your site's repository:

# Enter your project's root directory:
cd my-site-repo/

# Add a subtree for the trunk branch:
git subtree add --prefix plugins/vip-workflow-plugin [email protected]:Automattic/vip-workflow-plugin.git trunk --squash

To deploy the plugin to a remote branch, git push the committed subtree.

The trunk branch will stay up to date with the latest version of the plugin. Use this command to pull the latest trunk branch changes:

git subtree pull --prefix plugins/vip-workflow-plugin [email protected]:Automattic/vip-workflow-plugin.git trunk --squash

Ensure that the plugin is up-to-date by pulling changes often.

Note: We do not recommend using git submodule. Submodules on WPVIP that require authentication will fail to deploy.

Install via ZIP file

The latest version of the plugin can be downloaded from the repository's Releases page. Unzip the downloaded plugin and add it to the plugins/ directory of your site's GitHub repository.

Plugin activation

We recommend activating plugins with code.

Usage

Admin

Once the plugin is activated, go to the VIP Workflow menu in wp-admin to configure your workflow.

By default, the following post statuses are created:

  1. Pitch
  2. Assigned
  3. In Progress
  4. Draft
  5. Pending Review

Note that, these statuses are also available in the quick edit experience on the posts page alongside the core post statuses.

The plugin doesn't expect any specific configuration, so your first step is to set up statuses that reflect your workflow. You may notice that the steps are listed in a linear order. The plugin assumes a linear workflow where content is moving from creation to publish.

You can also specify which types of content use custom statuses. If a post does not use custom statuses, it will use the standard WordPress publishing flow.

Notifications

VIP Workflow has the ability to send email and/or webhook notifications when a post's status changes. By default, these are off as no email address or webhook is provided out of the box. You set up webhook and/or email notifications under Admin -> VIP Workflow -> Settings.

Additional filters are available here to customize the notifications that are sent.

Publish Guard

By default, VIP Workflow prevents publishing a post or page (the supported post types are configurable within settings) unless it has reached the last status on your list. This feature can be turned off under settings under the Publish Guard option in Admin -> VIP Workflow -> Settings.

Editorial Experience

Guided Status Movements

VIP Workflow adds an editor button to move posts between custom post statuses:

Moving between custom statuses using a custom save process

While editing a post with a custom status, click the "Move to ..." button to advance to the next state. When Publish Guard is enabled, the regular "Publish" button will be hidden until a post reaches the final custom status state.

Custom statuses can also be modified by using the "Extended Post Status" row "Edit" button in the post sidebar.

Preview Links

VIP Workflow adds a "Preview" section to the post sidebar, which allows sharing previews of pre-published content:

Generating a preview link on a pre-published post

Anybody with a preview link (including not logged-in users) will be able to view a post with a preview link. Preview links can expire in three ways:

  1. Via expiration. Preview links are generated with an expiration (1 hour, 8 hours, or 1 day by default). When this time has passed, the token URL will no longer be valid.
  2. Via one-time usage. If the "One-time use" checkbox is selected, the preview URL will only work a single time, and then the token will become invalid. If this box is not selected, a preview URL can be used any number of times before expiration.
  3. Via post status changes. If a post moves out of VIP Workflow's set of extended post statuses, tokens will no longer be valid. For example, a post moved to "Publish" will no longer have valid preview tokens.

Editorial Metadata

VIP Workflow adds a "Editorial Metadata" section to the post sidebar, which allows for additional data to be included with the post such as "Needs Legal Review". This can be managed under the plugin's settings, to get a visual for all of the configured editorial metadata fields.

Code Filters

vw_notification_ignored_statuses

When a post changes status, configured notifications are sent. You can use this filter to prevent notifications when a post transitions into specific statuses. By default, the plugin already filters the built-in inherit and auto-draft statuses.

/**
* Filter the statuses that should be ignored when sending notifications
*
* @param array $ignored_statuses Array of statuses that should be ignored when sending notifications
* @param string $post_type The post type of the post
*/

apply_filters( 'vw_notification_ignored_statuses', [ $old_status, 'inherit', 'auto-draft' ], $post->post_type );

For example, this filter can be used to add assigned to the ignored statuses for a post of post_type page, so no notifications are sent for such posts:

add_filter( 'vw_notification_ignored_statuses', function ( $ignored_statuses, $post_type ) {
    if ( $post_type === 'page' ) {
        $ignored_statuses[] = 'assigned';
    }

    return $ignored_statuses;
}, 10, 2 );

vw_notification_email_recipients

Change the recipients that receive an email notification, when the status of a post changes. By default, it is set to the configured email address under Admin -> VIP Workflow -> Settings.

/**
* Filter the email recipients
*
* @param array $email_recipients Array of email recipients
* @param string $action Action being taken, eg. status-change
* @param WP_Post $post Post object
*/
apply_filters( 'vw_notification_email_recipients', $email_recipients, $action, $post );

For example, this filter can be used to send email notifications to more than just 1 recipients especially for special statuses:

add_filter( 'vw_notification_email_recipients', function ( $email_recipients, $action, $post  ) {
  if ( $post->post_status === 'legal-review' ) {
    $email_recipients[] = '[email protected]';
  }

  return $email_recipients;
}, 10, 2 );

vw_notification_email_subject

Change the subject of the email that recipients receive, when the status of a post changes.

/**
* Filter the email subject
*
* @param string $subject Subject of the email
* @param string $action Action being taken, eg. status-change
* @param WP_Post $post Post object
*/
apply_filters( 'vw_notification_email_subject', $subject, $action, $post );

For example, this filter can be used to set a standardized subject regardless of what the status is:

add_filter( 'vw_notification_email_subject', function ( $subject, $action, $post  ) {
  return __( 'Content Status Update' );
}, 10, 2 );

vw_notification_email_message

Change the message of the email that recipients receive, when the status of a post changes.

/**
* Filter the email message
*
* @param string $message Body of the email
* @param string $action Action being taken, eg. status-change
* @param WP_Post $post Post object
*/
apply_filters( 'vw_notification_email_message', $message, $action, $post );

For example, this filter can be used to replace the signature that the plugin adds to the footer of the email with a company one instead:

add_filter( 'vw_notification_email_message', function ( $message, $action, $post  ) {
  return str_replace( 'You are receiving this email because a notification was configured via the VIP Workflow Plugin.', 'You are receiving this email as part of ACME Corp.', $message);
}, 10, 2 );

vw_notification_email_headers

Change the headers used for the email that recipients receive, when the status of a post changes. By default, they are the standard headers set by wp_mail.

/**
* Filter the email recipients
*
* @param array $message_headers Message headers
* @param string $action Action being taken, eg. status-change
* @param WP_Post $post Post object
*/
apply_filters( 'vw_notification_email_headers', $message_headers, $post );

For example, this filter can be used to send HTML formatted email notifications instead of the default plain text formatted email notifications:

add_filter( 'vw_notification_email_headers', function ( $message_headers, $action, $post  ) {
  return [ 'Content-Type: text/html; charset=UTF-8' ];
}, 10, 2 );

vw_notification_send_to_webhook_payload

Change the payload sent to the webhook, when the status of a post changes. By default, it is as follows:

{
  "type": "plugin:vip-workflow:post-update",
  "timestamp": "2024-07-22 00:03:19",
  "data": "*vipgo* changed the status of *Post #85 - <http://test-site.vipdev.lndo.site/wp-admin/post.php?post=85&action=edit|hello>* from *In Progress* to *Draft*"
}
/**
* Filter the payload before sending it to the webhook
*
* @param array $payload Payload to be sent to the webhook
*/

apply_filters( 'vw_notification_send_to_webhook_payload', $payload );

For example, this filter can be used to customize the payload so that it's compatible with Slack's incoming webhooks:

add_filter( 'vw_notification_send_to_webhook_payload', function ( $payload ) {
    return [
        'text' => $payload['data'],
    ];
}, 10, 1 );

vw_preview_expiration_options

Change the default expiration options available in the preview URL feature.

/**
 * Filter the expiration options available in the preview modal dropdown.
 *
 * @param array $expiration_options Array of expiration options. Each option uses keys:
 *     'label': The visible label for the option, e.g. "1 hour"
 *     'value': The value to be sent to the API, e.g. "1h". This value should be unique.
 *     'second_count': The number of seconds the this expiration should be valid for, e.g. 3600
 *     'default': Optional. Whether this option should be selected by default.
 */
return apply_filters( 'vw_preview_expiration_options', [ /* ... */ ]);

Here is an example using a shorter set of expiration lengths:

add_filter( 'vw_preview_expiration_options', function () {
    return [
        [
            'label'        => '5 minutes',
            'value'        => '5m',
            'second_count' => 5 * 60,
            'default'      => true,
        ],
        [
            'label'        => '15 minutes',
            'value'        => '15m',
            'second_count' => 15 * 60,
        ],
        [
            'label'        => '1 hour',
            'value'        => '1h',
            'second_count' => 60 * 60,
        ],
    ];
} );

This generates these custom expiration values in the preiew link dialog:

Preview link dialog with custom expiration times

Development

This plugin uses wp-env for development, and wp-env to run the tests written for the plugin. wp-env requires Docker so please ensure you have that installed on your system first.

To install wp-env, use the following command:

npm -g i @wordpress/env

Read more about wp-env here.

Optionally, it's also possible to use vip dev-env instead for development. Installation instructions for the VIP cli can be found here, and instructions on how to setup vip dev-env can be found here.

This plugin also uses Composer to manage PHP dependencies. Composer can be downloaded here.

Building the plugin

  1. Install PHP dependencies: composer install
  2. Install NPM dependencies: npm install
  3. Start dev environment: wp-env start

Using Hot Module Replacement

React hot reloading is supported. A few configuration steps are required for the setup:

  1. Set define( 'SCRIPT_DEBUG', true ); in your wp-config.php or vip-config.php. At the time of writing, this is a wp-scripts limitation.

  2. Run npm run dev:hot. If you're running WordPress on a non-localhost hostname, e.g. on vip dev-env, you may also need to specify the hostname:

    HOST=mysite.vipdev.lndo.site npm run dev:hot

    This can also be specified using a .env configuration file:

    HOST=mysite.vipdev.lndo.site
    

    If you use wp-env, you should be able to skip specifying HOST manually.

  3. If HMR is not working and you're developing out of a new component tree, you may also need to opt-in to hot module reloading via module.hot.accept()

Tests

We are currently in the process of writing unit tests to ensure thorough code coverage of the plugin. At the moment, these are just PHP tests which can be run locally using the following:

wp-env start
composer install
composer run test

Credits

This plugin has been based on the wonderful EditFlow plugin developed by Daniel Bachhuber, Scott Bressler, Mohammad Jangda, and others.