3

I am adding an alternate reviews tab to the product detail page, and I have the tab appearing, but it always renders as the first tab in the list, the leftmost. I'd like it to be at the end, after (or in place of) the standard Reviews tab.

<referenceBlock name="product.info.details">
    <block class="My\Module\Block\Reviews" name="my.reviews.tab" as="my_reviews" template="My_Module::reviews.phtml" group="detailed_info">
        <arguments>
            <argument translate="true" name="title" xsi:type="string">Reviews</argument>
        </arguments>
    </block>
</referenceBlock>

I've dug around in the mage-catalog and mage-reviews code, but I can't find an argument I can pass to change this.

  • Did you find an answer to this? I have the same problem but mine is appearing as the last tab and I want it as the first. – Alex May 5 '16 at 12:50
  • Unfortunately not, when we made a new copy of the site and ran the compile the problem solved itself. – Dennis Rogers May 11 '16 at 16:28
6

You can just change inside details.phtml template file and set as per your requirement tabbing order,

set details.phtml file inside your theme folder,

app/design/frontend/Packagename/themename/Magento_Catalog/templates/product/view/details.phtml

Code for details.phtml file,

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

// @codingStandardsIgnoreFile

?>
<?php if ($detailedInfoGroup = $block->getGroupChildNames('detailed_info', 'getChildHtml')):?>
    <?php $newOrderTabbing = array('product.info.description','reviews.tab','product.attributes'); //custom add ?>
    <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; ?>

After adding above code now review tab display after details tab. Finally Tab orders are display like Details, Review, More Information.

You can change order by setting in

<?php $newOrderTabbing = array('product.info.description','reviews.tab','product.attributes'); //custom add ?> array in above file.

Thanks.

4

You can try modify the module loading order at /etc/module.xml

<sequence>
    <module name="Magento_Catalog" />
</sequence>
  • No luck with that change, I compared the module.xml with that of module-review in mage2 core, to no avail. However, the position did change when we cloned the site and compiled it, so now I'm even more confused. – Dennis Rogers Mar 3 '16 at 17:44
  • This answer is half way there, the order of the tabs does depend on the order they are added. As a test I edited the sequence of Magento_Review and added my module and now the tab created in my module is the first tab which is what I wanted. This is a horrible way of doing it so am still looking for a better way – Alex May 5 '16 at 16:05
3

Magento's own arguments with the before and after statements don't work for the tabs, also does the move statement not work. Therefore you have to adjust the details.phtml file plus your themes layout XML file.

Here's a little tutorial how I achieved this feature.

I passed an argument for each tab via XML File in my themes XML file

...
<arguments>
    <argument name="priority" xsi:type="string">REPLACE WITH SOME NUMBER</argument>
</arguments>
...

So my themes XML file looks something like this:

<referenceBlock name="product.info.details">
        <referenceBlock name="product.info.description">
            <arguments>
                <argument name="priority" xsi:type="string">1</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="product.attributes">
            <arguments>
                <argument name="priority" xsi:type="string">3</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="reviews.tab">
            <arguments>
                <argument name="priority" xsi:type="string">4</argument>
            </arguments>
        </referenceBlock>
        <!-- MY OWN CUSTOM BLOCK ON THE SECOND POSITION -->
        <block class="Magento\Catalog\Block\Product\View\Description" name="product.features" as="features" template="product/view/features.phtml" group="detailed_info">
            <arguments>
                <argument translate="true" name="title" xsi:type="string">Features</argument>
                <argument name="priority" xsi:type="string">2</argument>
            </arguments>
        </block>
        <!-- MY OWN CUSTOM BLOCK ENDS HERE -->
    </referenceBlock>

Further more we have to adjust the details.phtml, so copy it from

<magento_root>/vendor/magento-catalog-view/frontend/templates/product/view/details.phtml

to

<magento_root>/app/design/frontend/<Vendor>/<theme>/Magento_Catalog/templates/product/view/details.phtml

Please keep in mind that Magento's own details.phtml could be changed in future Magento versions or patches. These changes should be also applied to your theme's details.phtml

We now need to get the priority which we passed on via the XML file.

<?php
/**
 * Copyright © 2016 Magento. 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(); ?>
        <?php
            # We create a new array;
            $newPriority = array();
            # forEach the original $detailedInfoGroup Array;
            foreach ($detailedInfoGroup as $name){
                $alias = $layout->getElementAlias($name);
                # Get the priority which we applied via xml file
                # If no priority is applied via xml file then just set it to 10
                $priority = $block->getChildData($alias,'priority') ? $block->getChildData($alias,'priority') : '10';
                # variables pushed into new two-dimensional array
                array_push($newPriority, array($name, $priority));
            }
            # Sort array by priority
            usort($newPriority, function($a, $b) {
                return $a['1'] <=> $b['1'];
            });
        ?>
        <div class="product data items" data-mage-init='{"tabs":{"openedState":"active"}}'>
            <?php
            # Delete the original forEach statement
            #foreach ($detailedInfoGroup as $name)
            foreach ($newPriority as $name):?>
                <?php
                    # rename $name[0] to $name because it's a two-dimensional array
                    # No further changes to this file, it works as explained
                    $name = $name[0];
                    $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; ?>

So you see: You just have to add a few lines and can always change the priority/order of the tabs via the xml file, you don't have to change the details.phtml in future anymore.

2

I found the solution: add this code before your block

<referenceBlock name="product.info.description">
    <block class="Magento\Framework\View\Element\Template" name="details.t1"/>
</referenceBlock>
<referenceBlock name="product.attributes">
    <block class="Magento\Framework\View\Element\Template" name="details.t2"/>
</referenceBlock>
<referenceBlock name="reviews.tab">
    <block class="Magento\Framework\View\Element\Template" name="details.t3"/>
</referenceBlock>

The blocks inside is empty. I think magento update positions of blocks after some change.

0

What worked for me was simply moving each tab in the order I wanted.

<move element="product.info.description" destination="product.info.details" />
<move element="reviews.tab" destination="product.info.details" /> 
<move element="product.custom.tab" destination="product.info.details" />

Hope this helps!

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.