Magento 2

Personalizzare il menu di Magento 2

Lettura 3 minuti

La realizzazione del menu è uno dei task più importanti e delicati nello sviluppo di un tema.

Magento 2, come anche Magento 1, non genera il markup del menu all’interno di un template, dunque il modo migliore per modificare strutturalmente il menu è estendere la classe \Magento\Theme\Block\Html\Topmenu che genera il markup dell’albero delle categorie. Vediamo nel dettaglio come fare.

Innanzitutto dobbiamo realizzare un modulo per Magento 2 (Vedi come realizzare un modulo per Magento2).

Creiamo il nostro file registration.php

 

use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE,
    'Bitbull_CustomMenu',
    __DIR__
);

Poi dichiariamo il modulo e la dipendenza dello stesso da _MagentoTheme. Quindi in etc/module.xml scriviamo:

 

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Bitbull_CustomMenu" setup_version="2.0.0">
        <sequence>
            <module name="Magento_Theme"/>
        </sequence>
    </module>
</config>

 

Successivamente andremo a configurare la Dependency Injection in etc/di.xml. Questo è solo uno dei modi con cui si può ottenere questo risultato in Magento2 (Per un approfondimento sul tema rimandiamo a un successivo articolo più specifico su questo blog).

 

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

    <preference for="Magento\Theme\Block\Html\Topmenu" type="Bitbull\CufficioMenu\Block\CustomMenu" />
</config>

 

Adesso abbiamo dichiarato una dipendenza dalla classe \Magento\Theme\Block\Html\Topmenu all’interno del nostro modulo e possiamo andare ad estenderla per riscrivere il metodo _addSubMenu( … ) che genera il markup del menu e l’albero delle categorie.

 

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Bitbull\CustomMenu\Block;


class CustomMenu extends \Magento\Theme\Block\Html\Topmenu {

    /**
     * @param \Magento\Framework\Data\Tree\Node $child
     * @param string $childLevel
     * @param string $childrenWrapClass
     * @param int $limit
     * @return string
     */

    protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
    {
        $html = '';
        if (!$child->hasChildren()) {
            return $html;
        }

        $colStops = null;
        if ($childLevel == 0 && $limit) {
            $colStops = $this->_columnBrake($child->getChildren(), $limit);
        }

        $html .= '<ul class="level' . $childLevel . ' submenu">';
        $html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
        $html .= '</ul>';

        if ($childLevel == 0) {
            $staticBlock = trim($this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId($child->getId())->toHtml());
            if(!empty($staticBlock)){
                $html .= '<div class="menu-static-block">'.$staticBlock.'<div>';
            }
        }

        return $html;
    }

    /**
     * @return string
     */

    protected function _toHtml()
    {
        $this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Topmenu'));
        return parent::_toHtml();
    }

}

 

In questo esempio è stato semplicemente aggiunto un blocco statico all’interno del sottomenu che ha come id l’id della categoria di primo livello corrispondente. E’ chiaro che lo stesso principio può essere usato per fare delle operazioni più complesse o per modificare radicalmente la struttura del menu.

 

jQuery menu widget

Per quanto riguarda la parte js Magento 2 estende il menu widget di jQuery Ui per renderlo responsive. Rispetto al menu di default di Magento 1 è già un grosso passo avanti ma la maggior parte dei progetti ha esigenze di navigazione specifiche che richiedono del javascript ad hoc.

Il widget viene inizializzato sul tag ul del menu principale, all’interno del template module-theme/view/frontend/templates/html/topmenu.phtml

 

data-mage-init='{"menu":{"responsive":true, "expanded":true, "position":{"my":"left top","at":"left bottom"}}}'

Per sostituirlo con un componente custom dovremo creare un file di configurazione di RequireJs requirejs-config.js all’interno del nostro tema o modulo specificando il nome del componente custom da sostituire a quello di default di Magento 2.

 

var config = {
  "map": {
    "*": {
      "menu": "js/CustomMenu",
    }
  }
};

Approfondimenti

Articolo scritto da