woocommerceattributesproducthook-woocommercecustom-fields

Use different displayed product attribute label name, based on custom fields in WooCommerce


In WooCommerce, I defined added/defined some product attributes with their names, and I wrote some code that should allow me to define alternative attribute label names at variable product level.

So in single product pages, for example, for some products the attribute "Color" can be displayed as "Color of T-Shirt", and on some others, "color of hat". This way, I have the flexibility to use the same attributes for different kind of items, but displaying different attribute label names in frontend.

// Create text input where text for custom label will be entered
add_action('woocommerce_product_options_attributes', 'add_custom_attribute_label_fields');
function add_custom_attribute_label_fields() {
    global $post;

    // Get the product attributes
    $product_attributes = maybe_unserialize(get_post_meta($post->ID, '_product_attributes', true));

    if (!empty($product_attributes)) {
        echo '<div class="options_group">';

        foreach ($product_attributes as $attribute_name => $attribute) {
            if ($attribute['is_taxonomy']) {
                $field_id = 'custom_attribute_label_' . $attribute_name;
                $label = get_post_meta($post->ID, $field_id, true);
              
                woocommerce_wp_text_input(array(
                    'id' => $field_id,
                    'label' => 'Name of the ATTRIBUTE ' . esc_html(wc_attribute_label($attribute["name"])) . ' for that product.',
                    'description' => esc_html('Please enter the name of that You would like to e shown at the single product page.'),
                    'desc_tip' => true,
                    'value' => esc_attr($label),
                ));
            }
        }
        echo '</div>';
    }
}

// Save the custom attribute labels
add_action('woocommerce_admin_process_product_object', 'save_custom_attribute_labels');
function save_custom_attribute_labels($product) {
    $product_id = $product->get_id();

    // Get the product attributes
    $product_attributes = maybe_unserialize(get_post_meta($product_id, '_product_attributes', true));

    if (!empty($product_attributes)) {
        foreach ($product_attributes as $attribute_name => $attribute) {
            if ($attribute['is_taxonomy']) {
                $field_id = 'custom_attribute_label_' . $attribute_name;
                if (isset($_POST[$field_id])) {
                    update_post_meta($product_id, $field_id, sanitize_text_field($_POST[$field_id]));
                }
            }
        }
    }
}
// Filter to display custom attribute label
add_filter('woocommerce_attribute_label', 'custom_attribute_label', 100, 3);
function custom_attribute_label($label, $name, $attproduct) {
    // Ensure $attproduct is an instance of WC_Product
    if (is_a($attproduct, 'WC_Product')) {
        $product_id = $attproduct->get_id();
        
        // Retrieve the custom label
        $custom_label = get_post_meta($product_id, 'custom_attribute_label_' . $name, true);

        // Check if custom label is not empty and return it
        if (!empty($custom_label)) {
            return $custom_label;
        }
    }
}

But I can't get it working. If I insert some "echos" inside function "custom attribute label", then I'm able to see the saved alternative attribute labels just at the variations form and repeated as many times as the number of variations I have, for that product. But the product attribute label name remain the old one.


Solution

  • There are some mistakes in your code, try the following revised code:

    // Add text input setting field where text for custom label will be entered
    add_action('woocommerce_product_options_attributes', 'add_custom_attribute_label_setting_fields');
    function add_custom_attribute_label_setting_fields() {
        global $post, $product_object;
    
        if ( $attributes = $product_object->get_attributes() ) {
            echo '<div class="options_group">';
    
            foreach ($attributes as $name => $attribute) {
                if ( $attribute->is_taxonomy() ) {
                    $field_key = 'custom_attr_label_'.$name;
                  
                    woocommerce_wp_text_input(array(
                        'id' => $field_key,
                        'label' => sprintf(__('Product attribute "%s" displayed custom label name'), wc_attribute_label($name)),
                        'description' => esc_html('Please enter the name of that You would like to e shown at the single product page.'),
                        'desc_tip' => true,
                    ));
                }
            }
            echo '</div>';
        }
    }
    
    // Save the custom attribute labels
    add_action('woocommerce_admin_process_product_object', 'save_custom_attribute_labels_fields_values');
    function save_custom_attribute_labels_fields_values($product) {
        if ( $attributes = $product->get_attributes() ) {
            foreach ($attributes as $name => $attribute) {
                if ( $attribute->is_taxonomy() ) {
                    $field_key = 'custom_attr_label_'.$name;
    
                    if ( isset($_POST[$field_key]) ) {
                        $product->update_meta_data($field_key, sanitize_text_field($_POST[$field_key]));
                    }
                }
            }
        }
    }
    
    // Display product attributes custom labels in single product pages
    add_filter('woocommerce_attribute_label', 'display_product_attributes_custom_labels', 20, 3);
    function display_product_attributes_custom_labels( $label, $name, $product ) {
        $custom_label = ''; // Initialize
    
        if ( ! is_admin() && ! is_a($product, 'WC_Product') ) {
            global $product;
    
            if ( is_a($product, 'WC_Product') ) {
                $custom_label = $product->get_meta('custom_attr_label_'.$name);
            }
        }
        return $custom_label ? $custom_label : $label;
    }
    

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