---
title: Checklist
description: MediaPress Checklist provides a way to register checks that would inform an editor of best practices when publishing posts/pages.
url: https://developers.wpengine.com/docs/newsroom/mediapress/checklist/
image: https://developers.wpengine.com/og/docs/newsroom/mediapress/checklist.png
---

# Checklist

MediaPress Checklist provides a way to register checks that would inform an editor of best practices when publishing posts/pages. These checks can also block publishing if needed.

Checks are registered via a JSON file. Each check is run through a filter before being sent to the publication checklist component. This means custom checks and additional checks can be performed also.

The publication checklist also provides 4 in-built checks (exists/min/max/range) to speed up generating common checks.

## Additional Configuration

Checklist must be activated via the “MediaPress” settings page.

Out of the box, it contains a sample config for testing purposes. You should replace this with your own JSON config file, and point to this file using the [appropriate filter](https://developers.wpengine.com/docs/newsroom/mediapress/checklist/#mediapress_checklist_config_path).

The exact format of the config file is documented in the plugin at `/wp-content/plugins/mediapress-core/packages/checklist/config-schema.json` and may be accessed from the filesystem or web browser. `example-config.json` in the same directory shows how this can be implemented. However, each checklist `item` within the config can receive the following properties:

### Item name (`name`)

A **unique** name given to the item in snake case.

### Item type (`type`)

The type of item it is. Accepts `blocking`, `non_blocking`, `info` and `custom`.

#### Blocking

`blocking` items will block the updating/publishing of a post and will count toward the total number of items to be completed.

#### Non-blocking

`non_blocking` items will **not** block the updating/publishing of a post but will still count towards the total number of items to be completed.

#### Info

`info` items will **not** block the updating/publishing of a post and will **not** be counted towards the total number of items to be completed.

#### Custom

`custom` items will not perform any kind of default behavior and will require code on the `mediaPress.checklist.item` filter that passes back the status and message of the item.

### Check types (`check: type`)

These checks are available to use out of the box when setting up your checklist config. Accepts `exists`, `min`, `max`, `range`.

#### Exists

`exists` checks if the provided source exists.

**Example:**

```json
{
  "name": "has_title",
  "type": "blocking",
  "check": {
    "type": "exists",
    "sourceKey": "title"
  },
  "messages": {
    "pass": "Has a title",
    "fail": "Must have a title"
  },
  "postTypes": ["post"]
}
```

#### Min

`min` checks if the provided source is greater than a min value. For a string, this can be used to check character count and for an array, it can be used to count items in the array.

**Character count example:**

```json
{
  "name": "has_5_character_title",
  "type": "blocking",
  "check": {
    "type": "min",
    "min": 5,
    "sourceKey": "title"
  },
  "messages": {
    "pass": "Has a title longer than 5 characters",
    "fail": "Must have a title longer than 5 characters"
  },
  "postTypes": ["post"]
}
```

**Item count example:**

```json
{
  "name": "has_5_categories",
  "type": "blocking",
  "check": {
    "type": "min",
    "min": 5,
    "sourceKey": "categories"
  },
  "messages": {
    "pass": "Has 5 categories",
    "fail": "Must have 5 categories"
  },
  "postTypes": ["post"]
}
```

#### Max

`max` checks if the provided source is smaller than a max value. For a string, this can be used to check character count and for an array, it can be used to count items in the array.

**Character count example:**

```json
{
  "name": "has_20_character_title",
  "type": "blocking",
  "check": {
    "type": "max",
    "min": 20,
    "sourceKey": "title"
  },
  "messages": {
    "pass": "Has a title shorter than 20 characters",
    "fail": "Must have a title shorter than 20 characters"
  },
  "postTypes": ["post"]
}
```

**Item count example:**

```json
{
  "name": "has_10_categories",
  "type": "blocking",
  "check": {
    "type": "min",
    "min": 10,
    "sourceKey": "categories"
  },
  "messages": {
    "pass": "Has less than 10 categories",
    "fail": "Must have less than 10 categories"
  },
  "postTypes": ["post"]
}
```

#### Range

`range` checks if the provided source is between a min/max value. For a string, this can be used to check character count and for an array, it can be used to count items in the array.

**Character count example:**

```json
{
  "name": "between_5_20_character_title",
  "type": "blocking",
  "check": {
    "type": "range",
    "min": 5,
    "max": 20,
    "sourceKey": "title"
  },
  "messages": {
    "pass": "Has a title between 5 and 20 characters",
    "fail": "Must have a title between 5 and 20 characters"
  },
  "postTypes": ["post"]
}
```

**Item count example:**

```json
{
  "name": "between_5_20_character_title",
  "type": "blocking",
  "check": {
    "type": "range",
    "min": 5,
    "max": 20,
    "sourceKey": "categories"
  },
  "messages": {
    "pass": "Has between 5 and 20 categories",
    "fail": "Must have between 5 and 20 categories"
  },
  "postTypes": ["post"]
}
```

### Source Key (`check: sourceKey`)

The key of the source to run the check against. This should be data that can be found using `getEditedPostAttribute()`.

> **Tip**
>
> - Taxonomies are stored at the root. For example `categories` or `tags`.
> - Meta is stored under a `meta` key. For example `meta.meta_key`.

### Messages (`messages`)

The messages to display when the check has passed or failed or if there is no check and it’s informational.

#### Pass

The `pass` message should contain the string to display if the check has passed.

#### Fail

The `fail` message should contain the string to display if the check has failed.

#### Info

The `info` message should contain the message if there is no check and the check is informational (`type: info`).

### Post Types (`postTypes`)

An array of registered post types the check should run on.

## Groups

Groups are an optional top-level array in the config that organise checklist items into collapsible accordions within the Publication Checklist panel. Items not assigned to any group are rendered above the groups.

### Group name (`name`)

A **unique** identifier for the group in lowercase letters, hyphens, or underscores (e.g. `title-checks`).

### Group title (`title`)

The human-readable label displayed as the accordion header.

### Group items (`items`)

An array of item `name` strings that belong to this group.

**Example:**

```json
{
  "groups": [
    {
      "name": "title-checks",
      "title": "Title Checks",
      "items": ["has_5_character_title", "title_between_6_9_characters"]
    },
    {
      "name": "excerpt-checks",
      "title": "Excerpt Checks",
      "items": ["excerpt_exists", "excerpt_less_than_20_characters"]
    }
  ]
}
```

> **Note**
>
> Each entry in `items` must match the `name` of an existing checklist item. Unrecognized names are silently ignored.

## Custom Check Example

In this example, we are checking that a post contains any banned words in the content.

This is a fairly expensive check, we should be mindful of performance when using complex checks which provide real-time feedback to users.

Implementing a custom check requires both adding a new check to the checklist config, and defining the conditions of the check using the JavaScript filter, examples of both are below:

### Config

Use the [`mediapress_checklist_config_path`](https://developers.wpengine.com/docs/newsroom/mediapress/checklist/#mediapress_checklist_config_path) filter to point to your custom config file, containing the following JSON:

```json
{
  "items": [
    {
      "name": "has_banned_words",
      "type": "custom",
      "postTypes": ["post"]
    }
  ]
}
```

### Code

Use the [`mediaPress.checklist.item`](https://developers.wpengine.com/docs/newsroom/mediapress/checklist/#mediapresschecklistitem) filter to define your check using JavaScript:

```jsx
/**
 * Checks if content contains any banned words
 */


import { getBlockContent } from '@wordpress/blocks';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { select, dispatch } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';


const BANNED_WORDS = ['banned', 'inappropriate', 'offensive'];


addFilter(
  'mediaPress.checklist.item',
  'my-plugin/check-for-banned-words',
  (item) => {
    if (item.name !== 'has_banned_words') {
      return item;
    }


    const content = select(editorStore).getEditedPostContent();


    const foundBannedWord = BANNED_WORDS.find((word) =>
      content.toLowerCase().includes(word.toLowerCase()),
    );


    if (foundBannedWord) {
      const blocks = select(editorStore).getBlocks();


      const failedBlock = blocks.find((block) => {
        const blockContent = getBlockContent(block);
        return blockContent.toLowerCase().includes(foundBannedWord);
      });


      /**
       * Function to select the block containing the banned word
       *
       * @return {void}
       */
      const selectBlock = () => {
        dispatch(blockEditorStore).selectBlock(failedBlock.clientId);
      };


      return {
        ...item,
        status: 'BLOCKING',
        // translators: %s the banned word
        message: sprintf(
          __('The content contains banned word: "%s"', 'my-plugin'),
          foundBannedWord,
        ),
        action: selectBlock,
      };
    }


    return {
      ...item,
      status: 'COMPLETED',
      message: __('The content does not contain any banned words', 'my-plugin'),
    };
  },
);
```

## Filters/Actions

### JavaScript

#### Filters

##### `mediaPress.checklist.item`

Allows for the filtering of a checklist item.

This is also used to implement custom checks, by registering a check as ‘custom’ in the JSON config and using this filter to return different statuses dynamically based on any logic you need to implement.

**Parameters**

| Name         | Type                                                              | Description                                    |
| ------------ | ----------------------------------------------------------------- | ---------------------------------------------- |
| item         | `ChecklistItem`                                                   | The filterable checklist item object           |
| item.message | `string`                                                          | The message of the item                        |
| item.name    | `string`                                                          | The name of the item                           |
| item.status  | `'BLOCKING'`\|`'NONBLOCKING'`\|`'COMPLETED'`\|`'INFO'`\|`'ERROR'` | The status of the item                         |
| item.action  | `Function`\|`null`                                                | Optional callback for when the item is clicked |

**Usage**

```js
addFilter(
  'mediaPress.checklist.item',
  'my-plugin/filter-checklist-item',
  (item) => {
    if (item.name !== 'my_checklist_item') {
      return item;
    }


    if (someCondition === true) {
      return {
        ...item,
        status: 'BLOCKING',
        message: __('This check is blocking.', 'my-plugin'),
        action: () => console.log('trigger an action'),
      };
    }


    return {
      ...item,
      status: 'COMPLETED',
      message: __('This check is completed.', 'my-plugin'),
    };
  },
);
```

### PHP

#### Filters

##### `mediapress_checklist_config_path`

Allows the adjustment of the checklist config JSON file location

**Parameters**

| Name | Type   | Description                      |
| ---- | ------ | -------------------------------- |
| path | string | The path to the config.json file |

**Usage**

```php
add_filter( 'mediapress_checklist_config_path', 'my_plugin_checklist_config_path' );
function my_plugin_checklist_config_path( string $path ): string {
  $path = __DIR__ . '/config/my-checklist-config.json';
  return $path;
}
```

##### `mediapress_checklist_config`

Filters the config immediately after the JSON file is parsed. Can be used by other features/plugins to introduce additional checks.

**Parameters**

| Name   | Type  | Description                 |
| ------ | ----- | --------------------------- |
| config | array | The parsed checklist config |

**Usage**

```php
/**
 * Adjust the config to include a custom check which be implemented in JS using 'mediaPress.checklist.item'
 */
add_filter( 'mediapress_checklist_config', 'adjust_config', 10, 1 );
function adjust_config( array $config ): array {
  $config['items'] = array_merge(
    $config['items'] ?? [],
    [
      [
        'name'      => 'my_plugin_has_custom_check',
        'title'     => __( 'My custom check', 'my-plugin' ),
        'type'      => 'custom',
        'postTypes' => [ 'post', 'page' ],
      ],
    ]
  );


  return $config;
}
```

## Was this helpful?

Thanks for the feedback!

```json
{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://developers.wpengine.com/#website","name":"WP Engine Product Documentation","url":"https://developers.wpengine.com/","description":"Resources for developing, deploying, and scaling on WP Engine.","inLanguage":"en-US","keywords":["API documentation","product documentation","headless WordPress","managed WordPress hosting"],"publisher":{"@id":"https://wpengine.com/#organization"}}]}
```
