Как добавить собственные поля к вариативным товарам WooCommerce в теме WordPress

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

Ниже — рабочий вариант для темы WordPress: добавляем поле в карточку каждой вариации, сохраняем его в мета-данных и выводим на витрине. Подход подходит для небольших доработок темы и не требует изменения файлов WooCommerce.

Когда проблема проявляется и что именно ломается

Обычно задача всплывает в одном из трёх мест:

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

Если просто добавить текст в шаблон single-product.php, он будет одинаковым для всех вариаций. Если записать данные в произвольное поле товара, они не привяжутся к конкретной вариации. Поэтому нужен именно метабокс вариации.

Что проверить до начала

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

Диагностика: где хранить данные вариации

Есть три рабочих подхода. Для большинства задач достаточно первого.

ПодходКогда подходитМинус
Пользовательское поле вариацииНужно хранить 1–3 дополнительных значенияНужно вручную вывести на витрине
Отдельная таксономия или атрибутЗначение выбирается из фиксированного спискаНеудобно для свободного текста и ссылок
Отдельная таблица/плагинСложная логика, много связанных данныхИзбыточно для простой темы

Если задача звучит как «добавить поле к каждой вариации и показать его на странице товара», используйте мета-поле вариации. Это проще поддерживать и легче отлаживать.

Пошаговое решение: добавляем поле в вариацию

Ниже пример для поля supplier_sku. Его можно заменить на любой другой ключ, но лучше использовать понятное имя без пробелов.

1. Добавляем поле в админке вариации

<?php
add_action( 'woocommerce_product_after_variable_attributes', 'wt_add_variation_custom_field', 10, 3 );
function wt_add_variation_custom_field( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input( array(
        'id'            => 'supplier_sku[' . $loop . ']',
        'name'          => 'supplier_sku[' . $loop . ']',
        'value'         => get_post_meta( $variation->ID, 'supplier_sku', true ),
        'label'         => 'Артикул поставщика',
        'desc_tip'      => true,
        'description'   => 'Отдельный артикул для этой вариации.',
        'wrapper_class' => 'form-row form-row-full',
    ) );
}

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

2. Сохраняем значение при обновлении товара

<?php
add_action( 'woocommerce_save_product_variation', 'wt_save_variation_custom_field', 10, 2 );
function wt_save_variation_custom_field( $variation_id, $i ) {
    if ( isset( $_POST['supplier_sku'][ $i ] ) ) {
        $value = sanitize_text_field( wp_unslash( $_POST['supplier_sku'][ $i ] ) );
        update_post_meta( $variation_id, 'supplier_sku', $value );
    }
}

Здесь важно не сохранять сырые данные из $_POST. Для текстового поля достаточно sanitize_text_field(). Если поле будет URL, используйте esc_url_raw().

3. Выводим значение на витрине при выборе вариации

Чтобы данные менялись вместе с выбранной вариацией, удобнее передать их в JSON WooCommerce и отрисовать через JavaScript.

<?php
add_filter( 'woocommerce_available_variation', 'wt_add_variation_data_to_json' );
function wt_add_variation_data_to_json( $data ) {
    $data['supplier_sku'] = get_post_meta( $data['variation_id'], 'supplier_sku', true );
    return $data;
}

Теперь на фронтенде можно вывести это значение в блоке товара:

<div class="variation-extra" style="display:none;">
    <strong>Артикул поставщика:</strong> <span class="variation-extra__value"></span>
</div>

<script>
document.addEventListener('DOMContentLoaded', function () {
    const form = document.querySelector('.variations_form');
    const box = document.querySelector('.variation-extra');
    const value = document.querySelector('.variation-extra__value');

    if (!form || !box || !value) return;

    form.addEventListener('found_variation', function (event, variation) {
        if (variation.supplier_sku) {
            value.textContent = variation.supplier_sku;
            box.style.display = '';
        } else {
            value.textContent = '';
            box.style.display = 'none';
        }
    });

    form.addEventListener('reset_data', function () {
        value.textContent = '';
        box.style.display = 'none';
    });
});
</script>

Этот вариант хорош тем, что не требует отдельного AJAX-запроса. WooCommerce уже передаёт данные вариации в объекте variation.

Как проверить, что всё работает

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

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

<script>
document.addEventListener('DOMContentLoaded', function () {
    const form = document.querySelector('.variations_form');
    if (!form) return;

    form.addEventListener('found_variation', function (event, variation) {
        console.log(variation);
    });
});
</script>

Если в консоли нет поля supplier_sku, значит проблема в фильтре woocommerce_available_variation или в том, что код не подключён на странице товара.

Частые ошибки и как их исправить

Поле есть в админке, но не сохраняется

Обычно причина в том, что индекс массива $i не совпадает с порядком вывода вариаций, либо код сохранения не срабатывает из-за ошибки в названии хука. Проверьте, что используется именно woocommerce_save_product_variation.

Данные не показываются на витрине

Частая ошибка — поле добавили в мета, но забыли передать его в woocommerce_available_variation. Без этого JavaScript не увидит значение. Ещё одна причина — на странице нет стандартной формы вариаций WooCommerce, потому что шаблон товара переопределён темой.

Показывается старое значение после изменения

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

Сломалась валидация или появились предупреждения PHP

Это часто происходит, когда в $_POST обращаются без проверки isset() или используют массив не того формата. Для текстового поля достаточно простой проверки, как в примере выше.

Безопасность и поддержка темы

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

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

Если в теме уже много ручных правок, полезно сначала проверить, нет ли дублирующих шаблонов WooCommerce в папке your-theme/woocommerce. Иногда проблема не в коде, а в старом шаблоне вариаций, который не поддерживает текущую разметку плагина.

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

Как создать тему WordPress с поддержкой RTL (Right-to-Left)
21.03.2026
Как удалить ненужные метаданные из вывода темы WordPress для оптимизации
04.07.2026
Как убрать типичные PHP warnings и ошибки WooCommerce в теме WordPress
02.05.2026
Как сделать динамический фон в теме WordPress: практическое руководство
19.01.2026
WooCommerce: как убрать типичные PHP warnings и ошибки в теме WordPress
07.06.2026