Magento2: Cambiar el orden de las pestañas en la página del producto

16

Estoy tratando de cambiar el orden de las pestañas en la página del producto en Magento 2. El valor predeterminado es Details|More Information|Reviews.

Lo intenté:

Proveedor / tema / 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>

Pero eso no funciona, y esa es la forma recomendada para mover elementos. Pude mover las pestañas fuera del área de pestañas a otras áreas, así como agregar nuevas pestañas, pero no puedo controlar el orden de las pestañas.

Mi conjetura es que tiene algo que ver con group="detailed_info"; Parece que Magento toma los elementos de diseño con este atributo en el XML y lo recorre para crear las pestañas.

¿Hay alguna manera de cambiar el orden de las pestañas sin reescribir el módulo?

andyjv
fuente
¿Encontraste una respuesta a esto? Estoy teniendo el mismo problema.
Alex
Todavía no tengo respuesta, lo siento.
andyjv
Intenté usar el elemento move y llegué a la misma conclusión que tú, se pueden mover fuera de las pestañas pero no se pueden ordenar dentro de ellas.
Ben Crook
Se puede hacer por diseño solo con un pequeño truco. Se muestra aquí: magento.stackexchange.com/questions/106412/…
skymeissner
@andyjv, encuentre la solución aquí, esto podría ayudarlo a lograr el resultado deseado. magento.stackexchange.com/a/242709/52244
Kanhaiya lal

Respuestas:

22

Mi enfoque es un poco diferente, pero probablemente más a prueba de futuro, en caso de agregar nuevas pestañas más adelante y cambiar la prioridad / orden de estas pestañas.

Pasé un argumento para cada pestaña a través del archivo XML en mi archivo XML de temas

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

Entonces mi archivo XML de temas se ve así:

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

Además, tenemos que ajustar el details.phtml, así que cópielo de

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

a

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

Tenga en cuenta que el propio details.phtmlMagento podría cambiarse en futuras versiones o parches de Magento. Estos cambios también deberían aplicarse a los temas de su tema.details.phtml

Ahora necesitamos obtener la prioridad que transmitimos a través del archivo 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; ?>

Como puede ver: solo tiene que agregar algunas líneas y siempre puede cambiar la prioridad / orden de las pestañas a través del archivo xml, ya no tiene que cambiar el details.phtmlen el futuro.

juhanix
fuente
¿Cómo podemos mostrar el contenido de la pestaña "Detalle" en la parte inferior de la pestaña "Más información", por favor?
Jai
Su pregunta no se refiere a la pregunta original. Deberías abrir un nuevo boleto. De todos modos: puede hacer referencia a un nuevo archivo phtml en el catálogo catalog_product_view.xml de su tema (p. Ej., Description-atributos-combinado.phtml) y pegar el contenido del descrption.phtml original y atributos.phtml.
juhanix
Pegué el contenido de ambos archivos en uno y llamé a los archivos xml como: <referenceBlock name = "product.info.details"> <block class = "Magento \ Catalog \ Block \ Product \ View \ Descripción" name = "product.info .description.attributes "template =" producto / vista / descripción-atributos-combinado.phtml "grupo =" información_detallada "> <argumentos> <argumento traducir =" verdadero "nombre =" título "xsi: tipo =" cadena "> Más Información </argument> </arguments> </block> </referenceBlock> Pero el sitio en blanco y muestra solo el contenido de las pestañas. ¿Qué falta?
Jai
Agregué una pregunta aquí: magento.stackexchange.com/q/157376/29175
Jai
@juhanix Esto requiere que avance una plantilla que podría modificarse en parches posteriores de Magento. Vea mi respuesta que no modifica ningún archivo central. Con suerte, este es un problema central que puede ser parcheado.
LordZardeck
14

Para Cambiar la posición de la pestaña en la página de detalles, el uso del archivo de configuración XML después o antes del atributo no ayuda en este caso.

Tienes que cambiar del archivo de plantilla.

Copie el archivo details.phtml del núcleo a su tema,

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

Dentro de este archivo, puede buscar el nombre de todas las pestañas usando, print_r ($ updatedInfoGroup) tiene que obtener un valor como,

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

Debe establecer de acuerdo con sus requisitos en una nueva matriz antes de foreach en el archivo,

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

añadir <?php foreach ($newOrderTab as $name):?>,

El código completo en details.phtml es como a continuación,

<?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
fuente
Gracias Rakesh Jesadiya, ¡Funciona de maravilla ...!
Sarfaraj Sipai
13

En Magento 2.3.1 o superior podemos usar sort_orderargumentos en " app/design/frontend/Packagename/themename/Magento_Catalog/layout/catalog_product_view.xml" xml config

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

También asegúrese de actualizar el método " getGroupChildNames" con " getGroupSortedChildNames" en el archivo de plantilla ( si lo está anulando ) " app/design/frontend/Packagename/themename/Magento_Catalog/templates/product/view/details.phtml".

Método antiguo

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

Método actualizado

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

Si está anulando la Magento\Catalog\Block\Product\View\Details.phpclase de bloque, entonces su clase de bloque también debería tener ese método actualizado " getGroupSortedChildNames".

Nadeem0035
fuente
1
Esta es definitivamente la respuesta correcta desde 2.3.1 en adelante.
Geat
Funciona para mí en 2.3.2, ¡muchas gracias!
Jared Chu el
3

Otra forma de usar el argumento de orden de clasificación.

Ruta de archivo - app\design\frontend\<companyNAme>\<ThemeName>\Magento_Catalog\layout\catalog_product_view.xml

Agregue el argumento de orden de clasificación dentro del contenedor de bloques de referencia product.info.details.

Código de ejemplo

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

Cambie el valor del argumento de orden de clasificación a 10, 20, 30 según su orden.

Rathna
fuente
1
La respuesta perfecta con un ejemplo sort_orderfue importante para mí, +1 me
alegró el
2

Sé que ha habido otras respuestas a esta pregunta, pero todas fueron demasiado invasivas para mi gusto. Al analizar el problema, Magento agrega un atributo de "grupo" separado a un elemento y agrega elementos secundarios a ese atributo en el orden cargado en el diseño, completamente separado del conjunto de elementos secundarios que contiene el conjunto ordenado de elementos. Para solucionar esto, escribí un plugin simple que soluciona la clasificación al recuperar hijos del grupo:

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

Esto ahora le permitirá ordenar las pestañas usando el estándar beforey los afteratributos en el diseño XML como es de esperar, y probablemente no necesitará ser modificado en futuros parches de Magento.

Lord Zardeck
fuente
El poderoso y honorable Lord Zardeck ha dado la respuesta correcta. Agregar tanta lógica a una plantilla, como lo hacen la mayoría de las respuestas anteriores, es solo pedir problemas al actualizar a versiones más recientes de magento.
Nathan Toombs
2

Creo que solo necesita agregarlos en el orden que elija. Para mí, estoy usando 4 pestañas en este orden:

  1. Detalles
  2. Etiquetas de productos
  3. Pestaña personalizada 1
  4. Pestaña personalizada 2

En mi módulo personalizado creé este archivo de diseño: catalog_product_view.xml con este contenido:

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

Puede ver que he agregado solo 3 pestañas porque la pestaña de detalles ya existe. Como resultado, obtuve las pestañas en este orden:

  1. Etiquetas de productos
  2. Pestaña personalizada 1
  3. Pestaña personalizada 2
  4. Detalles

Lo cual no es lo que quería, ahora mi solución a esto es agregar también la pestaña Detalles nuevamente, para que mi archivo de diseño sea así:

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

Ahora tengo el pedido que quiero :) ingrese la descripción de la imagen aquí

Abdelkebir ELHARFALI
fuente
1

La mejor y más fácil es, en mi opinión, la solución de LordZardeck con un complemento. Después de actualizar el proveedor / módulo / 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>

Todo funcionó como se desea.

¡Gracias @LordZardeck por el código limpio!

GeorgeGos
fuente
0

Aquí está la solución que usé. Intercambiará la descripción y la pestaña de atributos si ambos están disponibles. Esto está usando el tema Ultimo. Pero entenderás el punto. BESO.

<?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
fuente
0

Mi solución al problema es modificar la plantilla details.phtml para que obtenga los bloques secundarios del diseño.

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

Al hacerlo de esta manera, respeta el orden dado por los modificadores after y before .

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

Todavía uso la matriz proporcionada por getGroupChildNames para validar si el bloque pertenece al grupo.

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

Antonio Alonso
fuente
0

No quería trabajar en el tema, quería modificar el comportamiento del método 'getGroupChildNames'. Este enfoque debería funcionar incluso si la plantilla se modifica.

Agregué esto a 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>

Luego, cree un bloque para cambiar el comportamiento 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);
    }
}

Eso es todo.

amcastror
fuente
0

LordZardeck tiene la mejor respuesta, pero esto es básicamente un error y debe solucionarse en el núcleo.

La solución más simple al problema que encontré es la siguiente: Anule la plantilla Magento_Catalog :: product / view / details.phtml y después de la primera condición de php en la línea 10:

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

agregue el siguiente código para modificar el orden:

$_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);
    }
}

esto cambiará el orden y empujará todas las pestañas enumeradas en $ _prepend al comienzo de la matriz en el orden definido.

siux
fuente
0

Parece que todo lo anterior ya no es relevante. A partir de Magento 2.3.1 podemos usar sort_orderargumentos en la configuración xml.

Krzysztof Wołowski
fuente
0

Un complemento es una buena solución. Pero aún puedes mejorarlo. No desea escribir un complemento diferente cada vez que necesite reordenar las pestañas. Lo que quieres hacer es establecer el orden en xml. Me gusta esto:

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

y luego, en lugar de modificar la plantilla, cree un complemento que haga que Magento entienda el priorityargumento utilizado en la configuración 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;
    }
}

Y finalmente, el complemento debe aplicarse a la Magento\Catalog\Block\Product\View\Descriptionclase en el archivo di.xml.

Krzysztof Wołowski
fuente
0

Para Magento 2, cambie el orden de las pestañas en la página del producto.

Puede personalizar fácilmente el orden de las pestañas de forma sencilla.

  1. Crear archivo details.phtml en

app / design / frontend / vendor / theme / Magento_Catalog / templates / product / view /

Si el archivo details.phtml ya existe, actualícelo.

  1. Agregue este código antes del bucle foreach. Defina la matriz "$ updatedInfoGroup".

Código original:

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

Después de agregar código:

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

Y agregue una pestaña personalizada en la página del producto, consulte este enlace

Magento 2: crea una pestaña de producto que muestra un atributo personalizado

Sohel Khan
fuente