Статьи

Динамические шаблоны страниц в WordPress, часть 2

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

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

Я также покажу вам шаг за шагом, как расширить шаблон страницы из первого урока и превратить его в ваш самый первый работающий динамический шаблон страницы!

Итак, как мы можем сделать шаблоны страниц более гибкими, и почему это было бы полезно в любом случае?

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

Конечно, мы могли бы добавить еще один шаблон страницы для отображения портфелей разных размеров. Но что, если мы хотим показать маленькие, средние или большие портфели? Для этого нам понадобятся три отдельных шаблона страницы, каждый из которых имеет разные размеры для элементов портфолио.

Это можно было бы мгновенно сделать более гибким, добавив раскрывающийся элемент управления для выбора размера портфеля (например, «Маленький», «Средний» или «Большой»). Это более удобно для пользователя, так как поле шаблона страницы менее загромождено ненужными вариантами.

Это имеет больше смысла и для разработчика, у которого есть только один шаблон страницы для поддержки, а не три! Это следует принципу разработки программного обеспечения « Не повторяйся» (СУХОЙ).

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

Но, как вы увидите в конце этого урока, многие шаблоны страниц выиграют от большей гибкости.

Другим полезным примером для динамического шаблона страницы была бы форма контакта. Есть много пользовательских элементов управления, которые можно добавить, чтобы сделать этот шаблон страницы очень гибким.

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

Я буду создавать динамический шаблон страницы формы в третьей части этого урока. Но сначала давайте начнем с создания универсального динамического шаблона страницы.

Для начала мы создадим базовый динамический шаблон страницы, чтобы продемонстрировать, как все составные части сочетаются друг с другом. Пользовательские элементы управления будут добавлены в редактор страниц, который будет использоваться позже для управления выводом шаблона страницы.

Пользовательские элементы управления шаблонами страниц, которые мы вскоре добавим:

  • Текстовое окно
  • Textarea
  • Флажок
  • Радио-кнопки
  • Выпадающее окно выбора

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

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

Хуки являются фундаментом для разработки WordPress. Они позволяют разработчикам расширять базу кода, не прибегая к редактированию основных файлов, что обычно считается плохой идеей. Это связано с тем, что любой пользовательский код будет удален при каждом обновлении WordPress (что может происходить довольно регулярно).

Чтобы отобразить наше мета-поле на экране редактора страниц, добавьте load-post.php и load-post-new.php в метод дочерней темы init() который мы создали в load-post-new.php части.

1
2
3
4
5
<?php
add_action( ‘load-post.php’, array( $this, ‘page_template_meta_box’ ) );
add_action( ‘load-post-new.php’, array( $this, ‘page_template_meta_box’ ) );
add_action( ‘save_post’, array( $this, ‘save_page_template_meta’ ), 10, 2 );
}

Мы используем две ловушки WordPress, чтобы обеспечить отображение мета-блока в редакторе страниц, независимо от того, создаете ли вы новую страницу или редактируете существующую. Также есть хук save_post который обрабатывает сохранение метаданных save_post , о которых я расскажу чуть позже.

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

1
2
3
4
/* Add meta box hook.
public function page_template_meta_box() {
  add_action( ‘add_meta_boxes’, array( $this, ‘add_page_template_meta_box’ ) );
}
01
02
03
04
05
06
07
08
09
10
11
/* Register meta box.
public function add_page_template_meta_box() {
  add_meta_box(
    ‘page-template-meta-box’,
    esc_html__( ‘Page Template Meta Box’, ‘twenty-seventeen-child’ ),
    array( $this, ‘display_page_template_meta_box’ ),
    ‘page’,
    ‘side’,
    ‘default’
  );
}
1
2
3
4
/* Render meta box on the page editor.
public function display_page_template_meta_box($object) {
  wp_nonce_field( basename( __FILE__ ), ‘page_template_meta_box_nonce’ );
}

Я не буду вдаваться в подробности о мета-блоках WordPress, поскольку это может быть само учебное пособие, но обратите внимание на следующие моменты, касающиеся кода, который я добавил выше:

  • page_template_meta_box() и add_page_template_meta_box() регистрируют мета-поле в WordPress.
  • В add_page_template_meta_box() параметр 'page' указывает, что этот мета-блок будет отображаться только в редакторе типов add_page_template_meta_box() ‘page’ в администраторе WordPress.
  • Метод класса display_page_template_meta_box() визуализирует метаблок и устанавливает одноразовый номер, чтобы сделать элементы управления формы более безопасными.

Если все хорошо, теперь вы должны отобразить мета-поле в редакторе страниц, как показано ниже.

Новая мета-страница страницы

Хотя сейчас он немного пустой, поэтому давайте добавим некоторые элементы управления.

Если вы помните сверху, мы собираемся добавить текстовое поле, текстовую область, флажок, переключатель и выбрать элементы управления блока в мета-блок. Начните с добавления следующего кода в метод display_page_template_meta_box() под функцией nonce.

1
2
3
4
5
6
<?php
$text = get_post_meta( $object->ID, ‘page_template_text’, true );
$textarea = get_post_meta( $object->ID, ‘page_template_textarea’, true );
$checkbox = get_post_meta( $object->ID, ‘page_template_chk’, true );
$radio = get_post_meta( $object->ID, ‘page_template_radio’, true );
$select = get_post_meta( $object->ID, ‘page_template_select’, true );

Это извлекает текущие значения элементов управления нашего метабокса и сохраняет их в локальных переменных. Теперь добавьте следующий HTML-код непосредственно после, чтобы отобразить элементы управления мета-блока.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
?>
  <div>
    <p>
        <label for=»page-template-text»><?php _e( «Text Control», ‘twenty-seventeen-child’ );
        <input class=»widefat» type=»text» name=»page-template-text» id=»page-template-text» value=»<?php echo esc_attr( $text ); ?>» />
    </p>
 
    <p>
        <label for=»page-template-textarea»><?php _e( «Textarea Control», ‘twenty-seventeen-child’ );
        <textarea rows=»5″ class=»widefat» name=»page-template-textarea» id=»page-template-textarea»><?php echo esc_attr( $textarea );
    </p>
 
    <p>
        <input type=»checkbox» name=»page-template-chk» id=»page-template-chk» value=»1″ <?php checked($checkbox, true);
    </p>
 
    <p>
        <label for=»page-template-align»><?php _e( «Radio Button Control», ‘twenty-seventeen-child’ );
        <input type=»radio» name=»page-template-align» id=»rdo-left» value=»left» <?php checked( $radio, ‘left’ );
        <input type=»radio» name=»page-template-align» id=»rdo-right» value=»right» <?php checked( $radio, ‘right’ );
        <input type=»radio» name=»page-template-align» id=»rdo-center» value=»center» <?php checked( $radio, ‘center’ );
    </p>
 
    <p>
        <label for=»page-template-select»>Dropdown</label>
        <select name=»page-template-select» class=»widefat»>
            <option value=’one’ <?php selected( ‘one’, $select );
            <option value=’two’ <?php selected( ‘two’, $select );
            <option value=’three’ <?php selected( ‘three’, $select );
            <option value=’four’ <?php selected( ‘four’, $select );
        </select>
    </p>
</div><?php

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

Однако этого не произойдет, если мы не сохраним текущие данные элемента управления метабокса в базе данных WordPress.

Чуть раньше я зарегистрировал ловушку для выполнения метода класса при каждом обновлении редактора страниц. Давайте теперь добавим этот метод в наш класс дочерней темы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
/* Save meta box data.
public function save_page_template_meta( $post_id, $post ) {
 
    if ( ! ( isset( $_POST[ ‘page_template_meta_box_nonce’ ] ) && wp_verify_nonce( $_POST[ ‘page_template_meta_box_nonce’ ], basename( __FILE__ ) ) ) ) {
        return $post_id;
    }
 
    if ( ! current_user_can( ‘edit_post’, $post_id ) ) {
        return $post_id;
    }
 
    if( ‘page’ != $post->post_type ) {
        return $post_id;
    }
 
    $page_template_text_value = isset( $_POST[ ‘page-template-text’ ] ) ?
    update_post_meta( $post_id, ‘page_template_text’, $page_template_text_value );
 
    $page_template_textarea_value = isset( $_POST[ ‘page-template-textarea’ ] ) ?
    update_post_meta( $post_id, ‘page_template_textarea’, $page_template_textarea_value );
 
    $page_template_chk_value = isset( $_POST[ ‘page-template-chk’ ] ) ?
    update_post_meta( $post_id, ‘page_template_chk’, $page_template_chk_value );
 
    $page_template_radio_value = isset( $_POST[ ‘page-template-align’ ] ) ?
    update_post_meta( $post_id, ‘page_template_radio’, $page_template_radio_value );
 
    $page_template_select_value = isset( $_POST[ ‘page-template-select’ ]) ?
    update_post_meta( $post_id, ‘page_template_select’, $page_template_select_value );
}

save_page_template_meta() класса save_page_template_meta() обрабатывает сохранение управляющих данных save_page_template_meta() . Данные мета-бокса сохраняются только в том случае, если одноразовый номер подтвержден, текущие пользователи могут редактировать сообщения, и мы находимся на экране администратора редактора страниц.

Если эти условия выполняются, мы извлекаем данные для каждого элемента управления, которые хранятся в глобальной переменной $_POST . Эта переменная устанавливается каждый раз при отправке формы.

Наконец, данные мета-блока управления сохраняются в базе данных WordPress как метаданные для текущей страницы.

С добавлением пользовательских элементов управления шаблона страницы наше мета-окно должно выглядеть следующим образом.

Добавление элементов управления в мета-поле

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

Заполнение мета-блока

Полный исходный код для файла дочерней темы functions.php показан ниже.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
 
/**
 * Twenty Seventeen child theme class.
 *
 * DPT = D[ynamic] P[age] T[emplates].
 */
class DPT_Twenty_Seventeen_Child {
 
    /**
     * Register hooks.
     */
    public function init() {
        add_action( ‘wp_enqueue_scripts’, array( $this, ‘enqueue_parent_theme_styles’ ) );
        add_action( ‘load-post.php’, array( $this, ‘page_template_meta_box’ ) );
        add_action( ‘load-post-new.php’, array( $this, ‘page_template_meta_box’ ) );
        add_action( ‘save_post’, array( $this, ‘save_page_template_meta’ ), 10, 2 );
    }
 
    /* Enqueue parent theme styles.
    public function enqueue_parent_theme_styles() {
        wp_enqueue_style( ‘twenty-seventeen-css’, get_template_directory_uri() . ‘/style.css’ );
    }
 
    /* Add meta box hook.
    public function page_template_meta_box() {
      add_action( ‘add_meta_boxes’, array( $this, ‘add_page_template_meta_box’ ) );
    }
 
    /* Register meta box.
    public function add_page_template_meta_box() {
      add_meta_box(
        ‘page-template-meta-box’,
        esc_html__( ‘Page Template Meta Box’, ‘twenty-seventeen-child’ ),
        array( $this, ‘display_page_template_meta_box’ ),
        ‘page’,
        ‘side’,
        ‘default’
      );
    }
 
    /* Render meta box on the page editor.
    public function display_page_template_meta_box( $object ) {
 
      wp_nonce_field( basename( __FILE__ ), ‘page_template_meta_box_nonce’ );
 
      $text = get_post_meta( $object->ID, ‘page_template_text’, true );
      $textarea = get_post_meta( $object->ID, ‘page_template_textarea’, true );
      $checkbox = get_post_meta( $object->ID, ‘page_template_chk’, true );
      $radio = get_post_meta( $object->ID, ‘page_template_radio’, true );
      $select = get_post_meta( $object->ID, ‘page_template_select’, true );
      ?>
      <div>
        <p>
            <label for=»page-template-text»><?php _e( «Text Control», ‘twenty-seventeen-child’ );
            <input class=»widefat» type=»text» name=»page-template-text» id=»page-template-text» value=»<?php echo esc_attr( $text ); ?>» />
        </p>
 
        <p>
            <label for=»page-template-textarea»><?php _e( «Textarea Control», ‘twenty-seventeen-child’ );
            <textarea rows=»5″ class=»widefat» name=»page-template-textarea» id=»page-template-textarea»><?php echo esc_attr( $textarea );
        </p>
 
        <p>
            <input type=»checkbox» name=»page-template-chk» id=»page-template-chk» value=»1″ <?php checked($checkbox, true);
        </p>
 
        <p>
            <label for=»page-template-align»><?php _e( «Radio Button Control», ‘twenty-seventeen-child’ );
            <input type=»radio» name=»page-template-align» id=»rdo-left» value=»left» <?php checked( $radio, ‘left’ );
            <input type=»radio» name=»page-template-align» id=»rdo-right» value=»right» <?php checked( $radio, ‘right’ );
            <input type=»radio» name=»page-template-align» id=»rdo-center» value=»center» <?php checked( $radio, ‘center’ );
        </p>
 
        <p>
            <label for=»page-template-select»>Dropdown</label>
            <select name=»page-template-select» class=»widefat»>
                <option value=’one’ <?php selected( ‘one’, $select );
                <option value=’two’ <?php selected( ‘two’, $select );
                <option value=’three’ <?php selected( ‘three’, $select );
                <option value=’four’ <?php selected( ‘four’, $select );
            </select>
        </p>
      </div><?php
    }
 
    /* Save meta box data.
    public function save_page_template_meta( $post_id, $post ) {
 
      if ( ! ( isset( $_POST[ ‘page_template_meta_box_nonce’ ] ) && wp_verify_nonce( $_POST[ ‘page_template_meta_box_nonce’ ], basename( __FILE__ ) ) ) ) {
        return $post_id;
      }
 
      if ( ! current_user_can( ‘edit_post’, $post_id ) ) {
        return $post_id;
      }
 
      if( ‘page’ != $post->post_type ) {
        return $post_id;
      }
 
      $page_template_text_value = isset( $_POST[ ‘page-template-text’ ] ) ?
      update_post_meta( $post_id, ‘page_template_text’, $page_template_text_value );
 
      $page_template_textarea_value = isset( $_POST[ ‘page-template-textarea’ ] ) ?
      update_post_meta( $post_id, ‘page_template_textarea’, $page_template_textarea_value );
 
      $page_template_chk_value = isset( $_POST[ ‘page-template-chk’ ] ) ?
      update_post_meta( $post_id, ‘page_template_chk’, $page_template_chk_value );
 
      $page_template_radio_value = isset( $_POST[ ‘page-template-align’ ] ) ?
      update_post_meta( $post_id, ‘page_template_radio’, $page_template_radio_value );
 
      $page_template_select_value = isset( $_POST[ ‘page-template-select’ ]) ?
      update_post_meta( $post_id, ‘page_template_select’, $page_template_select_value );
    }
}
 
$ts_child_theme = new DPT_Twenty_Seventeen_Child();
$ts_child_theme->init();

Последняя часть головоломки заключается в использовании данных элемента управления метабокса в нашем шаблоне страницы на переднем крае. Откройте файл test-page-template.php который мы создали в первой части, и замените содержимое этим обновленным кодом.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
/**
 * Template Name: Test Page Template
 *
 * @package WordPress
 * @subpackage Twenty_Seventeen
 * @since 1.0
 */
 
get_header();
 
<div class=»wrap»>
    <div id=»primary» class=»content-area»>
        <main id=»main» class=»site-main» role=»main»>
 
            <?php
            while ( have_posts() ) : the_post();
 
                $text = get_post_meta( get_the_ID(), ‘page_template_text’, true );
                $textarea = get_post_meta( get_the_ID(), ‘page_template_textarea’, true );
                $checkbox = get_post_meta( get_the_ID(), ‘page_template_chk’, true );
                $radio = get_post_meta( get_the_ID(), ‘page_template_radio’, true );
                $select = get_post_meta( get_the_ID(), ‘page_template_select’, true );
 
                echo «<p>Text Box: » .
                echo «<p>Text Area: » .
                echo «<p>Checkbox: » .
                echo «<p>Radio Buttons: » .
                echo «<p>Dropdown: » .
 
                echo «<h2>Sitemap</h2>»;
                echo «<ul>» .
 
            endwhile;
            ?>
 
        </main><!— #main —>
    </div><!— #primary —>
</div><!— .wrap —>
 
<?php get_footer();

Убедитесь, что «Шаблон тестовой страницы» является текущим выбранным шаблоном страницы, и просмотрите страницу в интерфейсе пользователя.

Просмотр вывода мета-блока

Как видите, шаблон страницы теперь содержит значения, только что установленные для элементов управления мета-поля в редакторе страниц. Это ядро ​​остальной части руководства, поскольку мы будем опираться на этот базовый пример и создадим различные примеры полностью работающих динамических шаблонов страниц, которые вы можете использовать в своих собственных проектах WordPress.

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

В третьей и последней части этой серии руководств я покажу вам, как создавать различные динамические шаблоны страниц, от начала до конца, которые вы можете использовать (и расширять) в своих собственных проектах WordPress.

Если у вас есть какие-либо вопросы, пожалуйста, оставьте мне сообщение в комментариях ниже. Я хотел бы услышать ваши мысли по поводу урока.