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
idno tiene una estructura correcta, tiene la estructura delnameen su lugar... - El
idonameno 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.
Howdy_McGee
var_dump(get_post_meta( $post->ID, 'my_text_field', true )) devuelve string(0) "" incluso si mi campo personalizado tiene una cadena guardada.
Vucko
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.
ClemC
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.
ClemC
Continuemos esta discusión en el chat.
Vucko
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.
dungey_140
Ah, simplemente elimina if ( ! empty( $field ) ) {} y funcionará. ¿Hay algún inconveniente al hacer esto?
dungey_140