5

I'm following this tutorial on how to add an extra field to my variation products.

I just need to add an extra text field. The admin part works fine - the field is showing and saving/updating, however, the single product page doesn't - the field won't show.

So in my functions.php I've added:

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'       => __( 'Some label', 'woocommerce' ), 
            'placeholder' => '',
            'desc_tip'    => 'true',
            'description' => __( 'Some 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;
}

And in plugins/plugins/woocommerce/templates/single-product/add-to-cart/variation.php I've added (the theme doesn't have it's own variation.php):

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

How to display the custom field on the single product page?

Thanks

Update: If I inspect the single product page, the script is present:

<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>

The theme is belise.

Update: I'm looking at the themes custom woocommerce functions.php (belise/inc/woocommerce/functions.php) file and the logic seems to be there.

/**
 * Shop page woocommerce-Price-amount amountption on product archives
 */
function belise_woocommerce_template_single_excerpt() {
    global $post;

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

        <!-- if I add <p>test</p> it is printed on the product page -->
        <!-- I would like for the custom field element to be printed here -->

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

Answer - @ClemC first solution works, the field didn't show because of the browsers cache.

9
+50

For serious reference, see how WC itself adds the textarea variable_description to the variations here.

We notice multiple (potential) problems in your text field implementation.

  • The missing name...
  • The id string does not have a correct structure, it has the name structure instead...
  • The id or name are not same than in your template...

So taking as reference the WC variable_description textarea implementation, let's implement our text field this way:

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'         => __( 'Some label', 'woocommerce' ),
            'desc_tip'      => true,
            'description'   => __( 'Some 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;
}

Now, in the template that must have the following path:

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

Add this:

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

EDIT:

If you want to output your custom field the "classic" way:

<div class="woocommerce-variation-custom-text-field">
    <p><?php echo esc_html( get_post_meta( $post->ID, 'my_text_field', true ) ); ?></p>
</div>
  • Comments are not for extended discussion; this conversation has been moved to chat. – Howdy_McGee Aug 23 '17 at 18:17
  • @ClemC see the update. – Vucko Aug 26 '17 at 8:44
  • @Vucko see the update. – ClemC Aug 26 '17 at 9:53
  • It prints the div and the p, but the p is empty. – Vucko Aug 26 '17 at 9:55
  • var_dump(get_post_meta( $post->ID, 'my_text_field', true )) returns string(0) "" even if my custom field has a saved string. – Vucko Aug 26 '17 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.