0

I added a new product Tab which displays the custom attribute value.

app/code/Vendor/Module/view/frontend/layout/catalog_product_view.xml

<referenceBlock name="product.info.details">
        <block class="Vendor\Module\Block\Product\Index" name="custom.tab" 
               template="Vendor_Module::product/view/custom.phtml" group="detailed_info">
            <action method="setTitle">
                <argument translate="true" name="title" xsi:type="string">My Example Tab</argument>
            </action>
        </block>
    </referenceBlock>

app/code/Vendor/Module/view/frontend/templates/product/view/custom.phtml

<?php $attribute = $block->getProduct(); 
  echo  $attribute->getMyattribute();
?>

I created a attribute called "my_attribute" whatever value is entered for the attribute in the product, That is getting displayed here.

Can we display the attribute value as Tab Label?

Currently the tab name is getting displayed as "My Example Tab" as we set the title in layout file.

My Example Tab

I am looking for the code where we can display the attribute value as a Tab label. Can someone help me in this..

3
1

You should create product tab programmatically to achieve this requirement. You should create one custom extension for it.

Step 1: Please create module.xml file. Package/Customtab/etc/module.xml

<?xml version="1.0" ?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Package_Customtab" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog" />
        </sequence>
    </module>
</config>

Step 2: Register your module: (Package/Customtab/registration.php)

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Package_CustomTab',
    __DIR__
);

Step 3: For demonstration purposes I’m creating only a Config model here to retrieve values quickly in the form of array, which will be further used to push to tabs.

So let go ahead and create a new Config model Package/CustomTab/Model/TabConfig.php:

<?php
namespace Package\CustomTab\Model;

use Magento\Catalog\Model\Product;
use Magento\Framework\Registry;

class TabConfig
{
    /**
     * @var array $tabs
     */
    private $tabs = [];

    /**
     * @var null|Product
     */
    private $product = null;

    /**
     * Core registry
     *
     * @var Registry
     */
    private $coreRegistry;

    /**
     * TabConfig constructor.
     * @param Registry $registry
     */
    public function __construct(
        Registry $registry
    ) {
        $this->coreRegistry = $registry;
    }
 
    /**
     * @return array
     */
    public function getTabs()
    {
        $this->tabs = [
            'tabA'  => [
                'title'         =>  $this->getProduct()->getMyattribute(),//Get your custom attribute value here to display value as a tab label
                'type'          =>  'template',
                'data'          =>  [
                    "type"      =>  "Magento\Framework\View\Element\Template",
                    "name"      =>  "lorem.ipsum",
                    "template"  =>  "Package_CustomTab::template_c.phtml"
                ],
                'description'   =>  '',
                'sortOrder'     =>  45
            ]
        ];

        return $this->tabs;
    }

    /**
     * @return Product
     */
    public function getProduct()
    {
        if (!$this->product) {
            $this->product = $this->coreRegistry->registry('product');
        }
        return $this->product;
    }
}

Step 4: Next step is the injection of this data to block and adding these blocks will be treated as child of block product.info.details

To achieve this we need to observe the generation of layouts after event i.e layout_generate_blocks_after. So let’s move a head and create an event observer.

Create events.xml inside Package/CustomTab/etc/:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="layout_generate_blocks_after">
        <observer name="package_layout_generate_blocks_after" instance="Package\CustomTab\Observer\NewTab" />
    </event>
</config>

Step 5: Now create observer class NewTab.php inside Package/CustomTab/Observer:

<?php

namespace Package\CustomTab\Observer;
 
use Package\CustomTab\Model\TabConfig;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
 
class NewTab implements ObserverInterface
{
    /**
     * @var string PARENT_BlOCK_NAME
     */
    const PARENT_BlOCK_NAME = 'product.info.details';
 
    /**
     * @var string RENDERING_TEMPLATE
     */
    const RENDERING_TEMPLATE = 'Package_CustomTab::tab_renderer.phtml';
 
    /**
     * @var TabConfig $tabs
     */
    private $tabs;
 
    /**
     * NewTab constructor.
     * @param TabConfig $tabs
     */
    public function __construct(TabConfig $tabs)
    {
        $this->tabs = $tabs;
    }
 
    /**
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {
        /** @var \Magento\Framework\View\Layout $layout */
        $layout = $observer->getLayout();
        $blocks = $layout->getAllBlocks();
 
        foreach ($blocks as $key => $block) {
            /** @var \Magento\Framework\View\Element\Template $block */
            if ($block->getNameInLayout() == self::PARENT_BlOCK_NAME) {
 
                foreach ($this->tabs->getTabs() as $key => $tab) {
                    $block->addChild(
                        $key,
                        \Magento\Catalog\Block\Product\View::class,
                        [
                            'template' => self::RENDERING_TEMPLATE,
                            'title'     =>  $tab['title'],
                            'jsLayout'      =>  [
                                $tab
                            ]
                        ]
                    );
                }
            }
        }
    }
}

Step 6: Now create phtml rendering template: Package/CustomTab/view/frontend/templates/tab_renderer.phtml:

<?php
/**
 * @var \Magento\Catalog\Block\Product\View $block
 */
?>
<?php
if (!empty($block->getJsLayout())) {
    $jsLayout = \Zend_Json::decode($block->getJsLayout());
    foreach ($jsLayout as $layout) {
        if (isset($layout['type']) && 'template' === $layout['type'] && isset($layout['data'])){
            echo $this->getLayout()->createBlock($layout['data']['type'])
                ->setDisplayType($layout['data']['name'])
                ->setTemplate($layout['data']['template'])->toHtml();
        } else {
            ?>
            <h1><?= $layout['title']; ?></h1>
            <div><?= $layout['description']; ?></div>
            <?php
        }
    }
}

Step 7: We are step behind rendering the blocks. To render these blocks we need to add block names to grouped child data. The best way we can do with it is to add these blocks name via interceptor (plugin) to grouped data.

First create plugin configuration: Package/CustomTab/etc/frontend/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
 
    <type name="Magento\Catalog\Block\Product\View\Details">
        <plugin name="package_product_view_description" type="Package\CustomTab\Plugin\Description" />
    </type>
 
</config>

Step 8: Create Plugin instance class: Package/CustomTab/Plugin/Description.php:

<?php
namespace Package\CustomTab\Plugin;
 
use Package\CustomTab\Model\TabConfig;
 
class Description
{
    /**
     * @var TabConfig $tabs
     */
    private $tabs;
 
    /**
     * Description constructor.
     * @param TabConfig $tabs
     */
    public function __construct(
        TabConfig $tabs
    ) {
        $this->tabs = $tabs;
    }
 
    /**
     * @param \Magento\Catalog\Block\Product\View\Details $subject
     * @param array $result
     * @return array
     */
    public function afterGetGroupSortedChildNames(
        \Magento\Catalog\Block\Product\View\Details $subject,
        $result
    ) {
        if (!empty($this->tabs->getTabs())) {
            foreach ($this->tabs->getTabs() as $key => $tab) {
                $sortOrder = isset($tab['sortOrder']) ? $tab['sortOrder'] : 45;
                $result = array_merge($result, [ $sortOrder => 'product.info.details.' . $key]);
            }
        }
        return $result;
    }
}

Step 9: Now create template c renderer template:Package/CustomTab/view/frontend/templates/template_c.phtml

<?php
/**
 * @var \Magento\Framework\View\Element\Template $block
 */
?>
<h3>Custom Block</h3>
<div>
    <h4>What is Lorem Ipsum?</h4>
    <p>
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
</div>

Please check and let me know if you have any query.

2
  • Thank you @ZealousWeb, Its working well, can you suggest how to add ifconfig in this approach? – Manjunath Feb 5 at 15:03
  • I resolved it in other way, just checking with you is any way we can achieve using ifconfig.. – Manjunath Feb 5 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.