How to add tags to WooCommerce products

When a client came to me and asked me to add tags over the thumbnail in WooCommerce Archive and Category pages I thought that it would probably be an easy straight-forward task, and yet I couldn’t find an implementation that fits my needs, so I decided to write my own. I broke the task into several smaller tasks for ease of development:

  1. Make the HTML and CSS for the tags
  2. Find an appropriate hook where you want your tags code added
  3. Design the logic for the tags

Make the HTML and CSS for the tags

First part is adding the following CSS to your theme or child theme style.css

.flagcontainer {
    position: absolute;
    top: -5px;
    left: -5px;
    line-height: 26px;
    /**/
    display:block;
}

.flag {
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
    width: auto;
    padding: 2px 10px;
    text-align: center;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    z-index: 1;
    text-shadow: 1px 1px 1px rgba(0,0,0,.2);
    /**/
    display:block;
    margin-bottom:10px;
    margin-top: 10px;
}

.flag.new {
    background-color: #ca5410
}

.flag.free-shipping {
    background-color: #10caa9
}

.flag.discount {
    background-color: #d60a2c
}

.price > ins span {
    color: #d60a2c!important;
}
@media(min-width: 1200px) {
    .flag {
        font-size:14px
    }
}

You can define more flag colors by adding the following class to your style.css changing tag-name with the name you want to use and #123456 with the color you want to use:

.flag.tag-name {
    background-color: #123456
}

Now in order to use your flags you need the following HTML

<div class="flagcontainer">
    <span class="flag discount">-20%</span>
    <span class="flag free-shipping">Free shipping</span>
</div>

You can add multiple flags in the main “flagcontainer”

Find an appropriate hook where you want your tags code added

In order to find the appropriate hook to add my code to I started exploring the WooCommerce code starting from “templates/archive-product.php” where I discovered that within the loop they include the template “templates/content-product.php”. In there I found a pretty well documented hooks, acctions and priorities. The hook that made most sense for me was:

//templates/content-product.php - Line 39 - 45
/**
 * woocommerce_before_shop_loop_item_title hook.
 *
 * @hooked woocommerce_show_product_loop_sale_flash - 10
 * @hooked woocommerce_template_loop_product_thumbnail - 10
 */
do_action( 'woocommerce_before_shop_loop_item_title' );

So I decided to hook my code to the action “woocommerce_before_shop_loop_item_title”

Design the logic for the tags

Now that we have the HTML and CSS of the tags themselves and the action to which we want to hook our code lets get our hands dirty and do some coding. In your theme/child-theme functions.php add the following code, that will be the skeleton of the tags logic:

add_action( 'woocommerce_before_shop_loop_item_title', function() {
    echo woocommerce_get_product_thumbnail();
    global $product;
    echo '<div class="flagcontainer">';
    //Add the logic for your tags here
    echo '</div>';
}, 10 );

If the product is on sale, show the discount in percentage eg. “-20%”

In order to achieve that you need to know a few things first: how to know if a product is on sale, and how to get the maximum discount from all variations of the product. For the first part you’ll need some help from the is_on_sale() function of the WooCommerce products. And for the second part we need the get_available_variations() function. Here is the actual code for this part:

if( $product->is_on_sale() )
{	
    if( $product->is_on_sale() )
    {
	$available_variations = $product->get_available_variations();								
	$maximumper = 0;
	for ($i = 0; $i < count($available_variations); ++$i) {
		$variation_id=$available_variations[$i]['variation_id'];
		$variable_product1= new WC_Product_Variation( $variation_id );
		$regular_price = $variable_product1 ->regular_price;
		$sales_price = $variable_product1 ->sale_price;
		$percentage= round((( ( $regular_price - $sales_price ) / $regular_price ) * 100),1) ;
		if ($percentage > $maximumper) {
	        	$maximumper = $percentage;
		}
	}
	echo '<span class="flag left discount">'.sprintf( __('%s', 'woocommerce' ), '-'.round($maximumper) . '%' ).'</span>';	
    }
}

If the product is over a certain price show the free shipping tag

This one is a tad easier then the previous point, so I’ll straight-up go to the code:

//2.If price is > 499
if((int)$product->price >= 499)
{
    echo '<span class="flag free-shipping">Free shipping</span>';	
}

Show the manually added tags by the user

That part is also not hard at all, you just need to loop through the product tags, which are simply a WordPress term, so you can use the get_the_terms function for the taxonomy ‘product_tag’ and loop through the results in the following way:

//3.If there are tags
$terms = get_the_terms( get_the_ID(), 'product_tag' );
$term_array = array();
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
    foreach ( $terms as $term ){
	echo '<span class="flag new">'.$term->name.'</span>';
    }
}

And the complete code for your functions.php is

add_action( 'woocommerce_before_shop_loop_item_title', function() {
    echo woocommerce_get_product_thumbnail();
	global $product;
	echo '<div class="flagcontainer">';
	//1.Show discount percentage in a tag
	if( $product->is_on_sale() )
	{	
		if( $product->is_on_sale() )
		{
			$available_variations = $product->get_available_variations();								
			$maximumper = 0;
			for ($i = 0; $i < count($available_variations); ++$i) {
				$variation_id=$available_variations[$i]['variation_id'];
				$variable_product1= new WC_Product_Variation( $variation_id );
				$regular_price = $variable_product1 ->regular_price;
				$sales_price = $variable_product1 ->sale_price;
				$percentage= round((( ( $regular_price - $sales_price ) / $regular_price ) * 100),1) ;
				if ($percentage > $maximumper) {
					$maximumper = $percentage;
				}
			}
			echo '<span class="flag discount">'.sprintf( __('%s', 'woocommerce' ), '-'.round($maximumper) . '%' ).'</span>';	
		}
	}
	//2.If price is > 499
	if((int)$product->price >= 499)
	{
		echo '<span class="flag free-shipping">Free shipping</span>';	
	}
	//3.If there are tags
	$terms = get_the_terms( get_the_ID(), 'product_tag' );
	$term_array = array();
	if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
		foreach ( $terms as $term ){
			echo '<span class="flag new">'.$term->name.'</span>';
		}
	}
	echo '</div>';
}, 10 );

 


You can download the code for this how-to in
About Pavel Petrov 2 Articles |  21 How-tos
Pavel is a senior developer for the last 7 years, with extended interest in Linux administration, WordPress and Symfony.