В некоторых проектах на WordPress возникает необходимость создавать динамические поля для записи, которые меняются в зависимости от условий или ввода пользователя. Часто для этого используют плагины, например Advanced Custom Fields, но иногда хочется обойтись без дополнительного ПО, чтобы снизить нагрузку и повысить контроль над кодом.
Что такое динамические поля в WordPress и зачем они нужны
Динамические поля — это дополнительные поля, которые добавляются к записям или страницам, но их набор и содержимое зависит от контекста. Например, если у вас сайт с каталогом товаров, и для разных категорий нужны разные свойства: для телефонов — экран, для одежды — размер и т.д.
Стандартные метаполя в WordPress статичны — вы создаете поле и оно всегда показывается. Динамические же можно создавать и выводить по условию, что дает гибкость и удобство.
В этом руководстве мы рассмотрим, как создавать такие поля вручную, используя нативные функции WordPress, без сторонних плагинов.
Создание динамических метаполей: добавление и сохранение данных
Для начала нам нужно вывести на странице редактирования записи нужные динамические поля. Для этого воспользуемся хуком add_meta_boxes, чтобы добавить кастомный метабокс.
Пример добавления метабокса, который показывает разные поля в зависимости от категории записи:
function wordpressy_add_dynamic_meta_box() {
add_meta_box(
'wordpressy_dynamic_fields',
'Динамические поля',
'wordpressy_dynamic_fields_callback',
'post',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'wordpressy_add_dynamic_meta_box');
function wordpressy_dynamic_fields_callback($post) {
$categories = wp_get_post_categories($post->ID);
$value = get_post_meta($post->ID, '_wordpressy_dynamic_value', true);
wp_nonce_field('wordpressy_dynamic_fields_nonce', 'wordpressy_dynamic_fields_nonce');
if (in_array(5, $categories)) { // например, категория с ID 5
echo '<label for="wordpressy_field">Поле для категории 5:</label><br>';
echo '<input type="text" id="wordpressy_field" name="wordpressy_field" value="' . esc_attr($value) . '" size="25" />';
} elseif (in_array(10, $categories)) { // категория 10
echo '<label for="wordpressy_field">Поле для категории 10:</label><br>';
echo '<textarea id="wordpressy_field" name="wordpressy_field">' . esc_textarea($value) . '</textarea>';
} else {
echo 'Для этой категории динамические поля не заданы.';
}
}
В этом примере для категории с ID 5 выводится текстовое поле, для категории 10 — текстовая область, а для остальных — сообщение.
Далее нужно сохранить данные при сохранении записи. Для этого используем хук save_post:
function wordpressy_save_dynamic_fields($post_id) {
if (!isset($_POST['wordpressy_dynamic_fields_nonce'])) {
return;
}
if (!wp_verify_nonce($_POST['wordpressy_dynamic_fields_nonce'], 'wordpressy_dynamic_fields_nonce')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['wordpressy_field'])) {
update_post_meta($post_id, '_wordpressy_dynamic_value', sanitize_text_field($_POST['wordpressy_field']));
}
}
add_action('save_post', 'wordpressy_save_dynamic_fields');
Вывод динамических полей в шаблоне
Чтобы вывести значения динамических полей на фронтенде, используйте функцию get_post_meta. Например, в шаблоне single.php:
$dynamic_value = get_post_meta(get_the_ID(), '_wordpressy_dynamic_value', true);
if (!empty($dynamic_value)) {
echo '<div class="wordpressy-dynamic-field">' . esc_html($dynamic_value) . '</div>';
}
Если нужно выводить поля по-разному для разных категорий, можно повторить проверку и формировать вывод соответственно.
Расширение: создание динамических групп полей
Если нужно создавать не одно поле, а группу, количество которых может меняться, например, для добавления нескольких характеристик, можно использовать массивы в именах полей:
function wordpressy_dynamic_fields_callback($post) {
$features = get_post_meta($post->ID, '_wordpressy_features', true);
if (!is_array($features)) {
$features = [''];
}
echo '<label>Характеристики товара:</label><br>';
foreach ($features as $index => $feature) {
echo '<input type="text" name="wordpressy_features[]" value="' . esc_attr($feature) . '" size="30" /><br>';
}
echo '<button type="button" id="add_feature">Добавить характеристику</button>';
?>
<script>
document.getElementById('add_feature').addEventListener('click', function() {
var input = document.createElement('input');
input.type = 'text';
input.name = 'wordpressy_features[]';
input.size = 30;
this.parentNode.insertBefore(input, this);
this.parentNode.insertBefore(document.createElement('br'), this);
});
</script>
<?php
}
function wordpressy_save_dynamic_fields($post_id) {
// безопасность, как в предыдущем примере
if (!isset($_POST['wordpressy_dynamic_fields_nonce'])) return;
if (!wp_verify_nonce($_POST['wordpressy_dynamic_fields_nonce'], 'wordpressy_dynamic_fields_nonce')) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post', $post_id)) return;
if (isset($_POST['wordpressy_features']) && is_array($_POST['wordpressy_features'])) {
$features = array_map('sanitize_text_field', $_POST['wordpressy_features']);
update_post_meta($post_id, '_wordpressy_features', $features);
}
}
add_action('save_post', 'wordpressy_save_dynamic_fields');
Таким образом, мы можем добавлять и сохранять переменное количество полей — динамические группы.
Заключение по созданию динамических полей без плагинов
Использование нативных возможностей WordPress для создания динамических полей дает полный контроль над логикой, снижает зависимость от сторонних решений и оптимизирует производительность сайта.
Главное — аккуратно реализовывать безопасность (использовать nonce и проверки прав), а также тщательно тестировать интерфейс для удобства пользователей.
Если же функционал станет слишком сложным, можно рассмотреть плагины, например, Clearfy Pro, который оптимизирует работу с метаполями и помогает управлять дополнительными полями с минимальными усилиями. Подробнее о нем можно узнать на wpshop.ru.