6

I've read many add tabs post here, but can't seem to get any to work the way I need to work.

  1. Attribute is 'sizechart' and is text field added to the default attribute set (but could be dropdown or multiselect)

  2. In admin product add text to "sizechart" attribute eg "levi-size" ("levi-size' is name of CMS/Block already created in the backend).

  3. The product page would then display the new tab with the CMS/Block

Since the size charts for different manufacturers aren't the same, I can't make a static tab, but need one which will use the custom test field or even better, a dropdown where the storefront labels contain the CMS/Block widget code such as below

{{widget type="Magento\Cms\Block\Widget\Block" template="widget/static_block/default.phtml" block_id="3"}}

I had this working very well in 1.9, but since 2.2, I can't seem to find a way to make this work.

The code I've seen here for Magento 2 and 2.1 doesn't seem to work for 2.2 and I'm not sure what the solution is. I expect this to go to bounty in a few days ...

In the admin, you enter the text into the attribute field that matches the CMS Block ID

On the product page, the content of the CMS block is displayed as a tab on the product page. The same tab "Warranty" would display different content based on CMS Block ID

Ideally, creating a drop down where the admin label is "oneill" and the storefront field is

{{widget type="Magento\Cms\Block\Widget\Block" template="widget/static_block/default.phtml" block_id="3"}}

witch would correspond to the oneill warranty information would be much better.

And the same for size charts as well.

EDIT: For 2.3.2, the tabs were before the product details. To change that, I added SORT to the catalog_product_view.xml

This is what I added

<referenceBlock name="product.info.details">
            <referenceBlock name="product.info.description">
                <arguments>
                    <argument name="sort_order" xsi:type="string">10</argument>
                </arguments>
            </referenceBlock>
            <referenceBlock name="product.attributes">
                <arguments>
                    <argument name="sort_order" xsi:type="string">20</argument>
                </arguments>
            </referenceBlock>    
        </referenceBlock>

Then, below my added tab I added

<argument name="sort_order" xsi:type="string">50</argument>

So the whole file looks like

<?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> <referenceBlock name="product.info.details"> <referenceBlock name="product.info.description"> <arguments> <argument name="sort_order" xsi:type="string">10</argument> </arguments> </referenceBlock> <referenceBlock name="product.attributes"> <arguments> <argument name="sort_order" xsi:type="string">20</argument> </arguments> </referenceBlock>
</referenceBlock> <referenceBlock name="product.info.details"> <block class="Magento\Catalog\Block\Product\View" name="custom.tab" template="HBC_size::product/view/details/custom_tab.phtml" group="detailed_info"> <arguments> <argument translate="true" name="title" xsi:type="string">Size Chart</argument> <argument name="sort_order" xsi:type="string">50</argument> </arguments> </block> </referenceBlock> </body> </page>

2
  • Do you have an example of what your trying to achieve as if its what im thinking iv just done something on a similar basis for another site Dec 19, 2017 at 22:56
  • @DavaGordon I've added a few pictures and a little more description. I hope it makes it a little easier to understand.
    – dawhoo
    Dec 19, 2017 at 23:38

3 Answers 3

4
+50

You can try code, same as below:

  1. app/code/[VendorName]/[ModuleName]/registration.php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    '[VendorName]_[ModuleName]',
    __DIR__
);
  1. app/code/[VendorName]/[ModuleName]/etc/module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="[VendorName]_[ModuleName]" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Review"/>
        </sequence>
    </module>
</config>
  1. app/code/[VendorName]/[ModuleName]/view/frontend/layout/catalog_product_view.xml
<?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>
        <referenceBlock name="product.info.details">
            <block class="Magento\Catalog\Block\Product\View" name="custom.tab" template="[VendorName]_[ModuleName]::product/view/details/custom_tab.phtml" group="detailed_info">
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Tab Title</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>
  1. app/code/[VendorName]/[ModuleName]/view/frontend/templates/product/view/details/custom_tab.phtml
<?php $attributeCode = '<your_custom_attribute_name>'; ?>
<?php $blockIdentifier = $block->getProduct()->getData($attributeCode); ?>
<?php if($blockIdentifier): ?>
    <?php echo $block->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId($blockIdentifier)->toHtml(); ?>
<?php endif; ?>

Note:

1. Create new product attribute.
Admin Menu > Stores > Attributes > Product > Add New Attribute [Text Field] = (i.e. Size chart)
2. Assign attribute to attribute set.
3. Update Code
From:
<?php $attributeCode = '<your_custom_attribute_name>'; ?>
To:
<?php $attributeCode = 'sizechart'; ?>
4. In admin product add text to "sizechart" attribute
Catalog > Products > Edit > Size chart = (i.e. levi-size)
5. Create CMS Block
Admin Menu > Content > Elements > Blocks > Add New Block = Same identifier which you have added value in product's "Size chart" attribute textbox (i.e. levi-size)

For dropdown or multiselect attribute, you need to change code accordingly or add multiple conditions for the same.

4
  • 1
    This is working well. I added the custom name module for size, created another for warranty. In the catalog_product_view.xml I changed <block class="Magento\Catalog\Block\Product\View" name="custom2.tab" template="[VendorName]_[ModuleName]::product/view/details/custom_tab.phtml" group="detailed_info"> so it would display both of the new tabs. Adding the tabs with CMS content is exactly as expected. The only unexpected result - the tabs display before the reviews - is there an easy way to move the new tabs to the last displayed?
    – dawhoo
    Dec 21, 2017 at 20:13
  • Hi dawhoo, I've updated module.xml file (Step-2). Try updated code in your module to move the new tabs to the last.
    – Pratik Oza
    Dec 22, 2017 at 16:42
  • 1
    I haven't tested new and was really sick a few days, but I'm marking yours as the answer as it already works well and position Im sure will too.
    – dawhoo
    Dec 24, 2017 at 23:42
  • @dawhoo - Happy to help. Keep helping :)
    – Pratik Oza
    Dec 26, 2017 at 9:08
2

I have done this a few times from within a theme. You can just take the attribute e.g. warrantytype and then use the value for that to call the appropriate static block. Similar to below:

<?php
  $_product = $block->getProduct();
  $blockid = $_product->getResource()->getAttribute('warrantytype')->getFrontend()->getValue($_product);
  $blockhtml = $block->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId($shippingtype)->toHtml();
?>
<p><?php echo $blockhtml; ?></p>

This could be modified to show a custom widget like suggested by echoing the block_id into the widget also may be worth looking at getting a widget to show in phtml file however. Also code to grad the attribute value may need to be modified for drop downs but have not tested this.

app/design/frontend/vendor/Theme/Magento_Catalog/templates/product/view/warrantyinfo.phtml

Then simply add this block to a tab:

 <block class="Magento\Catalog\Block\Product\View" name="product.warranty" as="additional" template="product/view/warantyinfo.phtml" group="detailed_info">
      <arguments>
         <argument translate="true" name="title" xsi:type="string">Warranty</argument>
      </arguments>
   </block>

app/design/frontend/vendor/Theme/Magento_Catalog/layout/catalog_product_view.xml

1

Do the all above step:

For changing the Tabs Position:

Copy vendor/magento/module-catalog/view/frontend/templates/product/view/details.phtml in your theme /app/design/frontend/Namespace/Themename/Magento_Catalog/templates/product/view/details.phtml

Then replace code by following code:

<?php if ($detailedInfoGroup = $block->getGroupChildNames('detailed_info', 'getChildHtml')): ?>
    <?php $newOrderTabbing = array('product.info.description', 'product.attributes', 'reviews.tab', 'product.warranty'); //Add tab position
    <div class="product info detailed">
        <?php $layout = $block->getLayout(); ?>
        <div class="product data items" data-mage-init='{"tabs":{"openedState":"active"}}'>
            <?php foreach ($newOrderTabbing as $name): ?>
                <?php
                $html = $layout->renderElement($name);
                if (!trim($html)) {
                    continue;
                }
                $alias = $layout->getElementAlias($name);
                $label = $block->getChildData($alias, 'title');
                ?>
                <div class="data item title"
                     aria-labeledby="tab-label-<?php /* @escapeNotVerified */ echo $alias; ?>-title"
                     data-role="collapsible" id="tab-label-<?php /* @escapeNotVerified */ echo $alias; ?>">
                    <a class="data switch"
                       tabindex="-1"
                       data-toggle="switch"
                       href="#<?php /* @escapeNotVerified */ echo $alias; ?>"
                       id="tab-label-<?php /* @escapeNotVerified */ echo $alias; ?>-title">
                           <?php /* @escapeNotVerified */ echo $label; ?>
                    </a>
                </div>
                <div class="data item content" id="<?php /* @escapeNotVerified */ echo $alias; ?>" data-role="content">
                    <?php /* @escapeNotVerified */ echo $html; ?>
                </div>
            <?php endforeach; ?>
        </div>
    </div>
<?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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