Skip to content

Instantly share code, notes, and snippets.

@microneer
Forked from swalkinshaw/gist:2695510
Last active November 16, 2017 14:52
Show Gist options
  • Save microneer/abe764ae031e88c5b0919b661a0c8ff9 to your computer and use it in GitHub Desktop.
Save microneer/abe764ae031e88c5b0919b661a0c8ff9 to your computer and use it in GitHub Desktop.
WordPress: Mandatory Excerpt
// put this in functions.php or in your custom plugin or theme code.
$m = new Mandatory_Excerpt()
$m->add('post', 20 ); // will require all 'post' post types to have an excerpt at least 20 characters long
/**
* Helper class which removes specified metaboxes from specified pages. It manages setting up the hooks
* and calling them.
*
* @author: Michael Fielding
*
* Usage:
* $me = new Mandatory_Excerpt()
* $me->add('post', 20 )
* ->add('my_custom_post', 44); // repeat as needed
*/
class Mandatory_Excerpt {
private $min_lengths = [];
// set up the hooks we'll need
public function __construct() {
add_filter('wp_insert_post_data', [$this,'do_mandatory_excerpt']);
add_action('admin_notices', [$this,'do_admin_notice']);
}
public function add( $post_type, $minimum_excerpt_length = 0 ){
$this->min_lengths[$post_type] = $minimum_excerpt_length;
return $this;
}
// handler for wp_insert_post_data hook
public function do_mandatory_excerpt( $data ) {
$post_type = $data['post_type'];
// if there's a minimum excerpt length set for this post type, check it
if ( isset($this->min_lengths[$post_type]) ) {
$min_length = $this->min_lengths[$post_type];
$excerpt = $data['post_excerpt'];
if ( empty($excerpt) || strlen($excerpt)<$min_length ) {
// if user was trying to publish the post, show a warning
if ($data['post_status'] === 'publish') {
// add a filter to intercept the post-save redirect and show a message
add_filter('redirect_post_location', [$this,'do_error_message_redirect'], 10, 2);
}
// ensure it's not published
if ('deleted' !== $data['post_status'] && 'trash' !== $data['post_status']) {
$data['post_status'] = 'draft';
}
}
}
return $data;
}
// intercept the after-save redirect and ensure a message will be shown on the following page
public function do_error_message_redirect($location,$post_id) {
remove_filter('redirect_post_location', [$this,'do_error_message_redirect'], 10, 2);
$post_type = get_post_type( $post_id );
if ( isset($this->min_lengths[$post_type]) ) {
$min_length = $this->min_lengths[$post_type];
// add a query variable to display our admin notice
$location = add_query_arg('excerpt_not_long_enough', $min_length, $location);
// remove the post saved message
$location = remove_query_arg( 'message', $location );
}
return $location;
}
/**
* Show a warning or error that the excerpt is required, if it is not manually defined for something where it's required.
*/
public function do_admin_notice() {
// show a warning or error if there is no custom excerpt on a type where there should be
$screen = get_current_screen();
if ( $screen != NULL && $screen->base == 'post' && isset($this->min_lengths[$screen->post_type]) ) {
$min_length = $this->min_lengths[$screen->post_type];
$post_id = $_GET['post'];
if ( !has_excerpt($post_id) || strlen(get_the_excerpt($post_id)) < $min_length ) {
$this->echo_admin_notice(['Cannot publish this until a hand-written Excerpt of at least ',$min_length,' characters is provided.'], 'warning');
}
// check if the excerpt not long enough message was requested by being put in the query string
if (isset($_GET['excerpt_not_long_enough'])) {
$this->echo_admin_notice(['Publication failed because the Excerpt wasn\'t ',$min_length,' characters or more.']);
}
}
}
/**
* Show an admin message. Should be called in an admin_notices hook.
* @param string|array(string) $text The notice to show. This is passed through _e() for translation.
* Can be an array, in which case each string is concatenated after passing thru _e(), which allows
* parameters to be embedded.
* @param string $class error|warning|success|info
* @param boolean $is_dismissable If true, then the notice has an X to dismiss it.
*/
private function echo_admin_notice( $text, $class = 'error', $is_dismissable = true ) {
$dismissable = $is_dismissable ? 'is-dismissable' : '';
echo "<div class=\"notice notice-$class $dismissable\"><p>";
foreach( (array)$text as $t ) {
_e($t);
}
echo( "</p></div>" );
}
}
@darinronne
Copy link

Thanks for this. I needed to make the excerpt required on The Events Calendar events.

I found an error on lines 2 and 12: missing semicolons.
That broke the code for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment