Magento2: Changer l'ordre des onglets sur la page produit

16

J'essaie de changer l'ordre des onglets sur la page du produit dans Magento 2. La valeur par défaut est Details|More Information|Reviews.

J'ai essayé:

Fournisseur / thème / Magento_Catalog / layout / catalog_product_view.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <move element="product.info.description" destination="product.info.details" after="-" />
    </body>
</page>

Mais cela ne fonctionne pas, et c'est la façon recommandée pour déplacer des éléments. J'ai pu déplacer les onglets hors de la zone d'onglet et dans d'autres zones, ainsi que d'ajouter de nouveaux onglets, mais je ne peux pas contrôler l'ordre des onglets.

Je suppose que cela a quelque chose à voir avec group="detailed_info"; Il semble que Magento saisit les éléments de mise en page avec cet attribut dans le XML et les parcourt pour créer les onglets.

Existe-t-il un moyen de modifier l'ordre des onglets sans réécrire le module?

andyjv
la source
Avez-vous trouvé une réponse à cela? J'ai le même problème.
Alex
Je n'ai pas encore de réponse, désolé.
andyjv
J'ai essayé d'utiliser l'élément de déplacement et suis arrivé à la même conclusion que vous, ils peuvent être déplacés en dehors des onglets mais pas ordonnés à l'intérieur.
Ben Crook
Cela peut être fait par mise en page uniquement avec une petite astuce. Montré ici: magento.stackexchange.com/questions/106412/…
skymeissner
@andyjv veuillez trouver la solution ici, cela pourrait vous aider à atteindre la sortie désirée. magento.stackexchange.com/a/242709/52244
Kanhaiya lal

Réponses:

22

Mon approche est un peu différente mais probablement plus à l'épreuve du temps, en cas d'ajout de nouveaux onglets plus tard et de changement de priorité / ordre de ces onglets.

J'ai passé un argument pour chaque onglet via un fichier XML dans mon fichier XML de thèmes

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

Donc, mon fichier XML de thèmes ressemble à ceci:

<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>

De plus, nous devons ajuster le details.phtml, alors copiez-le depuis

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

à

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

Veuillez garder à l'esprit que le propre de magento details.phtmlpourrait être modifié dans les futures versions ou correctifs de Magento. Ces modifications doivent également être appliquées à votre thèmedetails.phtml

Nous devons maintenant obtenir la priorité que nous avons transmise via le fichier XML.

<?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; ?>

Vous voyez donc: il vous suffit d'ajouter quelques lignes et vous pouvez toujours changer la priorité / l'ordre des onglets via le fichier xml, vous n'avez plus besoin de changer details.phtmlà l'avenir.

juhanix
la source
Comment afficher le contenu de l'onglet "Détail" au bas de l'onglet "Plus d'infos" s'il vous plaît?
Jai
votre question ne fait pas référence à la question d'origine. vous devez ouvrir un nouveau ticket. Quoi qu'il en soit: vous pouvez faire référence à un nouveau fichier phtml dans le catalogue_product_view.xml de votre thème (par exemple, description-attributes-combine.phtml) et coller le contenu à partir descrption.phtml et attributes.phtml originaux.
juhanix
J'ai collé le contenu des deux fichiers en un seul et appelé les fichiers xml comme: <referenceBlock name = "product.info.details"> <block class = "Magento \ Catalog \ Block \ Product \ View \ Description" name = "product.info .description.attributes "template =" produit / vue / description-attributs-combiné.phtml "group =" information_détaillée "> <arguments> <argument translate =" true "name =" title "xsi: type =" string "> Plus Informations </argument> </arguments> </block> </referenceBlock> Mais un site vierge et n'affiche que le contenu des onglets. Qu'est-ce qui manque?
Jai
J'ai ajouté une question ici: magento.stackexchange.com/q/157376/29175
Jai
@juhanix Cela vous oblige à extraire un modèle qui pourrait être modifié dans les correctifs Magento ultérieurs. Voir ma réponse qui ne modifie aucun fichier core. J'espère que c'est un problème central qui peut être corrigé.
LordZardeck
14

Pour changer la position de tabulation dans la page de détails, l'utilisation d'un fichier de configuration XML après ou avant l' attribut n'aide pas dans ce cas.

Vous devez changer de fichier modèle.

Copiez le fichier details.phtml du cœur vers votre thème,

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

Dans ce fichier, vous pouvez récupérer le nom de tous les onglets en utilisant, print_r ($ detailedInfoGroup), vous devez obtenir une valeur comme,

Array
(
    [0] => product.info.description
    [1] => product.attributes
    [2] => reviews.tab
)

Vous devez définir en fonction de vos besoins dans un nouveau tableau avant de foreach dans le fichier,

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

ajouter <?php foreach ($newOrderTab as $name):?>,

Le code complet dans details.phtml est comme ci-dessous,

<?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 added 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): //custom arrayname?>
                <?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; ?>
Rakesh Jesadiya
la source
Merci Rakesh Jesadiya, ça marche comme un charme ...!
Sarfaraj Sipai
13

Dans Magento 2.3.1 ou supérieur, nous pouvons utiliser l' sort_orderargument dans la app/design/frontend/Packagename/themename/Magento_Catalog/layout/catalog_product_view.xmlconfiguration " " xml

<referenceBlock name="product.info.description">
    <arguments>
        <argument name="title" translate="true" xsi:type="string">Description</argument>
        <argument name="sort_order" xsi:type="string">20</argument>
    </arguments>
</referenceBlock>

Assurez-vous également de mettre à jour la méthode " getGroupChildNames" avec " getGroupSortedChildNames" dans le fichier modèle ( si vous la remplacez ) " app/design/frontend/Packagename/themename/Magento_Catalog/templates/product/view/details.phtml".

Ancienne méthode

<?php if ($detailedInfoGroup = $block->getGroupChildNames('detailed_info', 'getChildHtml')):?>

Méthode mise à jour

<?php if ($detailedInfoGroup = $block->getGroupSortedChildNames('detailed_info', 'getChildHtml')):?>

Si vous remplacez la Magento\Catalog\Block\Product\View\Details.phpclasse de bloc, votre classe de bloc doit également avoir cette méthode mise à jour " getGroupSortedChildNames".

Nadeem0035
la source
1
C'est définitivement la bonne réponse à partir de 2.3.1.
Geat
Cela fonctionne pour moi sur 2.3.2, merci beaucoup!
Jared Chu
3

Une autre façon d'utiliser l'argument de l'ordre de tri.

Chemin du fichier - app\design\frontend\<companyNAme>\<ThemeName>\Magento_Catalog\layout\catalog_product_view.xml

Ajoutez l'argument d'ordre de tri dans le conteneur du bloc de référence product.info.details.

Exemple de code

<block class="Magento\Catalog\Block\Product\View" name="shipping_tab" template="Magento_Catalog::product/view/shipping.phtml" group="detailed_info" >
    <arguments>
    <argument translate="true" name="title" xsi:type="string">Shipping</argument>
    <argument name="sort_order" xsi:type="string">10</argument>
    </arguments>
</block>

Modifiez la valeur de l'argument d'ordre de tri à 10, 20, 30 selon votre commande.

Rathna
la source
1
une réponse parfaite avec un exemple sort_orderétait importante pour moi, +1 a fait ma journée :)
SagarPPanchal
2

Je sais qu'il y a eu d'autres réponses à cette question, mais toutes étaient trop envahissantes à mon goût. En examinant le problème, Magento ajoute un attribut "groupe" distinct à un élément et ajoute des enfants à cet attribut dans l'ordre chargé dans la présentation, complètement séparé du tableau d'enfants qui contient le tableau d'éléments triés. Afin de résoudre ce problème, j'ai écrit un plugin simple around qui corrige le tri lors de la récupération des enfants du groupe:

class Structure
{
    /**
     * Re-orders the array of group children based on the sort order defined on the parent's children
     *
     * @param \Magento\Framework\Data\Structure $subject
     * @param callable $proceed
     * @param $parentId
     * @param $groupName
     * @return array
     */
    function aroundGetGroupChildNames( \Magento\Framework\Data\Structure $subject, callable $proceed, $parentId, $groupName )
    {
        $sortedList = [];

        // Go ahead and get all the children
        $groupChildNames = $proceed( $parentId, $groupName );

        // If there was no group children, just leave early
        if (empty( $groupChildNames ))
        {
            return $groupChildNames;
        }

        // Go through the order of the parent's children and if it's in the list of group children aggregated above,
        // add it to our own list
        foreach ($subject->getElement( $parentId )['children'] as $childId => $childAlias)
        {
            if (!in_array( $childId, $groupChildNames ))
            {
                continue;
            }

            array_push( $sortedList, $childId );
        }

        return $sortedList;
    }
}

Cela vous permettra désormais de commander les onglets en utilisant le standard beforeet les afterattributs dans la mise en page XML comme vous vous y attendez, et n'aura probablement pas besoin d'être modifié sur les futurs correctifs Magento.

LordZardeck
la source
Le puissant et honorable LordZardeck a donné la bonne réponse. Ajouter autant de logique à un modèle, comme le font la plupart des réponses ci-dessus, pose simplement des problèmes lors de la mise à jour vers des versions plus récentes de magento.
Nathan Toombs du
2

Je pense que vous avez juste besoin de les ajouter dans l'ordre de votre choix. Pour moi, j'utilise 4 onglets dans cet ordre:

  1. Détails
  2. Étiquettes de produit
  3. Onglet personnalisé 1
  4. Onglet personnalisé 2

Dans mon module personnalisé, j'ai créé ce fichier de mise en page: catalog_product_view.xml avec ce contenu:

<?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="tab.tags" template="Godogi_Utilities::catalog/product/tab_tags.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Product Tags</argument>
                </arguments>
            </block>
            <block class="Magento\Catalog\Block\Product\View" name="tab.custom.tab.one" template="Godogi_Utilities::catalog/product/custom_tab_1.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Custom Tab 1</argument>
                </arguments>
            </block>
            <block class="Magento\Catalog\Block\Product\View" name="tab.custom.tab.n" template="Godogi_Utilities::catalog/product/custom_tab_n.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Custom Tab N</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

Vous pouvez voir que je n'ai ajouté que 3 onglets car l'onglet Détails existe déjà. En conséquence, j'ai les onglets dans cet ordre:

  1. Étiquettes de produit
  2. Onglet personnalisé 1
  3. Onglet personnalisé 2
  4. Détails

Ce qui n'est pas ce que je voulais, maintenant ma solution est d'ajouter à nouveau également l'onglet Détails, donc mon fichier de mise en page serait comme ceci:

<?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\Description" name="product.info.description" template="product/view/attribute.phtml" group="detailed_info">
                <arguments>
                    <argument name="at_call" xsi:type="string">getDescription</argument>
                    <argument name="at_code" xsi:type="string">description</argument>
                    <argument name="css_class" xsi:type="string">description</argument>
                    <argument name="at_label" xsi:type="string">none</argument>
                    <argument name="title" translate="true" xsi:type="string">Details</argument>
                </arguments>
            </block>
            <block class="Magento\Catalog\Block\Product\View" name="tab.tags" template="Godogi_Utilities::catalog/product/tab_tags.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Product Tags</argument>
                </arguments>
            </block>
            <block class="Magento\Catalog\Block\Product\View" name="tab.custom.tab.one" template="Godogi_Utilities::catalog/product/custom_tab_1.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Custom Tab 1</argument>
                </arguments>
            </block>
            <block class="Magento\Catalog\Block\Product\View" name="tab.custom.tab.n" template="Godogi_Utilities::catalog/product/custom_tab_n.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Custom Tab N</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

Maintenant, j'ai la commande que je veux :) entrez la description de l'image ici

Abdelkebir ELHARFALI
la source
1

Le moyen le plus simple et le meilleur est à mon avis la solution de LordZardeck avec un plugin. Après la mise à jour du fournisseur / module / etc / frontend / di.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    ...

        <type name="Magento\Framework\Data\Structure">
            <plugin name="vendor_sort_tabs" type="Vendor\Module\Plugins\Structure" sortOrder="0"/>
        </type>

   ...

    </config>

tout a fonctionné comme souhaité.

Merci @LordZardeck pour le code propre!

GeorgeGos
la source
0

Voici la solution que j'ai utilisée. Il permutera l'onglet description et attributs s'ils sont tous les deux disponibles. Ceci utilise le thème Ultimo. Mais vous aurez compris. BAISER.

<?php 
$detailedInfoGroup = $block->getGroupChildNames('detailed_info', 'getChildHtml');

if ($detailedInfoGroup[0] == 'product.info.description' && $detailedInfoGroup[1] == 'product.attributes') {
    $detailedInfoGroup[0] = 'product.attributes';
    $detailedInfoGroup[1] = 'product.info.description';
}

// rest of the code to look through $detailedInfoGroup
?>
craigtadlock
la source
0

Ma solution au problème consiste à modifier le modèle details.phtml afin qu'il récupère les blocs enfants de la mise en page.

$blocks = $layout->getChildBlocks($block->getNameInLayout());

En procédant ainsi, il respecte l'ordre donné par les modificateurs après et avant .

<?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(); ?>
        <?php $blocks = $layout->getChildBlocks($block->getNameInLayout());?>
        <div class="product data items" data-mage-init='{"tabs":{"openedState":"active"}}'>
            <?php foreach($blocks as $alias=>$child_block):?>
                <?php if(in_array($child_block->getNameInLayout(),$detailedInfoGroup)):?>
                    <?php
                        $html = $child_block->toHtml();
                        if (!trim($html)) {
                            continue;
                        }       
                        $label = $child_block->getData('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 endif; ?>
            <?php endforeach;?>
        </div>
    </div>
<?php endif; ?>

J'utilise toujours le tableau fourni par getGroupChildNames afin de valider si le bloc appartient au groupe.

if(in_array($child_block->getNameInLayout(),$detailedInfoGroup))

Antonio Alonso
la source
0

Je ne voulais pas travailler sur le thème, je voulais modifier le comportement de la méthode 'getGroupChildNames'. Cette approche devrait fonctionner même si le modèle est modifié.

J'ai ajouté ceci à catalog_product_view.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
  xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <!-- CODE TO REORDER PRODUCT TABS -->
    <block class="Dsy\Ton\Block\Product\View\Description" name="product.info.details.new" template="Magento_Catalog::product/view/details.phtml">
        <!-- ADD MORE BOCKS IF NEEDED -->
    </block>
    <move element="product.info.details.new" destination="content" after="product.info.details"/> 

    <move element="product.info.description" destination="product.info.details.new" after="-"/>
    <move element="product.attributes" destination="product.info.details.new" after="-"/> 

    <referenceBlock name="product.info.details" remove="true"/>
    <!-- CODE TO REORDER PRODUCT TABS -->
  </body>

Ensuite, créez un bloc pour modifier le comportement de «getGroupChildNames»:

<?php

namespace My\Module\Block\Product\View;

use Magento\Catalog\Model\Product;

class Description extends \Magento\Catalog\Block\Product\View\Description
{
    public function getGroupChildNames($groupName)
    {
        if ('detailed_info' === $groupName) {
            return [
                // here you can change the order
                'product.attributes',
                'product.info.description',
            ];
        }

        return parent::getGroupChildNames($groupName);
    }
}

C'est tout.

amcastror
la source
0

LordZardeck a la meilleure réponse, mais il s'agit essentiellement d'un bug et devrait être corrigé dans le noyau.

La solution la plus simple au problème que j'ai trouvé est la suivante: Remplacez le modèle Magento_Catalog :: product / view / details.phtml et après la première condition php à la ligne 10:

if ($detailedInfoGroup = $block->getGroupChildNames(...

ajoutez le code suivant pour modifier la commande:

$_prepend = array_reverse(['product.overview.description']);
foreach ($_prepend as $_name) {
    $k = array_search($_name,$detailedInfoGroup);
    if ( $k !== false) {
        unset($detailedInfoGroup[$k]);
        array_unshift($detailedInfoGroup,$_name);
    }
}

cela va changer l'ordre et pousser tous les onglets répertoriés dans $ _prepend au début du tableau dans l'ordre défini.

siux
la source
0

Il semble que tout ce qui précède n'est plus pertinent. Depuis Magento 2.3.1, nous pouvons utiliser l' sort_orderargument dans la configuration xml.

Krzysztof Wołowski
la source
0

Un plugin est une bonne solution. Mais vous pouvez toujours l'améliorer. Vous ne voulez pas écrire un plugin différent chaque fois que vous devez réorganiser les onglets. Ce que vous voulez faire, c'est définir l'ordre en xml. Comme ça:

<referenceBlock name="product.info.details">
        <referenceBlock name="product.info.description">
            <arguments>
                <argument name="priority" xsi:type="number">1</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="product.attributes">
            <arguments>
                <argument name="priority" xsi:type="number">3</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="reviews.tab">
            <arguments>
                <argument name="priority" xsi:type="number">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="number">2</argument>
            </arguments>
        </block>
        <!-- MY OWN CUSTOM BLOCK ENDS HERE -->
    </referenceBlock>

puis, au lieu de modifier le modèle, créez un plugin qui ferait comprendre à Magento l' priorityargument utilisé dans la configuration xml:

class TabOrder
{
    const TABS_BLOCK_NAME = 'product.info.details';
    const ORDER_ARGUMENT_NAME = 'priority';

    public function afterGetGroupChildNames(
        \Magento\Catalog\Block\Product\View\Description $subject,
        array $result
    ) {
        if ($subject->getNameInLayout() === self::TABS_BLOCK_NAME) {
            foreach ($result as $blockName) {
                // get priority for each block and include it in modifiedResult
                $alias = $subject->getLayout()->getElementAlias($blockName);

                // 100 default value guarantees the tab without priority argument goes last
                $blockPosition =
                    $subject->getChildData($alias, self::ORDER_ARGUMENT_NAME) ?? 100;
                $modifiedResult[] = array(
                    $blockName,
                    $blockPosition);
            }

            // order elements from $modifiedResult by priority
            usort($modifiedResult, function ($a, $b) {
                return $a[1] <=> $b[1];
            });

            // remove priority and leave original values only
            array_walk($modifiedResult, function (&$value, $key) {
                $value = $value[0];
            });

            return $modifiedResult;
        }

        return $result;
    }
}

Et enfin, le plugin doit être appliqué à la Magento\Catalog\Block\Product\View\Descriptionclasse dans le fichier di.xml.

Krzysztof Wołowski
la source
0

Pour Magento 2, changez l'ordre des onglets sur la page du produit.

Vous pouvez facilement personnaliser l'ordre des onglets de manière simple.

  1. Créez le fichier details.phtml dans

application / design / frontend / fournisseur / thème / Magento_Catalog / templates / produit / vue /

Si le fichier details.phtml existe déjà, mettez-le à jour.

  1. Ajoutez ce code avant chaque boucle. Définissez le tableau "$ detailedInfoGroup".

Code d'origine:

<?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; ?> 

Après avoir ajouté le code:

<?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 $detailedInfoGroup = ["product.info.description", "product.attributes", "reviews.tab"]; ?>
            <?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; ?>

Et ajouter un onglet personnalisé dans la page du produit vérifier ce lien

Magento 2 - Créer un onglet de produit qui affiche un attribut personnalisé

Sohel Khan
la source