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');
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');
Share
Improve this question
edited Nov 25, 2013 at 16:41
Chris
asked Nov 25, 2013 at 16:14
ChrisChris
4532 gold badges15 silver badges31 bronze badges
3
- Please edit your question to include the code in your question, rather than linking to a third-party site. – Chip Bennett Commented Nov 25, 2013 at 16:21
- Sorry Chip. I've edited it now. I just thought it was the best way to give the author credit. – Chris Commented Nov 25, 2013 at 16:41
- The alert message is not displayed in Gutenberg (Wordpress 5). – Rodrigo Vieira Commented Jan 2, 2019 at 22:16
4 Answers
Reset to default 5The 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;
}
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;
}
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;
}
It seems the above solution did not work so well for me (as @slowaways mentioned earlier, with WordPress 5+). So I came up with a new solution. Since I am using ACF, I created a new 'short description' field ('extrait') and made it mandatory. So I can use the validation features of ACF, and update excerpt value on the fly :
/**
* Set excerpt from ACF field
*/
add_action('acf/save_post', function($post_id) {
$post_excerpt = get_field( 'extrait', $post_id );
if ( ( !empty( $post_id ) ) AND ( $post_excerpt ) ) {
// Update post options array
$update_post_excerpt_args = array(
'ID' => $post_id,
'post_excerpt' => $post_excerpt,
);
wp_update_post( $update_post_excerpt_args );
}
}, 50);
To give credit where credit is due i found this code here : https://gist.github/MWDelaney/fd0bed89b891e3ff0850428703786397
Hope this helps.