Add Some Attribute Values to Woocommerce Variable Product Title from Chosen Variation

Add some attribute values to WooCommerce variable product title from chosen variation

UPDATE 04-2021 - Successfully tested on WooCommerce 5.1+ (handle custom product attributes)

The following code, will add to variable product title the value(s) of the chosen variation from specific defined product attribute(s) (or all of them optionally too):

The code:

// Defining product Attributes term names to be displayed on variable product title
add_filter( 'woocommerce_available_variation', 'filter_available_variation_attributes', 10, 3 );
function filter_available_variation_attributes( $data, $product, $variation ){
// Here define the product attribute(s) slug(s) which values will be added to the product title
// Or replace the array with 'all' string to display all attribute values
$attribute_names = array('Custom', 'Color');

foreach( $data['attributes'] as $attribute => $value ) {
$attribute = str_replace('attribute_', '', $attribute);
$attribute_name = wc_attribute_label($attribute, $variation);

if ( ( is_array($attribute_names) && in_array($attribute_name, $attribute_names) ) || $attribute_names === 'all' ) {
$value = taxonomy_exists($attribute) ? get_term_by( 'slug', $value, $attribute )->name : $value;

$data['for_title'][$attribute_name] = $value;
}
}
return $data;
}

// Display to variable product title, defined product Attributes term names
add_action( 'woocommerce_after_variations_form', 'add_variation_attribute_on_product_title' );
function add_variation_attribute_on_product_title(){
// Here define the separator string
$separator = ' - ';
?>
<script type="text/javascript">
(function($){
var name = '<?php global $product; echo $product->get_name(); ?>';

$('form.cart').on('show_variation', function(event, data) {
var text = '';

$.each( data.for_title, function( key, value ) {
text += '<?php echo $separator; ?>' + value;
});

$('.product_title').text( name + text );

}).on('hide_variation', function(event, data) {
$('.product_title').text( name );
});
})(jQuery);
</script>
<?php
}

Displaying all attributes

You can display all variations attributes values for the chosen variation by defining the variable $attribute_names to "all" so like:

$attribute_names = "all";

Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.

Tested and works… you will get something like:

Sample Image

change title of variable woocommerce product based on attribute value selection

Not sure why you used php, that's totally front task - so should be done with front js.

Please add this js to external javascript file (it so bad practice to inject js inline, especially jquery - it will block defer optimization)
How it works:

  1. get default title text to var
  2. collect all variation selected and add to default title text
  3. set new text to title
jQuery( document ).ready( function( $ ) {
var title_text = $( '.product-type-variable .product_title' ).text(); // get default title
function add_variation_txt_to_title() {
var new_title_text = '';
$( '.variations select' ).each( function() {
new_title_text += ' ' + $( this ).find( ':selected' ).val(); // collect all variation selected <options>
})
$( '.product-type-variable .product_title' ).text( title_text + new_title_text ); // set new title
}
add_variation_txt_to_title(); // call on load
$( '.variations select' ).change( function() { // call on <select >change
add_variation_txt_to_titl();
})
})

Solution tested on default twentyseventeen theme.

Show the name of the chosen variation under the product title on the My Account Downloads page

There is some confusion in the initial part of the question.

You say you want to show the attribute under the product title on the cart and checkout page but then return __return_false, do you intend to do the opposite?

SOLUTION #1

You may want to reverse the check to make sure that your chosen product variation attribute is shown under the product name on your account page under Downloads (as evidenced by your comment above):

add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );

add_filter( 'woocommerce_product_variation_title_include_attributes', 'show_attributes_outside_title_1' );
function show_attributes_outside_title_1( $enabled ) {
if ( is_account_page() ) {
$enabled = true;
}
return $enabled;
}

add_filter( 'woocommerce_is_attribute_in_product_name', 'show_attributes_outside_title_2' );
function show_attributes_outside_title_2( $enabled ) {
if ( ! is_account_page() ) {
$enabled = false;
}
return $enabled;
}

SOLUTION #2

If you want to leave the code in your question unchanged you can use the woocommerce_account_downloads_column_download-product hook where download-product is the id of the product name column (in the /my-account/downloads/ page). Here the documentation.

Finally, with the wc_get_formatted_variation function you can get the name of the chosen variation. For more information on parameters read the documentation.

// shows the variation chosen in the product name in the download table of the my-account page
add_action( 'woocommerce_account_downloads_column_download-product', 'change_product_download_name', 10, 1 );
function change_product_download_name( $download ) {
// gets the product object
$product = wc_get_product( $download['product_id'] );
// gets the name of the produc
$product_name = $download['product_name'];
// if the product is a variation
if ( $product->is_type( 'variation' ) ) {
// gets the name of the product with the chosen variation
$product_name = $product->get_name() . " - " . wc_get_formatted_variation( $product, true, false, false );
}
// print the product name (with or without product url)
if ( $download['product_url'] ) {
echo '<a href="' . esc_url( $download['product_url'] ) . '">' . esc_html( $product_name ) . '</a>';
} else {
echo esc_html( $product_name );
}
}

The code has been tested and works. Add it to your active theme's functions.php.

Create programmatically a WooCommerce product variation with new attribute values

Update January 2020: Changed to WC_Product method get_name() instead of get_title()
Update September 2018: Handling taxonomy creation (Thanks to Carl F. Corneil)

From a defined variable product ID You will find below, a custom function that will add (create) a Product variation. The variable parent product needs to have set for it the needed attributes.

You will need to provide some information as:

  • the array of attributes/values
  • the Sku, prices and stock….

This data has to be stored in a formatted multi dimensional array (see an example at the end).

This function will check if the attributes values (term name) already exist and if not:

  • it create it for the product attribute
  • set it in the parent variable product.

The custom function code:

/**
* Create a product variation for a defined variable product ID.
*
* @since 3.0.0
* @param int $product_id | Post ID of the product parent variable product.
* @param array $variation_data | The data to insert in the product.
*/

function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);

$variation_post = array(
'post_title' => $product->get_name(),
'post_name' => 'product-'.$product_id.'-variation',
'post_status' => 'publish',
'post_parent' => $product_id,
'post_type' => 'product_variation',
'guid' => $product->get_permalink()
);

// Creating the product variation
$variation_id = wp_insert_post( $variation_post );

// Get an instance of the WC_Product_Variation object
$variation = new WC_Product_Variation( $variation_id );

// Iterating through the variations attributes
foreach ($variation_data['attributes'] as $attribute => $term_name )
{
$taxonomy = 'pa_'.$attribute; // The attribute taxonomy

// If taxonomy doesn't exists we create it (Thanks to Carl F. Corneil)
if( ! taxonomy_exists( $taxonomy ) ){
register_taxonomy(
$taxonomy,
'product_variation',
array(
'hierarchical' => false,
'label' => ucfirst( $attribute ),
'query_var' => true,
'rewrite' => array( 'slug' => sanitize_title($attribute) ), // The base slug
),
);
}

// Check if the Term name exist and if not we create it.
if( ! term_exists( $term_name, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy ); // Create the term

$term_slug = get_term_by('name', $term_name, $taxonomy )->slug; // Get the term slug

// Get the post Terms names from the parent variable product.
$post_term_names = wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );

// Check if the post term exist and if not we set it in the parent variable product.
if( ! in_array( $term_name, $post_term_names ) )
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );

// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}

## Set/save all other data

// SKU
if( ! empty( $variation_data['sku'] ) )
$variation->set_sku( $variation_data['sku'] );

// Prices
if( empty( $variation_data['sale_price'] ) ){
$variation->set_price( $variation_data['regular_price'] );
} else {
$variation->set_price( $variation_data['sale_price'] );
$variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );

// Stock
if( ! empty($variation_data['stock_qty']) ){
$variation->set_stock_quantity( $variation_data['stock_qty'] );
$variation->set_manage_stock(true);
$variation->set_stock_status('');
} else {
$variation->set_manage_stock(false);
}

$variation->set_weight(''); // weight (reseting)

$variation->save(); // Save the data
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Usage (example with 2 attributes):

$parent_id = 746; // Or get the variable product id dynamically

// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '',
'stock_qty' => 10,
);

// The function to be run
create_product_variation( $parent_id, $variation_data );

Tested and works.

Part 2: Create programmatically a variable product and two new attributes in WooCommerce

You will get this in backend:

Sample Image

And it will work perfectly in front end.

Related: Create programmatically a product using CRUD methods in Woocommerce 3

Change WooCommerce Product Name to Include Attribute When Attribute Selected

This only work on variable products that have a Color product attribute (for variations) and it will append the selected Color attribute label value to the product title.

For your Home page you will use WordPress conditional tag is_front_page()
You will have to set also the Product ID that you are using in your shortcode.

1) In the Home page I have this shortcode example (with a variable product ID):

[product_page id="40"]

2) To make it work for both single product pages and the home page (product shortcode) too:

add_filter( 'wp_footer','custom_product_title_script' );
function custom_product_title_script(){
// Only single product pages and home page
if( ! ( is_product() || is_front_page() ) ) return;

// HERE Set your home product ID
$shortcode_product_id = 40; // <===== ===== ===== HERE your Shortcode Product ID

$product_id = is_product() ? get_the_id() : $shortcode_product_id;

// get an instance of the WC_Product Object
$product = wc_get_product( $product_id );

// Only for variable products
if( ! $product->is_type( 'variable' ) ) return;

// Here set your specific product attributes in this array (coma separated):
$attributes = array('pa_color');
// The 1st loop for variations IDs
foreach($product->get_visible_children( ) as $variation_id ) {
// The 2nd loop for attribute(s)/value
foreach($product->get_available_variation( $variation_id )['attributes'] as $key => $value_id ){
$taxonomy = str_replace( 'attribute_', '', $key ); // Get the taxonomy of the product attribute
// Just for defined attributes
if( in_array( $taxonomy, $attributes) ){
// Set and structure data in an array( variation ID => product attribute => term name )
$data[ $variation_id ][$taxonomy] = get_term_by( 'slug', $value_id, $taxonomy )->name;
}
}
}
?>
<script type="text/javascript">
(function($){
// variables initialization
var variationsData = <?php echo json_encode($data); ?>,
productTitle = $('.product_title').text(),
color = 'pa_color';
// function that get the selected variation and change title
function update_the_title( productTitle, variationsData, color ){
$.each( variationsData, function( index, value ){
if( index == $('input.variation_id').val() ){
$('.product_title').text(productTitle+' - '+value[color]);
return false;
} else {
$('.product_title').text(productTitle);
}
});
}
// Once all loaded
setTimeout(function(){
update_the_title( productTitle, variationsData, color );
}, 300);
// On live event: select fields
$('select').blur( function(){
update_the_title( productTitle, variationsData, color );
});
})(jQuery);
</script>
<?php
}

This code goes in any plugin file with a constructor (but not in function.php file).

Tested and works.

Change WooCommerce variable product title based on variations

Yes this is possible in the same hook. You can manipulate the product title with class WC_Product get_name() and set_name() methods. But as for the price, you should set and get a custom cart field value to make it (just as $additionalPrice = $value['core'];).

See here a simple related answer: Changing WooCommerce cart item names

So you could have something like (just a fake example):

// Get your custom field cart value for the user selection
$userSelection = $value['user_selection'];
// Get original title
$originalTitle = $value['data']->get_name();
// Conditionally set the new item title
if($userSelection == 'option2')
$value['data']->set_name( $originalTitle . '-RZ' );

Woocommerce, show selected attribute title after a product title

Add the code in your functions.php . Replace pa_color with your attribute

remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
add_action( 'woocommerce_single_product_summary', 'custom_template_single_title', 5 );
function custom_template_single_title() {
global $product;

$brand_name = $product->get_attribute('brand-name');
$brand_output = '';
if( $brand_name )
$brand_output = ' - ' . $brand_name;

echo sprintf('<h1 class="product_title entry-title">%s %s <span></span></h1>',get_the_title(),$brand_output);
}

function change_title_on_color_change() {
global $product;
if($product->get_type() !== 'variable') return;
?>
<script>
jQuery(function($) {

$(document).ready(function() {
update_product_title();
});
$('select#pa_color').change( function(){
update_product_title();
});
function update_product_title() {
var color_val = $('select#pa_color option').filter(':selected').val();
var color_text = $('select#pa_color option').filter(':selected').text();
if(color_val.length > 0) {
$('.product_title.entry-title span').text(' - ' + color_text);
} else {
$('.product_title.entry-title span').empty();
}
}
});
</script>
<?php
}
add_action('woocommerce_after_single_product','change_title_on_color_change');


Related Topics



Leave a reply



Submit