Come aggiungere gli handle di layout personalizzati a livello di codice per la visualizzazione per categorie in Magento 2


9

Quindi, voglio aggiungere un handle di layout personalizzato per tutte le pagine della vista di categoria .. l'handle che dovrebbe essere caricato dipende da alcuni parametri di categoria, quindi l'handle deve essere aggiunto a livello di codice con $page->addPageLayoutHandles()

Sembra facile ..? Apparentemente no

Magento 2 fornisce un bel sistema di plugin che stavo per usare naturalmente, basta definire un afterExecute()plugin da eseguire dopo la categoria originale execute()e spingere qualsiasi aggiornamento nell'oggetto Page da lì.

Sfortunatamente non funziona così. La ragione è che il execute()metodo originale (alla fine) verrà eseguito $page->getConfig()->addBodyClass()- una chiamata a questo metodo costringerà automaticamente il layout a essere completamente caricato e generato, quindi eventuali tentativi successivi di aggiungere nuovi gli handle di layout della pagina sono completamente inutili. Mi sono guardato intorno per trovare modi non così eleganti per ottenere la stessa cosa (usando ancora plugin) .. non ho trovato nessuno.

Ho finito con il mio controller per la visualizzazione delle categorie, tuttavia non avrei preferito lasciarlo così.

Quindi la mia domanda è ... come posso aggiungere nuovi handle di layout di pagina (a livello di programmazione) per la visualizzazione delle categorie? e fallo elegantemente.


Quale versione di Magento stai usando? Perché dove puoi vedere che $page->getConfig()->addBodyClass()carica e genera il tuo layout? Al momento sto svolgendo un compito simile, solo con le pagine CMS.
Giel Berkers,

Sono così felice che tu l'abbia notato, mentre mi hai salvato un sacco di dolore. Cordiali saluti: il controller di visualizzazione della categoria chiama anche $ page-> getConfig () -> addBodyClass () che rende inutile un plugin per ottenere questo risultato.
Perry Holden,

Risposte:


17

Il modo XML

Bene, un modo semplice è quello di creare il seguente file nella cartella del modulo: view/frontend/layout/catalog_category_view.xmlcon il seguente contenuto:

<?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">
    <update handle="your_custom_handle"/>
</page>

Non è più o meno elegante del modo PHP e secondo quello che hai trovato è più sicuro.

Il modo PHP

Sfortunatamente nel tuo caso, sembra che PHP sia l'unico modo per ottenere dinamicamente creare handle basati sui parametri della categoria.

Tramite plugin

Invece di creare un plug-in sul execute()metodo della classe di azioni, è possibile creare direttamente un plug-in sul addPageLayoutHandles()metodo diMagento\Framework\View\Result\Page

Il problema principale è che verrà chiamato ogni volta che viene chiamato questo metodo e dovrai aggiungere alcune condizioni nel tuo codice plugin per assicurarti di essere in una pagina di visualizzazione della categoria.

Tramite le preferenze

Un altro modo per farlo sarebbe utilizzare le preferenze per la classe di azioni della vista categoria:

<?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\Catalog\Controller\Category\View"
                type="Vendor\Module\Controller\Category\View"/>
</config>

Quindi, nella tua classe di controller personalizzati, devi semplicemente ignorare il execute()metodo copiando / incollando il metodo originale e aggiungendo le modifiche direttamente in questo metodo.

Il problema principale è che quando aggiorni l'installazione di Magento, se vengono aggiunte modifiche alla classe di azioni Magento nativa originale, non si rifletterà nella tua classe di azioni personalizzata.


Il problema è ... deve essere programmaticamente aggiunto. Semplicemente perché l'handle che si sta caricando dipende dai parametri della categoria.
Kristjan H.

@KristjanH. hmmm vedo che è imbarazzante, fammi scavare più a fondo
Raffaello al Pianismo digitale

@KristjanH. vedi il mio aggiornamento
Raffaello al Pianismo digitale,

1
Usando <preference> .. cioè, quello che ho fatto poco prima di aver scritto la domanda qui, tuttavia, non ne sono soddisfatto. Lo stesso con l'utilizzo di un plug-in su addPageLayoutHandles, non voglio chiamare un plug-in tutto il tempo, anche se la penalità delle prestazioni è inesistente, non è giusto. Vediamo se ci sono altre soluzioni qui.
Kristjan H.

Hai provato in altro modo dopo questo?
LM_Fielding

8

Ho avuto un problema simile. per le categorie che non mostrano elenchi di prodotti avevo bisogno di un handle aggiuntivo. dopo aver omesso di aggiungere l'handle tramite l'XML di layout personalizzato della categoria, ho finito per aggiungerlo in un osservatore layout_load_beforeall'evento:

class LayoutLoadBefore implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @var \Magento\Framework\Registry
     */
    protected $_registry;

    public function __construct(
        \Magento\Framework\Registry $registry
    )
    {
        $this->_registry = $registry;
    }

    /**
     * add a custom handle to categories of page type 'PAGE'
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return $this
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $action = $observer->getData('full_action_name');
        if ($action != 'catalog_category_view')
            return $this;

        $category = $this->_registry->registry('current_category');
        if (!$category)
            return $this;

        if ($category->getDisplayMode() == $category::DM_PAGE) {
            $layout = $observer->getData('layout');
            $layout->getUpdate()->addHandle('catalog_category_view_cms');
        }

        return $this;
    }
}

c'è un piccolo impatto sulle prestazioni coinvolto quando l'osservatore viene chiamato per ogni visualizzazione di pagina. sfortunatamente, tutti gli eventi relativi a "category_view" sembrano troppo presto (categoria non ancora caricata) o troppo tardi (layout già elaborato).


Grazie! Ho avuto un problema simile ( magento.stackexchange.com/questions/156231/… ) e un plugin attivo\Magento\Cms\Controller\Page\View::execute() e \Magento\Framework\View\Result\Page::addPageLayoutHandles() or render()non ha funzionato. Questa soluzione di ultima istanza è stata l'unica soluzione che ha funzionato per me.
Giel Berkers,

1

Proviamo a osservare l'evento layout_load_before. La funzione di esecuzione sarà la stessa di questa:

public function execute(\Magento\Framework\Event\Observer $observer)
    {
        if($observer->getFullActionName() == 'catalog_category_view'){
            $observer->getLayout()->getUpdate()->addHandle('your_custom_handles');
        }
    }

Spero che questo possa aiutare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.