Расширение таксономий WordPress

Что такое таксономии / пользовательские таксономии WordPress?

По сути таксономии — это способ группировки информации.

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

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

Пользовательские таксономии позволяют задавать собственные имена и структуру для организации записей. Вы можете создать новую таксономию под названием grade_ranking, которая будет обрабатывать ранжирование записей по шкале с такими значениями, как pass, credit, distinction и high distinction.

Стандартная информация для таксономий

При определении таксономии вам нужно указать, будет ли это таксономия hierarchical или non-hierarchial. Это задает то, как будет группироваться информация в вашей таксономии.

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

non-hierarchial (не иерархические) таксономии действуют как теги, где все термины принадлежат одному уровню.

Пользовательские таксономии позволяют вводить следующую информацию для каждого из терминов:

  • Имя: определяет имя, используемое для термина, оно показывается конечному пользователю. Применяется и к категориям, и к тегам;
  • Slug: определяет URL-адрес, используемый для термина (как правило, состоит из символов нижнего регистра, разделенных тире). Применяется и к категориям, и к тегам;
  • Родительский элемент: позволяет определить, является ли термин родительским элементом верхнего уровня или это дочерний термин. Относится только к иерархическим таксономиям, таким как категории;
  • Описание: краткое описание того, что содержит этот термин. Показывается на странице списка терминов (когда вы кликаете по ссылке, чтобы просмотреть сам термин).

Это все, что предоставляет WordPress в отношении ваших терминов.

Расширение таксономий

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

WordPress предоставляет ряд обращений (hooks), которые можно использовать для изменения панели администрирования таксономии, и которые помогают в процессе сохранения дополнительной информации.

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

С чего начнем?

WordPress предоставляет два основных способа, с помощью которых можно создать термины таксономий:

  • Создание через панель администрирования таксономий;
  • На лету при редактировании типа записи, который связан с таксономией.

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

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

Что нужно изменить?

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

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

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

  • текст;
  • текстовое поле;
  • выбор элементов;
  • чекбокс.

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

Изменение панели добавления категории

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

Мы должны использовать обращение category_add_form_fields.

Обращение category_add_form_fields используется для добавления дополнительной информации в панель администрирования категории.

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

Следующий код должен быть добавлен в файл functions.php вашей темы (или другой файл, который вы используете для своего кода):

function add_extra_fields_to_category($taxonomy_name){
    ?>
    <div class="form-field">
        <label for="category-text">Текстовое поле</label>
        <input type="text" name="category-text" id="category-text"/>
        <p>This is a text field </p>
    </div>
    <div class="form-field">
        <label for="category-textarea">Текстовое поле </label>
        <textarea name="category-textarea" id="category-textarea"></textarea>
        <p>Это текстовое поле</p>
    </div>
    <div class="form-field">
        <label for="category-select">Поле для выбора значений</label>
        <select name="category-select" id="category-select">
            <option value="select-value-one"> Значение один </option>
            <option value="select-value-two"> Значение два </option>
        </select>
        <p>Это поле для выбора значений </p>
    </div>
    <div>
        <label for="category-radio-value-one">Опция переключателя один</label>
        <input type="radio" name="category-radio" id="category-radio-value-one" value="category-radio-value-one"/>
        <label for="category-radio-value-two">Опция переключателя два</label>
        <input type="radio" name="category-radio" id="category-radio-value-two" value="category-radio-value-two"/>
        <p>Это поле переключения опций </p>
    </div>
    <?php
}

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

add_action().
add_action('category_add_form_fields','add_extra_fields_to_category');

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

появиться дополнительные поля

В качестве дополнительного совета: когда вы определяете поля, которые должны быть добавлены в панель, вы, как правило, обертываете их в класс form-field, это гарантирует, что содержащиеся элементы ввода будут выводиться на всю ширину панели.

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

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

Сохранение новой информации о категории

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

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

При сборе информации, которая будет напрямую записываться в базу данных WordPress, всегда нужно проверять безопасность данных. Мы можем использовать ‘sanitize_text_field($string)’, чтобы проверить безопасность строк, убрать все теги, удалить разрывы строк, отступы и преобразовать значимые символы, такие, например, как < and >:

function save_extra_taxonomy_fields($term_id){

    //сбор всех данных, связанных с этой новой таксономией
    $term_item = get_term($term_id,'category');
    $term_slug = $term_item->slug;

//сбор данных из пользовательских полей
$term_category_text = sanitize_text_field($_POST['category-text']);
$term_category_textarea = sanitize_text_field($_POST['category-textarea']);
$term_category_select = sanitize_text_field($_POST['category-select']); 
$term_category_radio = sanitize_text_field($_POST['category-radio']);

 //сохранение информации из пользовательских полей в таблице wp-options
update_option('term_category_text_' . $term_slug, $term_category_text); 
update_option('term_category_textarea_' . $term_slug, $term_category_textarea);
update_option('term_category_select_' . $term_slug, $term_category_select);
update_option('term_category_radio_' . $term_slug, $term_category_radio);

}

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

Данная функция принимает один параметр, ID нового сохраняемого термина.

Имея этот ID, мы можем вызвать функцию get_term($term_id,$taxonomy_name).

Эта функция принимает два параметра, ID самого термина и имя таксономии. Так как мы знаем идентификатор самого термина, а также то, что мы имеем дело с таксономией category, теперь мы можем получить доступ к объекту термина.

Мы собираем значение slug из термина объекта и сохраняем его. После этого мы собираем все четыре значения новых полей из объекта $_POST. Наконец мы вызываем другую функцию update_option($option_name,$option_value).

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

Например, если мы создаем новую категорию под названием test, когда мы сохраняем информацию из текстового поля, имя опции будет term_category_textarea_test, когда сохраняем данные из поля выбора вариантов, имя будет — text_category_select_test и т.д. Мы добавляем для этих полей slug в конце имени, чтобы обеспечить уникальность значений (так как все значения slug являются уникальными).

Теперь нам нужно подключить эту функцию к обращению create_category:

add_action('create_category','save_extra_taxonomy_fields');

Изменение панели редактирования категории

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

Для отображения наших дополнительных полей нам нужно будет подключиться к обращению category_edit_form_fields.

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

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

function edit_extra_fields_for_category($term){

    //сбор slug терминов
    $term_slug = $term->slug;

    //сбор информации, сохраненной из новых полей
    $term_category_text = get_option('term_category_text_' . $term_slug); 
    $term_category_textarea = get_option('term_category_textarea_' . $term_slug); 
    $term_category_select = get_option('term_category_select_' . $term_slug); 
    $term_category_radio = get_option('term_category_radio_' . $term_slug);

    //вывод дополнительных полей?>
    <tr class="form-field">
        <th valign="top" scope="row">
            <label for="category-text"> Текстовое поле </label>
        </th>
        <td>
            <input type="text" name="category-text" id="category-text" value="<?php echo $term_category_text; ?>"/>
            <p class="description">Это текстовое поле </p>
        </td>
    </tr>
    <tr class="form-field">
        <th valign="top" scope="row">
            <label for="category-textarea"> Поле текстовой области </label>
        </th>
        <td>
            <textarea name="category-textarea" id="category-textarea"><?php echo $term_category_textarea; ?></textarea>
            <p class="description">Это поле текстовой области </p>
        </td>
    </tr>
    <tr class="form-field">
        <th valign="top" scope="row">
            <label for="category-select"> Поле выбора вариантов </label>
        </th>
        <td>
            <select name="category-select" id="category-select" value="<?php echo $term_category_select; ?>">
                <option value="select-value-one" <?php if($term_category_select=='select-value-one'){ echo 'selected';}?>> Value One </option>
                <option value="select-value-two" <?php if($term_category_select=='select-value-two'){ echo 'selected';}?>> Value Two </option>
            </select>
            <p class="description">Это поле выбора вариантов </p>
        </td>
    </tr>
    <tr>
        <th valign="top" scope="row">
            <label> Category Radio Field </label>
        </th>
        <td>
            <label for="category-radio-value-one">Опция переключателя один</label>
            <input type="radio" name="category-radio" id="category-radio-value-one" value="category-radio-value-one" <?php if($term_category_radio=='category-radio-value-one'){ echo 'checked'; }?> />
            <br/>
            <label for="category-radio-value-two"> Опция переключателя два</label>
            <input type="radio" name="category-radio" id="category-radio-value-two" value="category-radio-value-two" <?php if($term_category_radio=='category-radio-value-two'){ echo 'checked'; }?>/>
            <p>Это поле переключателя опций</p>
        </td>
    </tr>

    <?php
}

Эта функция использует свой предыдущий объект term для доступа к slug самого термина. С помощью этого slug, она ищет четыре сохраненных значения пользовательских полей, используя функцию get_option($option_name).

Эта функция ищет опции с указанным именем и присваивает им значения. В нашем случае мы ищем четыре значения полей и присваиваем их переменным.

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

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

  • Текстовое поле — для текстового поля мы назначаем значение непосредственно его атрибуту value, который будет предварительно заполняться сам собой;
  • Поле текстовой области — для текстовой области мы выводим ее значение непосредственно между тегами <textarea> и </textarea>, вследствие чего значение выводится в элементе текстовой области;
  • Поле выбора вариантов — для выбора вариантов мы сначала создаем элемент выбора вариантов и все связанные с ним параметры. Мы добавляем для элемента выбора вариантов атрибут, который называется value, и заполняем его нашим сохраненным значением (это очень похоже на то, как мы разобрались с текстовым полем). Даже с учетом того, что мы выводим все возможные значения списком, нам все равно нужно определить, какой вариант в данный момент назначен. Поэтому мы перебираем каждый из возможных вариантов выбора в элементе и определяем, совпадает ли его значение, с тем значением, которое мы собрали ранее. Если так, то в данный момент он является выбранным вариантом. Мы используем оператор IF, и, если он определяет совпадение значения опции с атрибутом selected, то данный вариант используется браузером, как вариант по умолчанию;
  • Поле переключателя опций — для этого поля мы выводим опции непосредственно на страницу и определяем, соответствует ли их значение значению, сохраненному в базе данных. Если это так мы используем оператор IF для вывода в поле атрибута checked. Этот атрибут указывает браузеру принять эту опцию в качестве значения по умолчанию (во многом это похоже на обработку вывода поля выбора вариантов, так как мы должны указать браузеру, какую опцию выводить).

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

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

add_action('category_edit_form_fields','edit_extra_fields_for_category');

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

экран редактирования категории должен обновиться

Сохранение обновленной информации о категории

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

К счастью, у нас уже есть такая функция. Ранее мы создали функцию save_extra_taxonomy_fields($term_id), которую мы использовали при добавлении нового термина в категорию.

Мы можем вызвать эту функцию при обновлении категории, подключив ее к другому обращению. Мы подключаем нашу функцию save_extra_taxonomy_fields($term_id) к обращению edit_category, и когда мы обновляем категорию, эта функция будет сохранять информацию:

add_action('edit_category','save_extra_taxonomy_fields');

Расширение пользовательских таксономий

Пользовательские таксономии могут быть расширены тем же образом, что и встроенные (категории и теги).

Единственное, что нужно будет изменить, это имена используемых обращений.

Для категорий вы должны использовать следующие обращения:

  • category_add_form_fields – добавление полей в панель добавления новой категории;
  • category_edit_form_fields – добавление полей в панель редактирования категорий;
  • create_category – используется, когда вы хотите сохранить новые термины категории;
  • edit_category – используется, когда вы хотите обновить термины категории.

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

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

  • $TAXONOMY_NAME_add_form_fields;
  • $TAXONOMY_NAME_edit_form_fields;
  • create_$TAXONOMY_NAME;
  • edit_$TAXONOMY_NAME.

Например, если вы зарегистрировали собственную таксономию под названием members, ваши обращения будут называться:

  • members_add_form_fields;
  • members_edit_form_fields;
  • create_members;
  • edit_members.

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

В заключение всего этого

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

Вы можете получить доступ к конкретным терминам с помощью get_term($term_name,$taxonomy_name), а затем оттуда вы можете использовать slug, так как вы уже получили доступ к дополнительной информации, извлекаемой из таблицы опций WordPress.

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

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

Перевод статьи «Extending WordPress Taxonomies» был подготовлен дружной командой проекта Сайтостроение от А до Я.