5

This is proving to be a challenge.

I'm trying to make the excerpt a required field, but only when editing/saving a post in a custom post type.

The following code makes the excerpt a required field for all posts, but doesn't take into account for narrowing its affect to a single custom post type.

function mandatory_excerpt($data) {
  $excerpt = $data['post_excerpt'];

  if (empty($excerpt)) {
    if ($data['post_status'] === 'publish') {
      add_filter('redirect_post_location', 'excerpt_error_message_redirect', '99');
    }

    $data['post_status'] = 'draft';
  }

  return $data;
}

add_filter('wp_insert_post_data', 'mandatory_excerpt');

function excerpt_error_message_redirect($location) {
  remove_filter('redirect_post_location', __FILTER__, '99');
  return add_query_arg('excerpt_required', 1, $location);
}

function excerpt_admin_notice() {
  if (!isset($_GET['excerpt_required'])) return;

  switch (absint($_GET['excerpt_required'])) {
    case 1:
      $message = 'Excerpt is required to publish a post.';
      break;
    default:
      $message = 'Unexpected error';
  }

  echo '<div id="notice" class="error"><p>' . $message . '</p></div>';
}

add_action('admin_notices', 'excerpt_admin_notice');
  • Please edit your question to include the code in your question, rather than linking to a third-party site. – Chip Bennett Nov 25 '13 at 16:21
  • Sorry Chip. I've edited it now. I just thought it was the best way to give the author credit. – Chris Nov 25 '13 at 16:41
  • The alert message is not displayed in Gutenberg (Wordpress 5). – Slowaways Jan 2 '19 at 22:16
5

The code adds a filter to wp_insert_post_data:

add_filter('wp_insert_post_data', 'mandatory_excerpt');

And here's the callback:

function mandatory_excerpt($data) {
  $excerpt = $data['post_excerpt'];

  if (empty($excerpt)) {
    if ($data['post_status'] === 'publish') {
      add_filter('redirect_post_location', 'excerpt_error_message_redirect', '99');
    }

    $data['post_status'] = 'draft';
  }

  return $data;
}

The filter callback is passed $data, which as per the Codex includes the following post data:

'post_author',
'post_date',
'post_date_gmt',
'post_content',
'post_content_filtered',
'post_title',
'post_excerpt',
'post_status',
'post_type',
'comment_status',
'ping_status',
'post_password',
'post_name',
'to_ping',
'pinged',
'post_modified',
'post_modified_gmt',
'post_parent',
'menu_order',
'guid'

Those data include 'post_type', which means you can use that inside the callback:

function mandatory_excerpt($data) {
    if ( 'custom-posttype-slug' != $data['post_type'] ) {
        return $data;
    } else {
        $excerpt = $data['post_excerpt'];

        if (empty($excerpt)) {
            if ($data['post_status'] === 'publish') {
                add_filter('redirect_post_location', 'excerpt_error_message_redirect', '99');
            }     
            $data['post_status'] = 'draft';
        }
    }     
    return $data;
}
  • Fantastic, Chip! I never thought it would be so easy (when you know how). – Chris Nov 25 '13 at 16:46
  • One issue I'm having with the above code, is if I try to trash a post with draft status, it remains in draft and does not move to trash. – Chris Nov 26 '13 at 8:30
  • That would be a separate question with what the code itself is actually doing. – Chip Bennett Nov 26 '13 at 12:49
  • What should excerpt_error_message_redirect be? Is that the name of a function? It's not clear how to actually display the message. – emersonthis Jun 14 '16 at 1:40
  • The alert message is not displayed in Gutenberg (Wordpress 5). – Slowaways Jan 2 '19 at 22:17
1

The solution to the problem with posts not being able to be removed or even published is adding an extra check to make sure the mandatory_excerpt() function only fires when there is no $_GET['action'] provided. Otherwise, the function will always return an error when removing a post or changing it's publish status.

So the altered function would be:

function mandatory_excerpt($data) {
    if ( 'custom-post-type-here' != $data['post_type'] || $_GET['action'] ) {
        return $data;
    } else {
        $excerpt = $data['post_excerpt'];

        if (empty($excerpt)) {
            if ($data['post_status'] === 'publish') {
                add_filter('redirect_post_location', 'bstcm_excerpt_error_message_redirect', '99');
            }     
            $data['post_status'] = 'draft';
        }
    }     
    return $data;
}
0

I don't have enough reputation on this site to comment.

Note that the code you're using doesn't have the appropriate checks for the post status. As a result, your admin dashboard will fill up with lots of Auto Drafts which are usually empty, which will never be cleaned up.

A simple fix is to do something like:

    function mandatory_excerpt($data) {
            if (empty($data['post_excerpt']) && $data['post_type'] != 'custom-post-type' && !isset($_GET['action'])) {

                    if ($data['post_status'] === 'publish') {
                            add_filter('redirect_post_location', 'excerpt_error_message_redirect', '99');
                    }

                    if ($data['post_status'] == 'publish' || $data['post_status'] == 'future' || $data['post_status'] == 'pending') {
                            $data['post_status'] = 'draft';
                    }
            }

            return $data;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.