Bagaimana cara menambahkan tata letak kustom menangani pemrograman untuk Tampilan Kategori di Magento 2

9

Jadi, saya ingin menambahkan pegangan tata letak khusus untuk semua halaman tampilan kategori .. pegangan yang seharusnya dimuat tergantung pada parameter kategori tertentu, sehingga pegangan perlu ditambahkan secara programatik dengan $page->addPageLayoutHandles()

Tampak mudah ..? Sepertinya tidak

Magento 2 menyediakan sistem Plugin yang bagus yang secara alami akan saya gunakan, cukup tentukan afterExecute()plugin yang akan dijalankan setelah kategori asli execute()dan dorong setiap pembaruan ke objek Halaman dari sana.

Sayangnya itu tidak berfungsi seperti itu .. alasannya adalah bahwa execute()metode asli (pada akhir) akan mengeksekusi $page->getConfig()->addBodyClass()- panggilan ke metode ini secara otomatis akan memaksa tata letak untuk dimuat dan dihasilkan sepenuhnya, sehingga setiap upaya berikutnya untuk menambah baru pegangan tata letak untuk Halaman sama sekali tidak berguna. Saya mencari-cari cara yang tidak terlalu elegan untuk mencapai hal yang sama (masih menggunakan plugin) .. tidak menemukan.

Saya akhirnya menjalankan controller saya sendiri untuk tampilan kategori, namun saya tidak akan memilih untuk meninggalkannya seperti itu.

Jadi pertanyaan saya adalah .. bagaimana saya bisa menambahkan pegangan tata letak halaman baru (secara terprogram) untuk tampilan kategori? dan melakukannya dengan elegan.

Kristjan H.
sumber
Versi Magento apa yang Anda gunakan? Karena di mana Anda dapat melihat yang $page->getConfig()->addBodyClass()memuat dan menghasilkan tata letak Anda? Saya memiliki tugas yang sama saat ini, hanya dengan halaman CMS.
Giel Berkers
Saya sangat senang Anda mencatat ini, karena Anda menyelamatkan saya banyak kesedihan. Hanya FYI: pengontrol tampilan kategori juga memanggil $ page-> getConfig () -> addBodyClass () yang membuat plugin tidak berguna untuk mencapai hal ini.
Perry Holden

Jawaban:

17

Cara XML

Cara yang mudah adalah dengan membuat file berikut di folder modul Anda: view/frontend/layout/catalog_category_view.xmldengan konten berikut:

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

Tidak lebih atau kurang elegan dari cara PHP dan menurut apa yang Anda temukan lebih aman.

Cara PHP

Sayangnya dalam kasus Anda, sepertinya PHP adalah satu-satunya cara untuk mencapai secara dinamis membuat pegangan berdasarkan parameter yang dimilikinya.

Melalui plugin

Alih-alih membuat plugin pada execute()metode kelas tindakan Anda, Anda bisa langsung membuat plugin pada addPageLayoutHandles()metodeMagento\Framework\View\Result\Page

Masalah utama adalah bahwa itu akan dipanggil setiap kali metode ini dipanggil dan Anda harus menambahkan beberapa kondisi dalam kode plugin Anda untuk memastikan Anda berada di halaman tampilan kategori.

Melalui preferensi

Cara lain untuk melakukannya adalah dengan menggunakan preferensi untuk kelas tindakan tampilan kategori:

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

Kemudian di kelas kontroler kustom Anda, Anda hanya menimpa execute()metode dengan menyalin / menempel metode asli dan menambahkan modifikasi Anda langsung dalam metode ini.

Masalah utama adalah bahwa ketika Anda akan meningkatkan instalasi Magento Anda, jika perubahan ditambahkan ke kelas aksi Magento asli asli, itu tidak akan tercermin dalam kelas tindakan kustom Anda.

Raphael di Digital Pianism
sumber
Masalahnya adalah .. itu perlu ditambahkan secara programatik. Hanya karena pegangan yang dimuat tergantung pada parameter yang dimiliki kategori.
Kristjan H.
@ KristjanH. hmmm saya lihat itu memalukan, izinkan saya menggali lebih jauh
Raphael di Digital Pianism
@ KristjanH. lihat pembaruan saya
Raphael di Digital Pianism
1
Menggunakan <preferensi> .. yaitu, apa yang saya lakukan sebelum saya menulis pertanyaan di sini, bagaimanapun, saya tidak senang dengan itu. Sama dengan menggunakan plugin di addPageLayoutHandles, saya tidak ingin memanggil plugin setiap saat, bahkan jika penalti kinerja tidak ada, itu tidak benar. Mari kita lihat apakah ada solusi lain yang muncul di sini.
Kristjan H.
Apakah Anda mencoba cara lain setelah ini?
LM_Fielding
8

Saya punya masalah serupa. untuk kategori yang tidak menampilkan daftar produk, saya memerlukan pegangan ekstra. setelah gagal menambahkan pegangan melalui Custom Layout XML kategori, saya akhirnya menambahkannya di pengamat pada layout_load_beforeacara tersebut:

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

ada hit kinerja kecil yang terlibat sebagai pengamat dipanggil untuk setiap tampilan halaman. Sayangnya, semua acara terkait 'category_view' tampaknya terlalu dini (kategori belum dimuat) atau terlambat (tata letak sudah diproses).

berganti-ganti
sumber
Terima kasih! Saya memiliki masalah yang sama ( magento.stackexchange.com/questions/156231/… ) dan sebuah plugin aktif \Magento\Cms\Controller\Page\View::execute()dan \Magento\Framework\View\Result\Page::addPageLayoutHandles() or render()tidak berhasil. Solusi terakhir ini adalah satu-satunya solusi yang bekerja untuk saya.
Giel Berkers
1

Mari kita coba amati tata letak acara_load_before. Menjalankan fungsi akan sama seperti ini:

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

Semoga ini bisa membantu

Hồ Trung Nghĩa
sumber