You’ve probably seen it before when viewing other eCommerce stores; the products display which WooCommerce product attributes (or variations) are available for a product on the single product page.

WooCommerce Attributes on Shop Page

At this point, you’ve probably asked yourself “how do I display custom product attributes on the WooCommerce shop page of my WooCommerce store?”.

Right?

Well let me guide you step-by-step through it with 3 potential methods:

Method 1: Code it Yourself

Let’s think about what we want to achieve here:

  • Display an attribute (or attributes) like “Color” or size attribute under product data in the WooCommerce shop.
  • Display each attribute value, and indicate it’s availability with a strikethrough.
  • Only show attributes on variable products where the attribute is used for WooCommerce variations.

Here, we’ll explain how you can enhance the default WooCommerce shop page. The first thing we’ll do is hook into the loop. We’ll output out attributes after the product title, so I’m going to use the woocommerce_shop_loop_item_title action.

/**
 * Display available attributes.
 * 
 * @return array|void
 */
function iconic_available_attributes() {
	global $product;

	if ( ! $product->is_type( 'variable' ) ) {
		return;
	}

	$attributes = iconic_get_available_attributes( $product );

	if ( empty( $attributes ) ) {
		return;
	}

	foreach ( $attributes as $attribute ) {
		?>
		<div class="iconic-available-attributes">
			<p class="iconic-available-attributes__title"><?php _e( 'Available', 'iconic' ); ?> <strong><?php echo $attribute['name']; ?></strong></p>

			<ul class="iconic-available-attributes__values">
				<?php foreach ( $attribute['values'] as $value ) { ?>
					<li class="iconic-available-attributes__value <?php echo $value['available'] ? '' : 'iconic-available-attributes__value--unavailable'; ?>"><?php echo $value['name']; ?></li>
				<?php } ?>
			</ul>
		</div>
		<?php
	}
}

add_action( 'woocommerce_shop_loop_item_title', 'iconic_available_attributes', 20 );

Firstly, we check if the product SKU is variable. If not, we return and do nothing.

Next we fetch the available attributes using a custom iconic_get_available_attributes() function, detailed shortly.

If there aren’t any attributes, we return the function again and do nothing.

Otherwise, we loop through the attributes array. We break out of PHP files and add some HTML.

We echo the attribute name into a p tag and then loop through the values into a list (the ul and li tags).

Simple!

But what about the iconic_get_available_attributes() function? That’s where things get a bit more complicated.

/**
 * Get available attributes.
 *
 * @param WC_Product_Variable $product
 *
 * @return array
 */
function iconic_get_available_attributes( $product ) {
	static $available_attributes = array();

	$product_id = $product->get_id();

	if ( isset( $available_attributes[ $product_id ] ) ) {
		return $available_attributes[ $product_id ];
	}

	$available_attributes[ $product_id ] = array();

	$attributes = $product->get_variation_attributes();

	if ( empty( $attributes ) ) {
		return $available_attributes[ $product_id ];
	}

	$attributes_to_show = iconic_get_attributes_to_show();

	foreach ( $attributes as $attribute => $values ) {
		if ( ! in_array( $attribute, $attributes_to_show ) ) {
			continue;
		}

		$available_attribute = iconic_get_available_attribute( $product, $attribute, $values );

		if ( empty( $available_attribute ) ) {
			continue;
		}

		$available_attributes[ $product_id ][] = $available_attribute;
	}

	return $available_attributes[ $product_id ];
}

This is where we’re going to fetch the attributes and then check whether they are purchasable.

The function accepts 1 parameter, $product, which we know will always be a variable product (an instance of WC_Product_Variable).

I’m using some static caching here. By stating that $available_attributes is a static variable, we can assign our data to it one time and then reference the “cached” data later on without rerunning all of the code.

So we start by getting the ID of the product. Then we check whether our data has already been assigned to the $available_attributes array for this product. if it has, we return it. Remember: as soon as you return in a function, the function stops running and the data is returned to the caller.

Otherwise, we assign an empty array to that product ID.

We then use the built in get_variation_attributes() method for the product. This will fetch only those attributes which have been used for a variation. This ignores whether those variations are in stock or purchasable.

If there aren’t any (unlikely), then we return the empty array. Otherwise, we continue.

I’m then calling iconic_get_attributes_to_show(). This returns an array of which attributes we want to display for each product.

/**
 * Get attributes to show.
 *
 * @return array
 */
function iconic_get_attributes_to_show() {
	return apply_filters( 'iconic_get_attributes_to_show', array(
		'pa_color',
	) );
}

If it’s a product specific attribute, you’d just enter the attribute name that you used (make sure to match the case).

Then we loop through the attributes. If the attribute is not in out $attributes_to_show array, then we continue. This will go to the next item item in the loop.

Next we fetch the attribute data, including whether it’s purchasable, using the iconic_get_available_attribute() function.

If data is returned, we add it to the $available_attributes array.

iconic_get_available_attribute() is a function that will convert the attribute data we already have into something more useful. It will determine the correct attribute labels and also whether the attribute has a variation which is available for purchase.

/**
 * Get available attribute.
 *
 * @param WC_Product_Variable $product
 * @param string              $attribute
 * @param array               $values
 *
 * @return array
 */
function iconic_get_available_attribute( $product, $attribute, $values ) {
	$available_attribute = array(
		'slug' => $attribute,
	);

	if ( ! taxonomy_exists( $attribute ) ) {
		$available_attribute['name'] = $attribute;

		foreach ( $values as $value ) {
			$available_attribute['values'][ $value ] = array(
				'name'      => $value,
				'available' => iconic_has_available_variation( $product, $attribute, $value ),
			);
		}

		return $available_attribute;
	}

	$taxonomy = get_taxonomy( $attribute );
	$labels   = get_taxonomy_labels( $taxonomy );

	$available_attribute['name']   = $labels->singular_name;
	$available_attribute['values'] = array();

	foreach ( $values as $value ) {
		$term = get_term_by( 'slug', $value, $attribute );

		if ( ! $term ) {
			continue;
		}

		$available_attribute['values'][ $value ] = array(
			'name'      => $term->name,
			'available' => iconic_has_available_variation( $product, $attribute, $value ),
		);
	}

	return $available_attribute;
}

The function accepts 3 parameters:

  • $product
    This is the product object. An instance of WC_Product_Variable.
  • $attribute
    This is the attribute slug, or name if it’s a product specific attribute.
  • $values
    This is an array of the available attribute values.

The function is going to return an array of data. The array will contain:

  • slug
    This is the attribute slug.
  • name
    This is the attribute label.
  • values
    This is a further formatted list of attribute values. Each value contains the following data:
    • name
      This is the attribute value label.
    • available
      This is a true or false flag which indicates whether there’s a variation available for this attribute value.

To get started, we check whether this attribute exists as a taxonomy. If it does, we handle the data slightly differently.

If there’s no taxonomy for it, then we know it’s a custom attribute for this specific product.

This means $attribute is the name/label of the attribute so we can assign that to our array already.

Then we loop through the $values.

We add the value to our new array, assigning it a name and using iconic_has_available_variation() to check whether there’s a purchasable variation for the attribute value.

Once complete, we return the newly formatted attribute data.

If this attribute was a taxonomy, we skipped all that and started by fetching the taxonomy object.

We then use get_taxonomy_labels() to fetch the labels for the attribute.

For the name key in our array we can use the singular label.

Then we’ll loop through the values again and assign them to the array with their additional data.

In this instance, each $value is a term slug. As such, we fetch the term using get_term_by().

If it exists, we assign the data to the `$available_attribute` array. Once all values are complete, we return the array.

The final function we need to run through is iconic_has_available_variation(). This function simply checks whether there’s a variation available to purchase with that attribute value and returns true or false.

/**
 * Has available variation?
 *
 * @param WC_Product_Variable $product
 * @param string              $attribute
 * @param string              $value
 *
 * @return bool
 */
function iconic_has_available_variation( $product, $attribute, $value ) {
	$available_variation = false;
	$attribute           = 'attribute_' . sanitize_title( $attribute );
	$variations          = $product->get_available_variations();

	if ( empty( $variations ) ) {
		return $available_variation;
	}

	foreach ( $variations as $variation ) {
		foreach ( $variation['attributes'] as $variation_attribute_name => $variation_attribute_value ) {
			if ( $attribute !== $variation_attribute_name ) {
				continue;
			}

			if ( $value !== $variation_attribute_value && ! empty( $variation_attribute_value ) ) {
				continue;
			}

			$available_variation = $variation['is_purchasable'] && $variation['is_in_stock'];
			break;
		}

		if ( $available_variation ) {
			break;
		}
	}

	return $available_variation;
}

Firstly we need to format the attribute “slug” to match that of the variations. WooCommerce simply prefixes them with attribute_.

We’re then going to fetch all variations available using the get_available_variations() method.

We’ll loop through each variation, and then each attribute for that variation.

Is the attribute does not match the one we are looking for we continue to the next attribute in the loop. Otherwise we proceed.

If the attribute value does not match the one we’re looking for, and the value is not empty (I.e. “Any Color…” has been selected) then we continue to the next attribute in the loop. Otherwise we proceed.

Next we check if the variation is in stock and purchasable. If either of them is not true, we continue to the next attribute in the loop. Otherwise we proceed.

If we got this far, it means we found a matching purchasable variation. We set $available_variation to true, then break out of the loop and return it.

That’s it! Now any attributes you assigned in iconic_get_attributes_to_show() will be displayed in your WooCommerce shop.

Method 2: Use WooCommerce Attribute Swatches

WooCommerce Attribute Swatches is a WordPress plugin which allows you to display your variable product options as colors, images, radio buttons, or text swatches in WooCommerce pages. It also has “show in catalog” functionality built in. You can do all of this without using shortcodes or widgets.

When you set an attribute to be visible in the WooCommerce catalog, it will show in the format you’ve chosen without affecting the shop page layout. For example, if your attribute uses color swatches, then the screenshot below depics what will show in the catalog and shop pages on the front-end instead of in a dropdown menu. This is possible without using a shortcode.

WooCommerce Change Product Image by Color

You can also choose whether the attribute values click through to the WooCommerce product and pre-select that option, or change the product image in the catalog; a great way to preview different colours of your product.

WooCommerce Attribute Swatches

Turn your WooCommerce product options into color, image, or text swatches. Instantly enhance your customers' online experience.

The WooCommerce Attribute Swatches plugin works seamlessly with most WordPress themes and page builders (like Elementor).

Method 3: Use WooCommerce Show Single Variations

Another popular option is to show the variations in your shop as though they were individual products. WooCommerce Show Single Variations for WordPress allows you to do just that as is shown in the screenshot below.

Once enabled you can choose which variations to display in your shop and product category page, and where to display them. This also boosts your WooCommerce shop page SEO without affecting the shop page layout.

You can display product variations everywhere, catalog pages, filtered results, and search results. You can then hide the parent product. The best part is that you don’t have to create any new pages.

Clicking on a variation will link you through to the variable product and preselect the appropriate options for the variation. From there, customers can add products to their WooCommerce cart and proceed to the checkout page.

This is a fantastic way to improve your WooCommerce product collection and customer experience on your WooCommerce store. Users can filter by attributes and see the exact variation they want to purchase.

WooCommerce Show Single Variations

Display individual product variations of a variable product in your product listings. Make it easy for your customers to view and filter product variations.

Conclusion

This article will give you plenty of options to make your customers aware of what options are available for each of your variable products. We also shared some helpful WooCommerce template files to help you enhance your own WooCommerce shop page template.

Keep in mind that you should always create a child theme for your WordPress theme (e.g. a Storefront child theme for your parent theme) to add custom code to, even if you’re using a page builder like Elementor.

Any questions? Simply comment below.