Whether horizontal (which are more common) or vertical, tabs are a great way to avoid information overload by organizing large content into easily digestible chunks of data. When done right they provide all the information (related to one specific subject) without overwhelming users, allowing them to quickly navigate through the content by showing data from just one tab at a time. From the UX standpoint tabs’ main purpose is to simply facilitate access to information and it’s also useful to know that they don’t have any negative effect on your SEO and site ranking in any way.
In Magento, like in most other eCommerce platforms, tabbed navigation is utilized on product pages for displaying various product information and data. By default, and this is the same for Luma and Blank theme, there are three tabs on the product page:
– details about the product i.e. description
– more information which stores product attributes and values
– reviews provided by products buyers and consumers
These tabs can easily be customised, and we’ll show you how. But, just before we start let’s take some time to explore and find out which templates and layout files we are actually going to customise. One way to do this is to enable Template Path Hints and add Block Names to Hints through Magento admin:
Stores => Configuration => Advanced => Developer => Debug
Although, it’s doubtful how useful these debug settings are at least now we know which Magento module (hint: module-catalog) is responsible for product info tabs so we can begin with our customisation. Let’s start off easy.
Renaming product tabs
In order to set another title for our tab we have to override base layout file catalog_product_view.xml
found inside vendor/module_catalog
folder. Standard (Magento) way to do this is to create new layout file inside our theme scope and name it exactly like the base file.
Our file path should look like this:
app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/layout/catalog_product_view.xml
And the code inside our file like this:
<?xml version="1.0"?>
<page layout="1column" xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi_noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.details">
<referenceBlock name="product.info.description">
<arguments>
<argument name="title" translate="true" xsi_type="string">Description</argument>
</arguments>
</referenceBlock>
</referenceBlock>
</body>
</page>
If we analyse the code above we’ll see that the first layout handler
<referenceBlock name="product.info.details"> reference our product tabbed navigation as a whole while the child handler <referenceBlock name="product.info.description"> reference single tab, in our case details tab. With <argument name="title" translate="true" xsi_type="string"> we simply set new title for our tab. <arguments> handler is just a (required) container for <argument> and it does’t have it’s own attributes.
Removing product tabs
This one is even more simple. We just have to reference our target block and set remove attribute to true. So our catalog_product_view.xml
looks like this:
<?xml version="1.0"?>
<page layout="1column" xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi_noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.review" remove="true" />
</body>
</page>
Adding custom tab
Now, let’s say we want to create an additional tab in our product info tabs and populate it with content e.g. value of some particular attribute. For demonstration purpose, let’s say that our new tab will hold information about contents of product packaging.
First, from Magento admin, we will create new attribute, let’s name it Packaging
and add it to default
attribute set.
Next, we will:
– create new template file, we can name it packaging-content.phtml
– save it in: app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/view/
– paste the following code:
<?php
$_helper = $this->helper('MagentoCatalogHelperOutput');
$_product = $block->getProduct();
$_code = $block->getAtCode();
$_className = $block->getCssClass();
$_attributeLabel = $block->getAtLabel();
$_attributeType = $block->getAtType();
$_attributeAddAttribute = $block->getAddAttribute();
if ($_attributeLabel && $_attributeLabel == 'default') {
$_attributeLabel = $_product->getResource()->getAttribute($_code)->getFrontendLabel();
}
$_attributeValue = $_product->getResource()->getAttribute($_code)->getFrontend()->getValue($_product);
?>
<?php if ($_attributeValue): ?>
<div class="packaging-content" <?php echo $_attributeAddAttribute;?>>
<?php echo $_attributeValue; ?>
</div>
<?php endif; ?>
N.B. attribute set (from the first step) must match string value in our if statement (line: 9)
Third and final step is to place following code in our layout file catalog_product_view.xml
:
<?xml version="1.0"?>
<page layout="1column" xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi_noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.details">
<block class="MagentoCatalogBlockProductViewDescription" name="packaging-content" template="Magento_Catalog::product/view/packaging-content.phtml" group="detailed_info">
<arguments>
<argument name="at_call" xsi_type="string">getPackaging</argument>
<argument name="at_code" xsi_type="string">packaging</argument>
<argument name="css_class" xsi_type="string">packaging</argument>
<argument name="at_label" xsi_type="string”>packaging</argument>
<argument name="add_attribute" xsi_type="string">itemprop="packaging"</argument>
<argument name="title" translate="true" xsi_type="string">Packaging content</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
Adding related products in tabbed navigation
For adding related products we also need two files, template and layout:
Our template file, we shall name it related-products.phtml
and save it in app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/
will have just one line of code:
<?php echo $this->getBlockHtml('catalog.product.related'); ?>
And our layout file catalog_product_view.xml
should look like this:
<?xml version="1.0"?>
<page layout="1column" xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi_noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<!— 1st Code Block: Get Related Products as new tab -->
<referenceBlock name="product.info.details">
<block class="MagentoCatalogBlockProductView" name="deliveryinfo.tab" as="deliveryinfo" template="Magento_Catalog::product/related-products.phtml" group="detailed_info" >
<arguments>
<argument translate="true" name="title" xsi_type="string">Related Products</argument>
</arguments>
</block>
</referenceBlock>
<!— 2nd Code Block: Move original block to product info tabs -->
<move element="catalog.product.related" destination="product.info.details" />
</body>
</page>
First code block is to set up a new tab with related products, and the second one is for removing the original block from layout flow.
In similar fashion this can be done for displaying upsell products as well. All we need to do is change our template (we can name it upsell-products.phtml
) file to:
<?php echo $this->getBlockHtml('product.info.upsell'); ?>
And in our layout file change:
– name of template file to upsell-products.phtml
(line: 6)
– title of our tab to “You might be interested” or something similar (line: 8)
– element attribute to product.info.upsell
(line: 14)
Wrapping up
As you can see from these examples, it’s fairly easy to customise product page tabbed navigation. Add some CSS for styling and you’ll have your new tabs with new customised content in a matter of few hours.
And if you wish to customise some other parts of product page you can refer to this blog post.