-
-
Save microneer/abe764ae031e88c5b0919b661a0c8ff9 to your computer and use it in GitHub Desktop.
WordPress: Mandatory Excerpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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>" ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.