Search code examples
phphtmljquerywoocommerceproduct-variations

Display html content set in WooCommerce product variation custom field when selected


How can I render HTML code in the Product Attributes Description in WordPress WooCommerce? Despite trying a custom plugin code, the HTML always displays as plain text in the Attribute Description field.

Custom Plugin code which i tested but not working. The HTML always renders as plane text in the Attribute Description.

<?php
/*
Plugin Name: Custom Product Attribute Description
Description: Allows adding HTML descriptions to WooCommerce product attributes.
Version: 1.0
Author: Your Name
*/

// Adding the custom field to product attributes
add_action('woocommerce_product_after_variable_attributes', 'add_custom_attribute_description_field', 10, 3);
function add_custom_attribute_description_field($product, $loop, $variations) {
    $html_value = get_post_meta($product->get_id(), 'attribute_description', true);
    echo '<div class="form-row form-row-wide">';
    echo '<p class="form-field">';
    echo '<label for="attribute_description[' . $loop . ']">' . __('Attribute Description', 'woocommerce') . '</label>';
    echo '<textarea id="attribute_description[' . $loop . ']" name="attribute_description[' . $loop . ']" rows="5" cols="40" class="input-text">' . esc_textarea($html_value) . '</textarea>';
    echo '</p>';
    echo '</div>';
}

// Saving the custom field value
add_action('woocommerce_save_product_variation', 'save_custom_attribute_description_field', 10, 2);
function save_custom_attribute_description_field($post_id, $i) {
    if (isset($_POST['attribute_description'][$i])) {
        $allowed_html = array(
            'a' => array(
                'href' => array(),
                'title' => array(),
            ),
            'br' => array(),
            'strong' => array(),
            // Add more allowed tags as needed
        );
        $html_value = wp_kses($_POST['attribute_description'][$i], $allowed_html);
        update_post_meta($post_id, 'attribute_description', $html_value);
    }
}

// Displaying the custom attribute description
add_filter('woocommerce_display_product_attributes', 'display_html_in_product_attributes', 10, 2);
function display_html_in_product_attributes($product_attributes, $product) {
    $html_value = get_post_meta($product->get_id(), 'attribute_description', true);
    if (!empty($html_value)) {
        $product_attributes['Custom Description'] = array(
            'label' => __('Description', 'woocommerce'),
            'value' => wp_kses_post($html_value) // Output sanitized HTML
        );
    }
    return $product_attributes;
}

Adding HTML to Attribute description:

[![Adding HTML to Attribute description][1]][1] [1]: https://i.sstatic.net/KPYHYjpG.png

Testing HTML description:

Testing HTML description

Update:

A temporary solution to make Custom Tab with Custom Attributes which supports HTML.

<?php
/**
 * Plugin Name: Custom WooCommerce Tabs
 * Description: Adds custom tabs to WooCommerce products.
 * Version: 1.0
 * Author: Your Name
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

// Register the custom fields in the product edit page
function cwt_add_custom_fields() {
    global $post;

    if ($post->post_type !== 'product') {
        return;
    }

    echo '<div class="options_group">';
    
    // Custom Tab Title
    woocommerce_wp_text_input([
        'id' => 'custom_tab_title',
        'label' => __('Custom Tab Title', 'txtdomain'),
        'placeholder' => 'Enter custom tab title here',
        'desc_tip' => 'true',
        'description' => __('This title will appear as the tab heading.', 'txtdomain'),
    ]);

    // Custom Tab Content
    wp_editor(get_post_meta($post->ID, 'custom_tab_content', true), 'custom_tab_content', []);
    
    echo '</div>';
}
add_action('woocommerce_product_after_attributes', 'cwt_add_custom_fields');

// Save the custom fields
function cwt_save_custom_fields($post_id) {
    $custom_tab_title = isset($_POST['custom_tab_title']) ? sanitize_text_field($_POST['custom_tab_title']) : '';
    update_post_meta($post_id, 'custom_tab_title', $custom_tab_title);

    if (isset($_POST['custom_tab_content'])) {
        update_post_meta($post_id, 'custom_tab_content', wp_kses_post($_POST['custom_tab_content']));
    }
}
add_action('woocommerce_process_product_meta', 'cwt_save_custom_fields');

// Add custom tabs to WooCommerce product pages
function cwt_add_custom_tab($tabs) {
    global $post;

    $custom_tab_title = get_post_meta($post->ID, 'custom_tab_title', true);
    $custom_tab_content = get_post_meta($post->ID, 'custom_tab_content', true);

    if (!empty($custom_tab_title)) {
        $tabs[sanitize_title($custom_tab_title)] = [
            'title' => $custom_tab_title,
            'callback' => function() use ($custom_tab_content) {
                echo $custom_tab_content;
            },
            'priority' => 10,
        ];
    }

    return $tabs;
}
add_filter('woocommerce_product_tabs', 'cwt_add_custom_tab');

Adding HTML to Custom Code Attributes:

Adding HTML to Custom Code Attributes

Rendering HTML in Custom Code Attributes:

Rendering HTML in Custom Code Attributes


Solution

  • You don't really need to set a custom attribute for that, as it seems that you want to display some different data for each product variation of a variable product.

    So assuming that you have set a variable product, with some product variations, try the following code:

    // Add a custom field to product variations
    add_action('woocommerce_product_after_variable_attributes', 'add_attribute_description_field_to_variation', 10, 3);
    function add_attribute_description_field_to_variation($loop, $variation_data, $variation) {
        $variation_obj = wc_get_product($variation->ID);
    
        woocommerce_wp_textarea_input( array(
            'id'            => "attr_description{$loop}",
            'name'          => "attr_description[{$loop}]",
            'wrapper_class' => 'form-row form-row-full',
            'label'         => __('Attribute Description', 'woocommerce'),
            'value'         => $variation_obj->get_meta('attr_description'),
        ) );
    }
    
    // Save the custom field for product variations
    add_action('woocommerce_admin_process_variation_object', 'save_amazon_link_field_from_variations', 10, 2 );
    function save_amazon_link_field_from_variations($variation, $i) {
        if ( isset($_POST['attr_description'][$i]) ) {
            $allowed_html = array(
                'a' => array(
                    'href' => array(),
                    'title' => array(),
                    'style' => array(),
                ),
                'br' => array(),
                'p'  => array(),
                'strong' => array(),
                // Add more allowed tags as needed
            );
            $variation->update_meta_data('attr_description', wp_kses($_POST['attr_description'][$i], $allowed_html) );
        }
    }
    
    // Add a "Description" row to the product attributes table
    add_filter('woocommerce_display_product_attributes', 'display_html_in_product_attributes', 10, 2);
    function display_html_in_product_attributes($product_attributes, $product) {
        $product_attributes['custom-description'] = array(
            'label' => __('Description', 'woocommerce'),
            'value' => 'n/a', // Default displayed value, when no variation is selected
        );
        return $product_attributes;
    }
    
    // Add variation custom field data value to the variable product data form
    add_action( 'woocommerce_available_variation', 'add_variations_custom_field_value_to_variable_product_form', 10, 3 );
    function add_variations_custom_field_value_to_variable_product_form( $variation_data, $product, $variation ) {
        if ( $attr_description = $variation->get_meta('attr_description') ) {
            $variation_data['attr_description'] = $attr_description;
        }
        return  $variation_data;
    }
    
    // Javacript: Displays the selected variation related html data
    add_action('woocommerce_after_add_to_cart_form', 'display_selected_variation_attr_description_js', 15 );
    function display_selected_variation_attr_description_js() {
        global $product;
    
        if ( $product->is_type('variable') ) : ?>
        <script>
        jQuery( function($){
            const targetSelector = '.woocommerce-product-attributes-item--custom-description > .woocommerce-product-attributes-item__value';
    
            if ( $(targetSelector).length ) {
                const htmlValue = $(targetSelector).html();
    
                $('form.cart').on('show_variation', function(event, data) {
                    if ( data.attr_description ) {
                        $(targetSelector).html(data.attr_description);
                    }
                }).on('hide_variation', function(){
                    $(targetSelector).html(htmlValue);
                });
            }
        });
        </script>
        <?php endif;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin).

    So in the admin for your variable product, go to the "variations" tab and click on "expand" link:

    enter image description here

    Then add the HTML content (limited to the allowed HTML tags defined) to each variation in "Attribute Description" textarea field:

    enter image description here

    Save changes.

    Now, in the front end, different HTML data will be displayed for each selected variation:

    enter image description here

    If no variation is selected, the default value (defined in the function) will be displayed:

    enter image description here

    You could also add multiple custom fields displayed on multiple rows…