Дуже часто зустрічаю дизайни сайтів у яких зовнішній вигляд, наприклад, рубрики “Новини IT” та “Новини освіти” відрізняються. У CSM WordPress можна створювати окремі шаблони для рубрик, але для цього потрібно редагувати файли теми. Створити один нестандартний шаблон для кількох категорій не вдасться, т.z. імена файлів повинні відповідати ідентифікатору або ярлику, а вони є унікальними.

Динамічна зміна шаблону у вигляді списку, що випадає, доступна в консолі тільки для постів і сторінок. Хотілося б щоб у консолі під час створення та редагування рубрики можна було швидко вибрати потрібний шаблон і використовувати його для різних рубрик одночасно. У статті буде розглянуто приклад додавання такого функціоналу для стандартних рубрик WordPress.

Реалізація

Ім’я файлу шаблону сторінки або поста зберігається у метаполі _wp_page_template таблиці БД wp_postmeta. При виборі шаблону WordPress отримує значення цього поля та підключає потрібний файл. Докладніше про шаблони сторінок WordPress можна прочитати тут: 3 способи створення шаблону сторінки.

Для категорій використовуємо такий алгоритм роботи, це:

  1. Отримати список шаблонів у файлах теми
  2. Додати поле з вибором шаблону на сторінці створення та редагування рубрики
  3. Зберегти поле з вибраним шаблоном у метаданих рубрики
  4. У публічній частині сайту замінити шаблон за замовчуванням на нестандартний

Список шаблонів

У WordPress є список відповідних назв файлів, кожна з назв перевіряється по черзі на фізичне існування такого файлу. Як тільки WordPress бачить, що файл існує пошук припиняється і знайдений файл використовується як шаблон. Ієрархія шаблонів та порядок їх вибору для рубрик wordpress такий:

  1. category-{ярлык}.php
  2. category-{id}.php
  3. category.php
  4. archive.php
  5. paged.php
  6. index.php

Докладніше про ієрархію шаблонів: Ієрархія файлів об’єкта (шаблону)

Список файлів шаблонів рубрик можна вписати в код у вигляді змінної під час створення теми, а можна отримати динамічно. Мені більше подобається другий варіант. Для цього створимо окрему функцію, яку підключимо до фільтра category_custom_templates, це дозволить отримувати список імен файлів і при необхідності змінювати його в інших частинах теми.

Для отримання списку файлів можна використовувати функцію php glob (докладніше https://www.php.net/manual/ru/function.glob.php), аргументом функції буде шлях до директорії теми і шаблон імені файлу для пошуку.

Шлях до директорії теми отримаємо за допомогою функції get_stylesheet_directory().

Ім’я файлу сформуємо за аналогією перших двох зі списку, тобто такого формату category-{*}.php, де * – назва шаблону. Це дозволить додати динамічний вибір у консолі та зберегти стандартний функціонал WordPress, при якому шаблон обирається за допомогою ярлика (tem_id) та ідентифікатора рубрики (slug).

<?php

/**
 * Отримання списку шаблонів
 * */
function get_category_templates( $templates ) {
  $theme_path = get_stylesheet_directory();
  $templates = array_merge( $templates, array_map( 'basename', glob( $theme_path . '/category-*.php', GLOB_BRACE ) ) );
  return $templates;
}

add_filter( 'category_custom_templates', 'get_category_templates', 10, 1 );

Додавання поля

Для додавання довільних полів в адмінці рубрик передбачено два хуки. Перший виводь html-верстку у формі створення категорії та другий у формі редагування:

  • category_add_form_fields – хук для виведення додаткових полів у форму редагування категорії;
  • category_edit_form_fields – хук для виведення додаткових полів у форму редагування категорії.

category – ідентифікатор таксономії, який можна замінити, наприклад, product_cat для WooCommerce.

Верстка двох форм відрізняється, тому потрібно створити дві різні функції.

<?php

/**
 * Додавання поля для вибору шаблону у формі редагування категорії
 */
function edit_category_custom_template( $term ) {

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

  // получаем список созданных шаблонов
  $templates = apply_filters( 'category_custom_templates', [] );

  // формируем html-код поля выбора сайдбара

  if ( is_array( $templates ) && ! empty( $templates ) ) : ?>
    <tr class="form-field">
      <th scope="row" valign="top">
        <label for="custom_template"><?php _e( 'Шаблон', THEME_TEXTDOMAIN ); ?></label>
      </th>
      <td>
        <select class="resume-control" id="custom_template" name="custom_template">
          <option value=""><?php _e( 'Стандартный шаблон', THEME_TEXTDOMAIN ); ?></option>
          <?php foreach ( $templates as $value ) : ?>
            <option value="<?php echo $value; ?>" <?php selected( $custom_template, $value, true ); ?> ><?php echo $value; ?></option>
          <?php endforeach; ?>
        </select>
      </td>
    </tr>
  <?php endif;
}

add_action( 'category_edit_form_fields', 'edit_category_custom_template' );


<?php

/**
 * Додавання поля для вибору шаблону у формі СТВОРЕННЯ категорії
 */
function add_category_custom_template( $taxonomy_slug ) {

  // получаем список созданных шаблонов
  $templates = apply_filters( 'category_custom_templates', [] );

  // формируем html-код поля выбора сайдбар
  if ( is_array( $templates ) && ! empty( $templates ) ) : ?>
    <div class="form-field">
      <label for="custom_template"><?php _e( 'Шаблон', THEME_TEXTDOMAIN ); ?></label>
      <select class="resume-control" id="custom_template" name="custom_template">
        <option value=""><?php _e( 'Стандартный шаблон', THEME_TEXTDOMAIN ); ?></option>
        <?php foreach ( $templates as $value ) : ?>
          <option value="<?php echo $value; ?>" ><?php echo $value; ?></option>
        <?php endforeach; ?>
      </select>
    </div>
  <?php endif;
}

add_action( 'category_add_form_fields', 'add_category_custom_template' );

Збереження шаблону

Збереження даних рубрики під час створення та редагування відбувається під час роботи різних хуків, це

  • create_category
  • edited_category

Алгоритм роботи у них однаковий, тому можна створити одну функцію та підключити її до обох хуків. Функція робитиме таке:

  1. перевірить чи має поточний користувач права на редагування категорії
  2. перевірить nonce-поле безпеки
  3. провалідує (очистить) ідентифікатор шаблону із глобального масиву $_POST
  4. збереже або видаляє ідентифікатор шаблону з метаданих категорії
<?php

/**
 * Функція збереження ідентифікатора прикріпленого шаблону у метаполі категорії
 */
function save_category_custom_template( $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_template = ( isset( $_POST[ 'custom_template' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'custom_template' ] ) ) : '';
  if ( empty( $custom_template ) ) {
    delete_term_meta( $term_id, '_custom_template' );
  } else {
    update_term_meta( $term_id, '_custom_template', $custom_template );
  }
  return $term_id;
}

add_action( 'create_category', 'save_category_custom_template' );
add_action( 'edited_category', 'save_category_custom_template' );

Заміна шаблону

Для динамічної заміни шаблону використовується хук template_include. Фільтр спрацьовує після події template_redirect і після того, як WordPress підбере файл, який використовуватиметься як файл шаблону.

/**
 * Заміна шаблону у публічній частині сайту
 * */
function category_custom_template_include( $default_template ) {
  if ( is_category() ) {
    $category = get_queried_object();
    $custom_template = get_term_meta( $category->term_id, '_custom_template', true );
    $templates = apply_filters( 'category_custom_templates', [] );
    if ( ! empty( $custom_template ) && in_array( $custom_template, $templates ) ) {
      $default_template = get_stylesheet_directory() . '/' . $custom_template;
    }
  }
  return $default_template;
}

add_filter( 'template_include', 'category_custom_template_include' );

Висновок

Розглянуто приклад додавання динамічного списку вибору шаблону для категорій.

Посилання на git з повним кодом: category-templates.php

Код необхідно підключити до файлу functions.php теми. Код можна модифікувати і використовувати не тільки для стандартних рубрик WordPress, але і для користувацьких таксономій.

52голосів
Рейтинг статті
Підписатися
Сповістити про
guest
0 Коментарі
Вбудовані Відгуки
Переглянути всі коментарі
0
Ми любимо ваші думки, будь ласка, прокоментуйте.x
()
x