Agregar campo extra a producto variable en Woocommerce
Estoy siguiendo este tutorial sobre cómo añadir un campo extra a mis productos variables.
Solo necesito añadir un campo de texto extra. La parte de administración funciona bien - el campo se muestra y se guarda/actualiza, sin embargo, la página de producto individual no funciona - el campo no se muestra.
Entonces en mi functions.php
he añadido:
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' => __( 'Alguna etiqueta', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Alguna descripción.', '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;
}
Y en plugins/plugins/woocommerce/templates/single-product/add-to-cart/variation.php
he añadido (el tema no tiene su propio variation.php
):
<div class="woocommerce-variation-custom-text-field">
{{{ data.variation.text_field }}}
</div>
¿Cómo mostrar el campo personalizado en la página de producto individual?
Gracias
Actualización: Si inspecciono la página de producto individual, el script está presente:
<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>
El tema es belise.
Actualización: Estoy mirando el archivo functions.php
personalizado de WooCommerce del tema (belise/inc/woocommerce/functions.php) y la lógica parece estar ahí.
/**
* Descripción de precio en la página de tienda en los archivos de productos
*/
function belise_woocommerce_template_single_excerpt() {
global $post;
if ( ! $post->post_excerpt ) {
return;
}
?>
<div class="woocommerce-Price-amount amountption" itemprop="woocommerce-Price-amount amountption">
<!-- si añado <p>test</p> se imprime en la página de producto -->
<!-- Me gustaría que el elemento del campo personalizado se imprimiera aquí -->
<?php echo apply_filters( 'woocommerce_short_woocommerce-Price-amount amountption', $post->post_excerpt ); ?>
</div><?php
}
Respuesta - La primera solución de @ClemC funciona, el campo no se mostraba debido a la caché del navegador.

Para una referencia seria, observa cómo WC mismo añade el textarea variable_description
a las variaciones aquí.
Notamos múltiples problemas (potenciales) en tu implementación del campo de texto.
- El faltante
name
... - La cadena del
id
no tiene una estructura correcta, tiene la estructura delname
en su lugar... - El
id
oname
no son iguales a los de tu plantilla...
Tomando como referencia la implementación del textarea variable_description
de WC, implementemos nuestro campo de texto de esta manera:
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' => __( 'Etiqueta', 'woocommerce' ),
'desc_tip' => true,
'description' => __( 'Descripción.', '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;
}
Ahora, en la plantilla que debe tener la siguiente ruta:
yourtheme/woocommerce/single-product/add-to-cart/variation.php
Añade esto:
<div class="random-class woocommerce-variation-custom-text-field">
{{{ data.variation.my_text_field }}}
</div>
EDITADO:
Si deseas mostrar tu campo personalizado de la manera "clásica":
<div class="woocommerce-variation-custom-text-field">
<p><?php echo esc_html( get_post_meta( $post->ID, 'my_text_field', true ) ); ?></p>
</div>

Los comentarios no son para discusiones extensas; esta conversación ha sido movida al chat.

var_dump(get_post_meta( $post->ID, 'my_text_field', true ))
devuelve string(0) ""
incluso si mi campo personalizado tiene una cadena guardada.

Creo que es debido al $post->ID
que no es una variación y por lo tanto para el cual no ingresaste un valor de 'my_text_field'
. Realmente necesitas estar dentro del bucle de variaciones. Desde donde intentas imprimir el meta campo, parece que el MISMO meta campo estará presente para todas las variaciones y el producto principal en sí, no es lo que quieres. El campo de texto solo debe mostrarse para su variación correspondiente.

Realmente no tienes muchas otras opciones más que hacerlo con nuestro primer enfoque. Te sugiero que vayas a la sala de chat para solucionar tu caso.

Continuemos esta discusión en el chat.

Esto es genial, gracias @ClemC - un pequeño problema, puedo editar el texto del campo y guardarlo nuevamente, sin embargo si elimino todo el contenido y luego guardo, parece que no se guarda.

Ah, simplemente elimina if ( ! empty( $field ) ) {} y funcionará. ¿Hay algún inconveniente al hacer esto?
