How to list all product’s categories in magento 2 product page

Suppose you want to list all product categories in the product page, or even better, use that to show categories’ depend information (like a CMS Block for each category). How can you do it?

First, you will need to create a new block in the product page layout by adding a block statement into your catalog_product_view.xml file (which you can find or create in /app/design/frontent/<Theme_Vendor>/<Theme_Name>/Magento_Catalog/layout).

The code below will create a new block called product.category inside the product.info.main container (which is the container that holds pretty much all the relevant product information in the product page).

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
	<body>
		<referenceContainer name="product.info.main">
			<block class="Magento\Catalog\Block\Product\View" name="product.category" template="Magento_Catalog::product/view/categories.phtml" />		
		</referenceContainer>
	</body>
</page>

That block will be rendered using the categories.phtml template that needs to be created under /app/design/frontend/<Theme_Vendor>/<Theme_Name>/Magento_Catalog/templates/product/view (according to the template attribute that you see in the xml layout file above).

This is where the “magic” happens :).

<?php 
$_product = $block->getProduct(); 
$categories = $_product->getCategoryCollection()->addAttributeToSelect('*')->addIsActiveFilter();
                    
foreach ($categories as $category) {
	$category_block = 'category-'.strtolower(str_replace(' ','-',$category->getName()));
    if ($static_block = $this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId($category_block)->toHtml()) { ?>
		<div class="category-block">
			<?= $static_block; ?>
		</div>
	<?php }
}
?>

To get all the categories under which the product is listed you will need to call $_product->getCategoryCollection(). This will return a collection of categories that you can iterate.

In each iteration, the template will get the category name and look for a static block with an identifier equal to ‘category-<category_name>‘, where <category_name> is the category name in lowercase and with all spaces replaced with the ‘-‘ character.

If such a static block exists it will render it in the product page inside a div tag.

So, for example, if the product is listed under categories ‘Shoes’ and ‘Featured Articles’, the template will look for static blocks ‘category-shoes‘ and ‘category-featured-articles‘ and render their content if they exist.

And that’s it! Enjoy 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *