1

In catalog_product_view.xml I have the following section:

<referenceBlock name="product.info.details">
  <block class="Magento\Framework\View\Element\Template" template="Magento_Catalog::product/tabs/tab1.phtml" name="extra-tab-1" group="detailed_info">
    <arguments>
      <argument name="title" translate="true" xsi:type="string">Extra Tab 1</argument>
    </arguments>
  </block>
  <block class="Magento\Framework\View\Element\Template" template="Magento_Catalog::product/tabs/tab2.phtml" name="extra-tab-2" group="detailed_info">
    <arguments>
      <argument name="title" translate="true" xsi:type="string">Extra Tab 2</argument>
    </arguments>
  </block>
</referenceBlock>

My issue is that only "Extra Tab 2" shows up on the product page. If I remove that block and clear caches, "Extra Tab 1" is then displayed.

I was hoping someone had experienced a similar issue and could point me towards a cause. There are no other custom modules or themes interfering with the product page layout.

  • Hello @Geat, I have tried your code and it is showing both tab.could you please share some more info ? – Pawan Apr 6 at 2:07
3

I just stumbled across the answer.

As of Magento 2.3.1, if the tab does not have a sort order set, it uses 0. Unfortunately, Magento uses that sort order as the array key, so if multiple tabs do not have a sort order set, they overwrite the same array element and only the last tab is left. This issue is not present in 2.3.0.

The solution is to simply ensure that each tab has a sort order set, e.g.:

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

Have you modified the details.phtml file? If not the only reason I've ever seen the tabs fail to render without any sort of syntax error is when there is no value returned by a tab. For instance if you use a custom attribute, like manufacturer_country in one of the tabs and $product->getManufacturerCountry() returns null or "".

Let's look at the file responsible for rendering the tabs vendor/magento/module-catalog/view/frontend/templates/product/view/details.phtml.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

?>
<?php if ($detailedInfoGroup = $block->getGroupChildNames('detailed_info', 'getChildHtml')):?>
    <div class="product info detailed">
        <?php $layout = $block->getLayout(); ?>
        <div class="product data items" data-mage-init='{"tabs":{"openedState":"active"}}'>
            <?php foreach ($detailedInfoGroup 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-<?= /* @escapeNotVerified */ $alias ?>-title"
                     data-role="collapsible" id="tab-label-<?= /* @escapeNotVerified */ $alias ?>">
                    <a class="data switch"
                       tabindex="-1"
                       data-toggle="switch"
                       href="#<?= /* @escapeNotVerified */ $alias ?>"
                       id="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title">
                        <?= /* @escapeNotVerified */ $label ?>
                    </a>
                </div>
                <div class="data item content" id="<?= /* @escapeNotVerified */ $alias ?>" data-role="content">
                    <?= /* @escapeNotVerified */ $html ?>
                </div>
            <?php endforeach;?>
        </div>
    </div>
<?php endif; ?>

These few lines below are what will decide if a tab is rendered or not:

$html = $layout->renderElement($name);
                    if (!trim($html)) {
                        continue;
                    }

So unless the value you're trying to return is empty or you've customized details.phtml then there is no reason for the tab not to be rendered.

  • As mentioned in the question, if I remove tab 2 then tab 1 is rendered, so it's an issue somnewhere outside of the tab rendering logic. For some reason, only one custom tab is ever rendered, it doesn't work if there's more than 1. – Geat Apr 8 at 15:30
  • @Geat have you modified anything outside of the xml you posted? – NSwanson7 Apr 8 at 15:52
  • I haven't, and I also have very similar code working in a couple of other projects. The only difference is this site was a straight 2.3 install, the others were upgraded from 2.2 to 2.3. No idea if that makes a difference. – Geat Apr 8 at 16:18
  • @Geat hmm, that's odd. I just checked the v2.3 version of details.phtml, and it doesn't look to be any different. Let's try to debug this via process of elimination. Set both the tags to use the same template file. Lets see if you're still experiencing the issue. – NSwanson7 Apr 8 at 16:25
  • 1
    @Geat Just read your answer. Gotta hate logical errors they're the hardest to debug. You get no error to go off of. Good job figuring it out. – NSwanson7 Apr 8 at 17:05

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.