Обязательная выдержка для пользовательского типа записи


Это оказывается непростой задачей.

Я пытаюсь сделать отрывок обязательным полем, но только при редактировании/сохранении записи в пользовательском типе записи.

Следующий код делает выдержку обязательным полем для всех записей, но не учитывает сужение ее влияния до одного пользовательского типа записи.

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');
Author: Chris, 2013-11-25

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;
}
 5
Author: Chip Bennett, 2013-11-25 16:27:04

Решение проблемы с невозможностью удаления или даже публикации сообщений заключается в добавлении дополнительной проверки, чтобы убедиться, что функция 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;
}
 1
Author: Jelle Wielsma, 2016-11-17 16:09:25

У меня недостаточно репутации на этом сайте, чтобы комментировать.

Обратите внимание, что в используемом вами коде нет соответствующих проверок статуса публикации. В результате ваша панель администратора будет заполнена множеством автоматических черновиков, которые обычно пусты, и которые никогда не будут очищены.

Простое решение состоит в том, чтобы сделать что-то вроде:

    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;
    }
 0
Author: Jamie, 2017-09-26 19:29:01

Похоже, вышеприведенное решение не сработало для меня так хорошо (как упоминалось ранее @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

Надеюсь, это поможет.

 0
Author: Cypher, 2021-01-27 00:01:10