Обязательная выдержка для пользовательского типа записи
Это оказывается непростой задачей.
Я пытаюсь сделать отрывок обязательным полем, но только при редактировании/сохранении записи в пользовательском типе записи.
Следующий код делает выдержку обязательным полем для всех записей, но не учитывает сужение ее влияния до одного пользовательского типа записи.
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');
4 answers
Код добавляет фильтр к wp_insert_post_data
:
add_filter('wp_insert_post_data', 'mandatory_excerpt');
И вот обратный вызов:
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;
}
Обратный вызов фильтра передается $data
, который в соответствии с Кодексом включает следующие данные post:
'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'
Эти данные включают 'post_type'
, что означает, что вы можете использовать их внутри обратного вызова:
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;
}
Решение проблемы с невозможностью удаления или даже публикации сообщений заключается в добавлении дополнительной проверки, чтобы убедиться, что функция mandatory_excerpt()
срабатывает только в том случае, если не предусмотрено $_GET['action']
. В противном случае функция всегда будет возвращать ошибку при удалении публикации или изменении ее статуса публикации.
Таким образом, измененная функция будет:
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;
}
У меня недостаточно репутации на этом сайте, чтобы комментировать.
Обратите внимание, что в используемом вами коде нет соответствующих проверок статуса публикации. В результате ваша панель администратора будет заполнена множеством автоматических черновиков, которые обычно пусты, и которые никогда не будут очищены.
Простое решение состоит в том, чтобы сделать что-то вроде:
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;
}
Похоже, вышеприведенное решение не сработало для меня так хорошо (как упоминалось ранее @slowaways, с WordPress 5+). Поэтому я придумал новое решение. Поскольку я использую ACF, я создал новое поле "краткое описание" ("дополнительное") и сделал его обязательным. Таким образом, я могу использовать функции проверки ACF и обновлять значение выдержки на лету:
/**
* 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);
Чтобы отдать должное там, где это необходимо, я нашел этот код здесь : https://gist.github.com/MWDelaney/fd0bed89b891e3ff0850428703786397
Надеюсь, это поможет.