WooCommerce add extra field to variation product

15 авг. 2017 г., 12:51:48
Просмотры: 27.6K
Голосов: 9

Я следую этому руководству о том, как добавить дополнительное поле к моим вариативным товарам.

Мне просто нужно добавить дополнительное текстовое поле. Административная часть работает нормально - поле отображается и сохраняется/обновляется, однако на странице отдельного товара поле не отображается.

Итак, в мой functions.php я добавил:

add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );

add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );

function variation_settings_fields( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input( 
        array( 
            'id'          => '_text_field[' . $variation->ID . ']', 
            'label'       => __( 'Некоторая метка', 'woocommerce' ), 
            'placeholder' => '',
            'desc_tip'    => 'true',
            'description' => __( 'Некоторое описание.', 'woocommerce' ),
            'value'       => get_post_meta( $variation->ID, '_text_field', true )
        )
    );
}

function save_variation_settings_fields( $post_id ) {
    $text_field = $_POST['_text_field'][ $post_id ];
    if( ! empty( $text_field ) ) {
        update_post_meta( $post_id, '_text_field', esc_attr( $text_field );
    }
}

add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );

function load_variation_settings_fields( $variations ) {

    $variations['text_field'] = get_post_meta( $variations[ 'variation_id' ], '_text_field', true );

    return $variations;
}

И в plugins/plugins/woocommerce/templates/single-product/add-to-cart/variation.php я добавил (в теме нет собственного variation.php):

<div class="woocommerce-variation-custom-text-field">
    {{{ data.variation.text_field }}}
</div>

Как отобразить пользовательское поле на странице товара?

Спасибо

Обновление: Если я проверяю страницу товара, скрипт присутствует:

<script type="text/template" id="tmpl-variation-template">
    <div class="woocommerce-variation-description">
        {{{ data.variation.variation_description }}}
    </div>

    <div class="woocommerce-variation-price">
        {{{ data.variation.price_html }}}
    </div>

   <div class="woocommerce-variation-custom-text-field">
        {{{ data.variation.text_field }}}
    </div>

    <div class="woocommerce-variation-availability">
        {{{ data.variation.availability_html }}}
    </div>
</script>

Тема - belise.

Обновление: Я просматриваю пользовательский файл functions.php WooCommerce темы (belise/inc/woocommerce/functions.php) и похоже, что логика там есть.

/**
 * Описание на странице магазина woocommerce-Price-amount amount для архивов продуктов
 */
function belise_woocommerce_template_single_excerpt() {
    global $post;

    if ( ! $post->post_excerpt ) {
        return;
    }
    ?>
    <div class="woocommerce-Price-amount amountption" itemprop="woocommerce-Price-amount amountption">

        <!-- если я добавлю <p>test</p>, он отображается на странице товара -->
        <!-- я хотел бы, чтобы элемент пользовательского поля отображался здесь -->

        <?php echo apply_filters( 'woocommerce_short_woocommerce-Price-amount amountption', $post->post_excerpt ); ?>
    </div><?php
}

Ответ - первое решение @ClemC работает, поле не отображалось из-за кэша браузера.

0
Все ответы на вопрос 1
11
23

Для серьезного примера смотрите, как сам WC добавляет текстовое поле variable_description к вариациям здесь.

Мы заметили несколько (потенциальных) проблем в вашей реализации текстового поля.

  • Отсутствует атрибут name...
  • Строка id имеет неправильную структуру, она соответствует структуре name...
  • Атрибуты id или name не совпадают с теми, что используются в вашем шаблоне...

Итак, беря за основу реализацию текстового поля variable_description в WC, давайте реализуем наше текстовое поле следующим образом:

add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );

function variation_settings_fields( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input(
        array(
            'id'            => "my_text_field{$loop}",
            'name'          => "my_text_field[{$loop}]",
            'value'         => get_post_meta( $variation->ID, 'my_text_field', true ),
            'label'         => __( 'Название поля', 'woocommerce' ),
            'desc_tip'      => true,
            'description'   => __( 'Описание поля.', 'woocommerce' ),
            'wrapper_class' => 'form-row form-row-full',
        )
    );
}

function save_variation_settings_fields( $variation_id, $loop ) {
    $text_field = $_POST['my_text_field'][ $loop ];

    if ( ! empty( $text_field ) ) {
        update_post_meta( $variation_id, 'my_text_field', esc_attr( $text_field ));
    }
}

function load_variation_settings_fields( $variation ) {     
    $variation['my_text_field'] = get_post_meta( $variation[ 'variation_id' ], 'my_text_field', true );

    return $variation;
}

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

yourtheme/woocommerce/single-product/add-to-‌​cart/variation.php

Добавьте это:

<div class="random-class woocommerce-variation-custom-text-field">
    {{{ data.variation.my_text_field }}}
</div>

ИЗМЕНЕНИЕ:

Если вы хотите вывести ваше пользовательское поле "классическим" способом:

<div class="woocommerce-variation-custom-text-field">
    <p><?php echo esc_html( get_post_meta( $post->ID, 'my_text_field', true ) ); ?></p>
</div>
21 авг. 2017 г. 13:28:37
Комментарии

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

Howdy_McGee Howdy_McGee
23 авг. 2017 г. 21:17:05

@ClemC см. обновление.

Vucko Vucko
26 авг. 2017 г. 11:44:55

@Vucko см. обновление.

ClemC ClemC
26 авг. 2017 г. 12:53:49

Он выводит div и p, но p оказывается пустым.

Vucko Vucko
26 авг. 2017 г. 12:55:49

var_dump(get_post_meta( $post->ID, 'my_text_field', true )) возвращает string(0) "", даже если в моем пользовательском поле сохранена строка.

Vucko Vucko
26 авг. 2017 г. 13:02:36

Я думаю, это из-за $post->ID, который не является вариацией и для которого вы не вводили значение 'my_text_field'. Вам действительно нужно находиться внутри цикла вариаций. Судя по тому, откуда вы пытаетесь вывести метаполе, получается, что ОДИНАКОВОЕ метаполе будет присутствовать для всех вариаций и самого основного товара - это не то, что вам нужно. Текстовое поле должно отображаться только для своей вариации.

ClemC ClemC
26 авг. 2017 г. 13:04:02

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

ClemC ClemC
26 авг. 2017 г. 13:05:35

Давайте продолжим это обсуждение в чате.

Vucko Vucko
26 авг. 2017 г. 13:06:10

Это отлично, спасибо @ClemC - есть одна небольшая проблема: я могу редактировать текст в поле и сохранять его снова, однако если я удалю все содержимое и затем сохраню, изменения, кажется, не сохраняются?

dungey_140 dungey_140
5 авг. 2019 г. 13:22:31

Ах, просто удалите if ( ! empty( $field ) ) {}, и всё заработает. Есть ли какие-то недостатки в таком решении?

dungey_140 dungey_140
5 авг. 2019 г. 13:27:53

После следования блогу, вероятно, такому же, как у автора вопроса, поскольку там был такой же код, вы сталкиваетесь с той же проблемой... Если бы авторы блогов проверяли свои коды, мы бы здесь не оказались

Tofandel Tofandel
14 сент. 2021 г. 20:06:30
Показать остальные 6 комментариев