Cách thêm xử lý bố cục tùy chỉnh theo chương trình cho Chế độ xem danh mục trong Magento 2


9

Vì vậy, tôi muốn thêm một điều khiển bố cục tùy chỉnh cho tất cả các trang xem danh mục .. tay cầm được cho là được tải tùy thuộc vào các tham số danh mục nhất định, vì vậy cần xử lý thêm chương trình với $page->addPageLayoutHandles()

Có vẻ dễ dàng ..? Rõ ràng là không

Magento 2 cung cấp một hệ thống Plugin đẹp mà tôi sẽ sử dụng một cách tự nhiên, chỉ cần xác định một afterExecute()plugin sẽ được chạy sau danh mục gốc execute()và đẩy mọi cập nhật vào đối tượng Trang từ đó.

Thật không may, nó không hoạt động theo cách đó .. lý do là execute()phương thức ban đầu (ở cuối) sẽ thực thi $page->getConfig()->addBodyClass()- một cuộc gọi đến phương thức này sẽ tự động buộc bố cục được tải và tạo hoàn toàn, vì vậy mọi nỗ lực tiếp theo để thêm mới xử lý bố trí để Trang hoàn toàn vô dụng. Tôi nhìn xung quanh để tìm bất kỳ cách không thanh lịch nào để đạt được điều tương tự (vẫn sử dụng plugin) .. không tìm thấy bất kỳ.

Cuối cùng tôi đã chạy bộ điều khiển của riêng mình để xem danh mục, tuy nhiên tôi không muốn để nó như vậy.

Vì vậy, câu hỏi của tôi là .. làm thế nào tôi có thể thêm tay cầm bố cục trang mới (theo chương trình) cho chế độ xem danh mục? và làm điều đó một cách thanh lịch.


Phiên bản Magento nào bạn đang sử dụng? Bởi vì bạn có thể thấy $page->getConfig()->addBodyClass()tải và tạo bố cục của mình ở đâu? Hiện tại tôi đang có một nhiệm vụ tương tự, chỉ với các trang CMS.
Giel Berkers

Tôi rất vui vì bạn đã lưu ý điều này, vì bạn đã cứu tôi một loạt đau buồn. Chỉ cần FYI: trình điều khiển chế độ xem danh mục cũng gọi $ page-> getConfig () -> addBodyClass () làm cho plugin trở nên vô dụng khi thực hiện điều này.
Perry Holden

Câu trả lời:


17

Cách XML

Một cách dễ dàng là tạo tệp sau trong thư mục mô-đun của bạn: view/frontend/layout/catalog_category_view.xmlvới nội dung sau:

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

Nó không hơn hoặc kém thanh lịch hơn cách của PHP và theo những gì bạn thấy thì an toàn hơn.

Cách thức của PHP

Thật không may trong trường hợp của bạn, có vẻ như PHP là cách duy nhất để đạt được các trình điều khiển tạo động dựa trên các tham số mà danh mục có.

Thông qua các plugin

Thay vì tạo một plugin theo execute()phương thức của lớp hành động của bạn, bạn có thể trực tiếp tạo một plugin theo addPageLayoutHandles()phương thứcMagento\Framework\View\Result\Page

Vấn đề chính là nó sẽ được gọi mỗi khi phương thức này được gọi và bạn sẽ phải thêm một số điều kiện trong mã plugin của mình để đảm bảo bạn đang ở trang xem danh mục.

Qua sở thích

Một cách khác để làm điều đó là sử dụng các tùy chọn cho lớp hành động xem danh mục:

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

Sau đó, trong lớp trình điều khiển tùy chỉnh của bạn, bạn chỉ cần ghi đè execute()phương thức bằng cách sao chép / dán phương thức ban đầu và thêm các sửa đổi của bạn trực tiếp vào phương thức này.

Vấn đề chính là khi bạn sẽ nâng cấp cài đặt Magento của mình, nếu các thay đổi được thêm vào lớp hành động Magento gốc, nó sẽ không phản ánh trong lớp hành động tùy chỉnh của bạn.


Vấn đề là .. nó cần được bổ sung theo chương trình. Đơn giản là vì tay cầm đang được tải phụ thuộc vào các tham số mà danh mục có.
Kristjan H.

@KristjanH. hmmm Tôi thấy nó ngượng ngùng, hãy để tôi đào sâu hơn
Raphael tại Digital Pianism

@KristjanH. xem cập nhật của tôi
Raphael tại Digital Pianism

1
Sử dụng <ưu tiên> .. đó là, những gì tôi đã làm ngay trước khi tôi viết câu hỏi ở đây, tuy nhiên, tôi không hài lòng với điều đó. Tương tự với việc sử dụng plugin trên addPageLayoutHandles, tôi không muốn gọi plugin mọi lúc, ngay cả khi hình phạt hiệu suất là không tồn tại, điều đó không đúng. Hãy xem liệu có giải pháp nào khác xuất hiện ở đây không.
Kristjan H.

Bạn đã thử cách nào khác sau này?
LM_Fielding

8

Tôi đã có một vấn đề tương tự. đối với các danh mục không hiển thị danh sách sản phẩm, tôi cần xử lý thêm. sau khi không thêm tay cầm thông qua XML Bố cục tùy chỉnh của danh mục, cuối cùng tôi đã thêm nó vào trình quan sát về layout_load_beforesự kiện:

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ó một hiệu suất nhỏ liên quan đến việc người quan sát được gọi cho mỗi lần xem trang. thật không may, tất cả các sự kiện liên quan đến 'category_view' dường như quá sớm (danh mục chưa được tải) hoặc quá muộn (bố cục đã được xử lý).


Cảm ơn! Tôi đã gặp một vấn đề tương tự ( magento.stackexchange.com/questions/156231/ ) và một plugin trên \Magento\Cms\Controller\Page\View::execute()\Magento\Framework\View\Result\Page::addPageLayoutHandles() or render()không thực hiện được mẹo này. Giải pháp cuối cùng này là giải pháp duy nhất hiệu quả với tôi.
Giel Berkers

1

Hãy thử quan sát layout event_load_b Before. Hàm thực thi sẽ giống như thế này:

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

Hy vọng điều này sẽ giúp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.