Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Publication Checklist feature #13

Merged
merged 3 commits into from
Jul 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"type": "package",
"require": {
"php": ">=7.1",
"humanmade/workflows": "~0.3.4"
"humanmade/workflows": "~0.3.4",
"humanmade/publication-checklist": "~0.1.0"
},
"license": "GPL-3.0",
"authors": [
Expand Down
179 changes: 179 additions & 0 deletions docs/publication-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Publication Checklist

Publication Checklist provides a framework for building out prepublish checks, with flexibility to fit your workflows.


## Enabling

This feature is enabled by default, but has no visual effect until you create checks.

The feature can be disabled entirely by setting the `modules.workflow.publication-checklist` option to `false`:

```json
{
"extra": {
"altis": {
"modules": {
"workflow": {
"publication-checklist": false
}
}
}
}
}
```

To set advanced options (detailed below), set this option to an object. The `enabled` key should be set to `true`:

```json
{
"extra": {
"altis": {
"modules": {
"workflow": {
"publication-checklist": {
"enabled": true
}
}
}
}
}
}
```

## Creating checks

The core of a check is a function that receives the post's data and meta, and returns a `Status` object. This status object indicates whether publish should be blocked or not.

For example, to enforce setting a value for the "foo" meta key:

```php
use function Altis\Workflow\PublicationChecklist\register_prepublish_check;
use Altis\Workflow\PublicationChecklist\Status;

add_action( 'altis.publication-checklist.register_prepublish_checks', function () {
register_prepublish_check( 'foo', [
'run_check' => function ( array $post, array $meta ) : Status {
if ( isset( $meta['foo'] ) ) {
return new Status( Status::COMPLETE, 'Foo completed' );
}

return new Status( Status::INCOMPLETE, 'Missing foo data' );
},
] );
} );
```

Checks are registered via the `Altis\Workflow\PublicationChecklist\register_prepublish_check` function with a unique ID. This function should be called on the `altis.publication-checklist.register_prepublish_checks` action.

Your check function receives the post data as an array, and the post's meta data as an array. Your function should only use this data to run the check, as this may represent data before it is saved to the database. Specifically, your function's signature should be:

```php
function ( array $post, array $meta ) : Status;
```

Your function must return a `Altis\Workflow\PublicationChecklist\Status` object. This object is marked as either complete (allow publishing), incomplete (block publishing), or informational (show as failed, but allow publishing). This status object takes the status type (which should be either `Status::COMPLETE`, `Status::INCOMPLETE`, or `Status::INFO`) and a human-readable message.

You can additionally pass data with the status object, which can be used on the frontend to assist with rendering.


## Displaying check status

By default, Publication Checklist will render a simple checklist of all checks.

You can override a specific item to render richer UI if needed. For example, you may wish to integrate deeply into the block editor, or allow users to correct failing checks inline. This UI is directly inserted into the React element tree and replaces the default output.

Publication Checklist exposes a `altis-publishing-workflow.item.{check_id}` filter using [`withFilters`](https://github.com/WordPress/gutenberg/tree/master/packages/components/src/higher-order/with-filters) to allow overriding the list item component.

For example, to wrap the default status message with a link to a documentation page for the `foo` check:

```jsx
import { Fragment } from '@wordpress/element';

addFilter( 'altis-publishing-workflow.item.image-texts', 'foo/link-message', () => {
return props => {
return (
<Fragment>
{ props.renderStatusIcon() }
<a href="http://example.com/">{ props.message }</a>
</Fragment>
);
};
} );
```

Your component receives the following props:

```jsx
const propTypes = {
// Check ID.
name: PropTypes.string.isRequired,

// Human-readable message returned from the backend.
message: PropTypes.string.isRequired,

// Status string.
status: PropTypes.oneOf( [ 'complete', 'incomplete', 'info' ] ).isRequired,

// Function to render the status of the current check.
// () => ReactElement
renderStatusIcon: PropTypes.func.isRequired,

// Additional data from the backend.
data: PropTypes.any,
};
```

To enable advanced functionality, you may want to wrap this component in [selectors which provide data about the post](https://developer.wordpress.org/block-editor/data/data-core-block-editor/). Note that the backend acts as the canonical source of all check data, so changes to check status will require saving to the backend to take effect.


## Enforcing checks

By default, Publication Checklist will display a warning if some items are incomplete, with a prompt to allow publishing anyway.

To enforce these checks and block publication, set the `modules.workflow.publication-checklist.block_on_failing` option to `true`:

```json
{
"extra": {
"altis": {
"modules": {
"workflow": {
"publication-checklist": {
"enabled": true,
"block_on_failing": true
}
}
}
}
}
}
```

This will change the UI to disable the publish button, display a user-facing message that checks must be completed, and block requests to publish the post.


## Disabling the list view

Publication Checklist will add a Tasks column to the Posts list screen showing the status of each post. This column is only shown if statuses have been registered.

To hide this column, set the `modules.workflow.publication-checklist.hide_column` option to `true`:

```json
{
"extra": {
"altis": {
"modules": {
"workflow": {
"publication-checklist": {
"enabled": true,
"block_on_failing": true
}
}
}
}
}
}
```

This will hide the Tasks column.
25 changes: 25 additions & 0 deletions inc/namespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,36 @@
namespace Altis\Workflow;

use const Altis\ROOT_DIR;
use function Altis\get_config;

function bootstrap() {
add_action( 'muplugins_loaded', __NAMESPACE__ . '\\load_workflows', 0 );
add_action( 'muplugins_loaded', __NAMESPACE__ . '\\load_publication_checklist', 0 );
}

function load_workflows() {
require_once ROOT_DIR . '/vendor/humanmade/workflows/plugin.php';
}

/**
* Load the Publication Checklist feature, if enabled.
*/
function load_publication_checklist() {
$config = get_config()['modules']['workflow']['publication-checklist'] ?? null;
if ( ! $config ) {
return;
}

if ( ! is_array( $config ) ) {
$config = [];
}

if ( $config['block_publish'] ?? false ) {
add_filter( 'altis.publication-checklist.block_on_failing', '__return_true' );
}
if ( $config['hide_column'] ?? false ) {
add_filter( 'altis.publication-checklist.show_tasks_column', '__return_false' );
}

require_once ROOT_DIR . '/vendor/humanmade/publication-checklist/plugin.php';
}
5 changes: 5 additions & 0 deletions load.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
'enabled' => true,
'posts-workflow' => false,
'editorial-workflow' => false,
'publication-checklist' => [
'enabled' => true,
'block_on_failing' => false,
'hide_column' => false,
],
];
register_module( 'workflow', __DIR__, 'Workflow', $default_settings, __NAMESPACE__ . '\\bootstrap' );
} );