Третья часть продолжение статьи про создание кастомных сайдбаров в WordPress-теме. В этой части рассмотрен процесс добавление формы для выбора сайдбара при редактировании страниц и категорий.

Предыдущие посты:

Ранее был рассмотрен процесс создания кастомных сайдбаров и подмена стандартного сайдбара в публичной части сайта. Остатаётся только привязать идентификатор созданного сайдбара к страницам и категориям.

Идентификатор сайдбара хранится в метаданных. Метаданные категорий и страниц хранятся в разных таблицах базы данных. Поэтому код для категорий и страниц будет отличаться, но смысл его работы одинаков, это:

  1. создание формы в которой редактор сайта выберет сайдбар
  2. скрипт для сохранения выбранного сайдбара в базе данных.

Выбор сайдбара для страниц

Для создания дополнительных полей и форм при редактировании страниц в WordPress предусмотрены метабоксы. Соответственно форма выбора сайдбара будет находиться в таком метабоксе.

Создание метабокса

Для того, чтобы метабокс появился на странице редактирования его нужно зарегистрировать (создать) в WordPress и добавить функцию для вывода его содержимого. Метабокс регистрируется с помощью функции ядра WordPress add_meta_box (подробное описание https://wp-kama.ru/function/add_meta_box).

Содержимым метабокса в нашем случае будет поле формы в виде выпадающего списка сайдбаров. Нужно обратить внимание, что содержимое метабокса и выпадающий список не нужно обрамлять в тег form, т.к. на странице он уже присутствует “глобально”.


<?php

/**
 * Регистранцая сайдбара
 */
function add_custom_columns_meta_box() {
  add_meta_box(
    RESUME_SLUG . '_custom_columns',
    __( 'Пользовательские колонки', RESUME_TEXTDOMAIN ),
    'resume\render_custom_columns_meta_box',
    array( 'page' ),
    'side'
  );
}
add_action( 'add_meta_boxes', 'add_custom_columns_meta_box' );



/**
 * Функция для формирования с вывода контента метабокса
 */
function render_custom_columns_meta_box( $post, $meta ) {
  global $wp_registered_sidebars;

  // Получает или выводит скрытое одноразовое поле для защиты (валидации) формы
  wp_nonce_field( plugin_basename( __FILE__ ), 'custom_columns_noncename' );

  // получаем текущий прикреплёный к странице сайдбар
  $custom_columns = get_post_meta( $post->ID, '_custom_columns', true );

  // получаем список созданных сайдбаров из настроек темы
  $register_columns = get_theme_mod( 'register_columns', [] );

  // если сайдбары созданы, то формируем контент метабокса
  if ( ! empty( $register_columns ) ) : ?>
    <name class="resume-name" for="custom_columns"><?php _e( 'Выбрать сайдбар', RESUME_TEXTDOMAIN ); ?></name>
    <select class="resume-control" id="custom_columns" name="custom_columns">
      <option value=""><?php _e( 'Стандартная колонка', RESUME_TEXTDOMAIN ); ?></option>
      <?php foreach ( $register_columns as $column ) : ?>
        <option value="<?php echo $column[ 'id' ]; ?>" <?php selected( $custom_columns, $column[ 'id' ], true ); ?> ><?php echo $column[ 'name' ]; ?></option>
      <?php endforeach; ?>
    </select>
  <?php endif;
}

Сохранение данных

Сохранение страницы происходит в хуке save_post. Во время его работы необходимо записать идентификатор садбара в метаданные страницы. Все поля формы редактирования страницы будут доступны в глобальном массиве $_POST. Соответственно нужно проверить имеет ли пользователь права на редактирование поста, выбрать из массива $_POST нужное поле, провалидировать его и сохранить.


<?php

/**
 * Функция сохранения идентификатора прикреплённого сайдбара в метаполе страницы
 */
function save_custom_columns_metadata( $post_id ) {

  // проверяем код защиты созданный функцией wp_nonce_field
  if ( ! isset( $_POST[ 'custom_columns_noncename' ] ) ) return;
  if ( ! wp_verify_nonce( $_POST[ 'custom_columns_noncename' ], plugin_basename( __FILE__ ) ) ) return;

  // исключаем автосохранение
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

  // проверяем усть ли у текущего пользователя права на редактирование страницы
  if ( ! current_user_can( 'edit_post', $post_id ) ) return;

  // валидируем полученный идентификатор сайдбара перед сохранением
  $custom_columns = sanitize_text_field( $_POST[ 'custom_columns' ] );

  // проверям что осталось после валидации и если идентификатор существует, то сохроаняем его, в противном случае - удаляем
  if ( empty( $custom_columns ) ) {
    delete_post_meta( $post_id, '_custom_columns' );
  } else {
    update_post_meta( $post_id, '_custom_columns', $custom_columns );
  }
}
add_action( 'save_post', 'save_custom_columns_metadata' );

Выбор сайдбара для категорий

Алгоритм добавления формы выбора сайдбара для категорий такой же как и для страниц, это создать дополнительное поле select со списком сайдбаров, а затем сохранить идентификатор выбранного сайдбара.

Дополнительные поля формы

У категорий в консоли предусмотрено две формы, это

  • форма создания категории
  • форма редактирования категории.

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

<?php

/**
 * Добавление поля для выбора сайдбара в форме РЕДАКТИРОВАНИЯ категории
 */
function edit_category_custom_columns( $term ) {

  // получаем идентификатор уже прикреплённого к категории сайдбара
  $custom_columns = get_term_meta( $term->term_id, '_custom_columns', true );

  // получаем список созданных сайдбаров из настроек темы
  $register_columns = get_theme_mod( 'register_columns', [] );

  // формируем html-код поля выбора сайдбара
  ?>
    <tr class="form-field">
      <th scope="row" valign="top">
        <label for="custom_columns"><?php _e( 'Выбрать сайдбар', RESUME_TEXTDOMAIN ); ?></label>
      </th>
      <td>
        <select class="resume-control" id="custom_columns" name="custom_columns">
          <option value=""><?php _e( 'Стандартная колонка', RESUME_TEXTDOMAIN ); ?></option>
          <?php foreach ( $register_columns as $column ) : ?>
            <option value="<?php echo $column[ 'id' ]; ?>" <?php selected( $custom_columns, $column[ 'id' ], true ); ?> ><?php echo $column[ 'name' ]; ?></option>
          <?php endforeach; ?>
        </select>
      </td>
    </tr>
  <?php
}
add_action( 'category_edit_form_fields', 'edit_category_custom_columns' );



/**
 * Добавление поля для выбора сайдбара в форме СОЗДАНИЯ категории
 */
function add_category_custom_columns( $taxonomy_slug ) {

  // получаем список созданных сайдбаров из настроек темы
  $register_columns = get_theme_mod( 'register_columns', [] );

  // формируем html-код поля выбора сайдбар
  ?>
    <div class="form-field">
      <label for="custom_columns"><?php _e( 'Выбрать сайдбар', RESUME_TEXTDOMAIN ); ?></label>
      <select class="resume-control" id="custom_columns" name="custom_columns">
        <option value=""><?php _e( 'Стандартная колонка', RESUME_TEXTDOMAIN ); ?></option>
        <?php foreach ( $register_columns as $column ) : ?>
          <option value="<?php echo $column[ 'id' ]; ?>" ><?php echo $column[ 'name' ]; ?></option>
        <?php endforeach; ?>
      </select>
    </div>
  <?php
}
add_action( 'category_add_form_fields', 'add_category_custom_columns' );

Сохранение полей формы

Сохранение данных категории при создании и редактировании происходит во время работы разных хуков, это

  • create_category
  • edited_category

Алгоритм работы при этом одинаковый, поэтому можно создать одну функцию, но подключить её к обоим хукам. Функция будет делать следующее:

  1. проверит имеет ли текущий пользователь права на редактирование категории
  2. проверит nonce-поле безопасности
  3. провалидировать идентификатор сайдбара из глобального массива $_POST
  4. сохранить или удалить идентификатор из метаданных категории
<?php

/**
 * Функция сохранения идентификатора прикреплённого сайдбара в метаполе категории
 */
function save_category_custom_columns( $term_id ) {
  if ( ! current_user_can( 'edit_term', $term_id ) ) return;
  if (
    ( isset( $_POST[ '_wpnonce' ] ) && ! wp_verify_nonce( $_POST[ '_wpnonce' ], "update-tag_$term_id" ) ) ||
    ( isset( $_POST[ '_wpnonce_add-tag' ] ) && ! wp_verify_nonce( $_POST[ '_wpnonce_add-tag' ], "add-tag" ) )
  ) return;
  $custom_columns = ( isset( $_POST[ 'custom_columns' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'custom_columns' ] ) ) : '';
  if ( empty( $custom_columns ) ) {
    delete_term_meta( $term_id, '_custom_columns' );
  } else {
    update_term_meta( $term_id, '_custom_columns', $custom_columns );
  }
  return $term_id;
}
add_action( 'create_category', 'save_category_custom_columns' );
add_action( 'edited_category', 'save_category_custom_columns' );

Вывод

Полный код доступен по ссылке https://github.com/chomovva/resume/blob/master/includes/custom-columns.php

51голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x
()
x