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 🙂