WordPress. Theme Customize API. Часть 11

21.04.2019

Теги: APICMSWeb-разработкаWordPressНастройка

WordPress из коробки предоставляет множество элементов управления: text (простое поле ввода), textarea (поле для ввода большого текста), checkbox (переключатель), radio (группа переключателей), select (выпадающий список) и другие. Но иногда этого не хватает и возникает необходимость в создании своих элементов управления. Давайте посмотрим, как это можно сделать.

Создадим настройку, которая позволит фильтровать последние записи блога, показывая только посты выбранной категории. Для этого создаем файл My_Dropdown_Taxonomy_Control.php в директории customize и добавляем в него код:

<?php
class My_Dropdown_Taxonomy_Control extends WP_Customize_Control {

    public $type = 'dropdown-taxonomy';
    protected $taxonomy = 'category';

    protected function render_content() {
        $input_id = '_customize-input-' . $this->id;
        $description_id = '_customize-description-' . $this->id;
        ?>

        <?php if (!empty($this->label)): ?>
            <label for="<?php echo esc_attr($input_id); ?>"
                   class="customize-control-title">
                <?php echo esc_html($this->label); ?>
            </label>
        <?php endif; ?>
        <?php if (!empty($this->description)) : ?>
            <span id="<?php echo esc_attr($description_id); ?>"
                  class="description customize-control-description">
                <?php echo $this->description; ?>
            </span>
        <?php endif; ?>

        <?php
        $show_option_none = '&mdash; Выберите &mdash;';
        $option_none_value = '0';
        $dropdown = wp_dropdown_categories(
            array(
                'taxonomy'          => $this->taxonomy,
                'show_option_none'  => $show_option_none,
                'option_none_value' => $option_none_value,
                'selected'          => $this->value(),
                'echo'              => false,
            )
        );
        if (empty($dropdown)) {
            $dropdown = '<select>';
            $dropdown .= sprintf(
                '<option value="%1$s">%2$s</option>',
                esc_attr($option_none_value),
                esc_html($show_option_none)
            );
            $dropdown .= '</select>';
        } else {
            $dropdown = preg_replace(
                '~<select[^>]*>~',
                '<select>',
                $dropdown
            );
        }
        $dropdown = str_replace(
            '<select>',
            '<select ' . $this->get_link() . ' id="' . esc_attr($input_id) . '">',
            $dropdown
        );
        echo $dropdown;
    }
}

Теперь создадим настройку «Только записи категории» и элемент управления для нее и разместим настройку в секции «Настройки главной страницы»:

<?php
add_action(
    'customize_register',
    function($customizer) { // $customizer — объект класса WP_Customize_Manager

        require_once __DIR__ . '/My_Dropdown_Taxonomy_Control.php';

        // Добавляем настройку «Только записи категории»
        $customizer->add_setting(
            'setting_category_front_page', // идентифкатор настройки
            [
                // значение по умолчанию
                'default'           => 0,
                // настройка только для темы
                'type'              => 'theme_mod',
                // как обновлять окно предпросмотра
                'transport'         => 'refresh',
                // функция очистки данных
                'sanitize_callback' => 'absint',
            ]
        );
        $customizer->add_control(
            new My_Dropdown_Taxonomy_Control(
                $customizer,
                'control_category_front_page', // идентификатор элемента управления
                [
                    // label элемента формы
                    'label'       => 'Только записи категории',
                    // идентификатор секции
                    'section'     => 'static_front_page',
                    // идентификатор настройки
                    'settings'    => 'setting_category_front_page',
                    // что показывать в списке: категории или теги
                    'taxonomy'    => 'category',
                    // порядок сортировки
                    'priority'    => 100,
                ]
            )
        );
    }
);

Теперь нам надо вмешаться в процесс формирования запроса к БД, который получает последние записи блога. Для этого добавляем в файл functions.php следующий код:

/*
 * На странице последних записей показываем только записи категории,
 * выбранной в настройках темы. Это будет срабатывать, только если
 * категория была действительно выбрана
 */
if (get_theme_mod('setting_category_front_page', 0)) {
    add_action(
        'pre_get_posts',
        function ($query) {
            if ($query->is_main_query() && $query->is_home) {
                $cat = get_theme_mod('setting_category_front_page', 0);
                $query->set('cat', $cat);
            }
        }
    );
}

И вот что у нас получилось в итоге:

Хорошо, давайте усложним задачу — добавим настройку, которая позволит отфильтровать последние записи:

  • только посты выбранной категории
  • только посты с выбранной меткой

Удаляем весь код из customize.php и добавляем новый:

<?php
add_action(
    'customize_register',
    function($customizer) { // $customizer — объект класса WP_Customize_Manager

        require_once __DIR__ . '/My_Dropdown_Taxonomy_Control.php';

        // Добавляем настройку «Фильтровать записи»
        $customizer->add_setting(
            'setting_filter_last_posts', // идентифкатор настройки
            [
                // значение по умолчанию
                'default'           => 0,
                // настройка только для темы
                'type'              => 'theme_mod',
                // как обновлять окно предпросмотра
                'transport'         => 'refresh',
                // функция очистки данных
                'sanitize_callback' => 'absint',
            ]
        );
        $customizer->add_control(
            'control_filter_last_posts', // идентификатор элемента управления
            [
                // label элемента формы
                'label'       => 'Фильтровать записи',
                // идентификатор секции
                'section'     => 'static_front_page',
                // идентификатор настройки
                'settings'    => 'setting_filter_last_posts',
                // порядок сортировки
                'priority'    => 100,
                // тип элемента формы
                'type'        => 'radio',
                // значения radio-кнопок
                'choices' => [
                    0 => 'Не фильтровать',
                    1 => 'Только записи выбранной категории',
                    2 => 'Только записи с выбранным тегом',
                ],
            ]
        );

        // Добавляем настройку «Записи выбранной категории»
        $customizer->add_setting(
            'setting_filter_ctg_front', // идентифкатор настройки
            [
                // значение по умолчанию
                'default'           => 0,
                // настройка только для темы
                'type'              => 'theme_mod',
                // как обновлять окно предпросмотра
                'transport'         => 'refresh',
                // функция очистки данных
                'sanitize_callback' => 'absint',
            ]
        );
        $customizer->add_control(
            new My_Dropdown_Taxonomy_Control(
                $customizer,
                'control_filter_ctg_front', // идентификатор элемента управления
                [
                    // label элемента формы
                    'label'       => 'Только записи категории',
                    // идентификатор секции
                    'section'     => 'static_front_page',
                    // идентификатор настройки
                    'settings'    => 'setting_filter_ctg_front',
                    // что показывать в списке: категории или теги
                    'taxonomy'    => 'category',
                    // когда показывать этот элемент управления
                    'active_callback' => function ($control) {
                        $value = $control->manager->get_setting('setting_filter_last_posts')->value();
                        if (1 == $value) {
                            return true;
                        }
                        return false;
                    },
                    // порядок сортировки
                    'priority'    => 110,
                ]
            )
        );

        // Добавляем настройку «Записи с выбранным тегом»
        $customizer->add_setting(
            'setting_filter_tag_front', // идентифкатор настройки
            [
                // значение по умолчанию
                'default'           => 0,
                // настройка только для темы
                'type'              => 'theme_mod',
                // как обновлять окно предпросмотра
                'transport'         => 'refresh',
                // функция очистки данных
                'sanitize_callback' => 'absint',
            ]
        );
        $customizer->add_control(
            new My_Dropdown_Taxonomy_Control(
                $customizer,
                'control_filter_tag_front', // идентификатор элемента управления
                [
                    // label элемента формы
                    'label'       => 'Записи с выбранным тегом',
                    // идентификатор секции
                    'section'     => 'static_front_page',
                    // идентификатор настройки
                    'settings'    => 'setting_filter_tag_front',
                    // что показывать в списке: категории или теги
                    'taxonomy'    => 'post_tag',
                    // когда показывать этот элемент управления
                    'active_callback' => function ($control) {
                        $value = $control->manager->get_setting('setting_filter_last_posts')->value();
                        if (2 == $value) {
                            return true;
                        }
                        return false;
                    },
                    // порядок сортировки
                    'priority'    => 120,
                ]
            )
        );
    }
);

Здесь мы добавили три настройки:

  • Настройка «Фильтровать записи»
    • Не фильтровать
    • Только записи выбранной категории
    • Только записи с выбранным тегом
  • Настройка «Записи выбранной категории»
  • Настройка «Записи с выбранным тегом»

Настройка «Записи выбранной категории» показывается, когда выбрано «Только записи выбранной категории», во всех остальных случаях она скрыта. Настройка «Записи с выбранным тегом» показывается, когда выбрано «Только записи с выбранным тегом», во всех остальных случаях она скрыта.

Теперь добавим фильтрацию последних записей блога. Для этого удаляем старый код фильтрации из functions.php и добавляем новый:

/*
 * На странице последних записей показываем только посты выбранной
 * категории или посты с выбранным тегом.
 */
if (get_theme_mod('setting_filter_last_posts', 0)) {
    add_action(
        'pre_get_posts',
        function ($query) {
            if ($query->is_main_query() && $query->is_home) {
                $filter = get_theme_mod('setting_filter_last_posts', 0);
                if (1 == $filter) {
                    $cat = get_theme_mod('setting_filter_ctg_front', 0);
                    if ($cat) {
                        $query->set('cat', $cat);
                    }
                } elseif (2 == $filter) {
                    $tag = get_theme_mod('setting_filter_tag_front', 0);
                    if ($tag) {
                        $query->set('tag_id', $tag);
                    }
                }
            }
        }
    );
}

И вот что у нас получилось в итоге:

Дополнительно

Поиск: API • CMS • Web-разработка • WordPress • Настройка • Элемент управления • Секция • Control • Section • Setting • Theme Customize

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.