Magento 2のカテゴリビューにプログラムでカスタムレイアウトハンドルを追加する方法


9

したがって、すべてのカテゴリビューページにカスタムレイアウトハンドルを追加したいと思います。ロードされるはずのハンドルは特定のカテゴリパラメータに依存するため、プログラムでハンドルを追加する必要があります。 $page->addPageLayoutHandles()

簡単そうです どうやら

Magento 2は、私が自然に使うつもりの素晴らしいプラグインシステムを提供します。afterExecute()元のカテゴリの後に実行するプラグインを定義し、execute()そこからすべての更新をPageオブジェクトにプッシュします。

残念ながら、この方法ではうまく機能しません。理由は、元のexecute()メソッドが(最後に)実行されるためです。$page->getConfig()->addBodyClass()このメソッドを呼び出すと、レイアウトが自動的に完全にロードおよび生成されるため、その後に新しいメソッドを追加しようとすると、 Pageへのレイアウトハンドルは完全に役に立ちません。私は周りを見回して同じことを達成するためにそれほどエレガントではない方法を見つけました(まだプラグインを使用しています)。何も見つかりませんでした。

結局、カテゴリビュー用に独自のコントローラを実行することになりましたが、そのままにしたくありません。

だから私の質問は.. カテゴリビューに新しい(プログラムで)ページレイアウトハンドルを追加するにどうすればよいですか?エレガントにそれを行います。


どのMagentoバージョンを使用していますか?$page->getConfig()->addBodyClass()レイアウトが読み込まれて生成されるのはどこで確認できるでしょうか。現在、CMSページのみで同様のタスクを実行しています。
Giel Berkers 2017年

あなたが私にたくさんの悲しみを救ったので、あなたがこれに気付いて本当にうれしいです。参考までに、カテゴリビューコントローラは$ page-> getConfig()-> addBodyClass()も呼び出します。これにより、プラグインはこれを実行するために役に立たなくなります。
ペリーホールデン

回答:


17

XMLの方法

簡単な方法は、モジュールフォルダーに次のファイルを作成することですview/frontend/layout/catalog_category_view.xml

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

それは多かれ少なかれPHPの方法よりエレガントではなく、あなたが見つけたものによるとそれはより安全です。

PHPの方法

残念ながら、あなたの場合、カテゴリーが持つパラメーターに基づいて動的にハンドルを作成する唯一の方法はPHPのようです。

プラグイン経由

代わりにプラグイン作成のexecute()あなたのアクションクラスのメソッドを、あなたは直接にプラグインを作成することができますaddPageLayoutHandles()する方法Magento\Framework\View\Result\Page

主な問題は、このメソッドが呼び出されるたびに呼び出され、カテゴリビューページにいることを確認するためにプラグインコードにいくつかの条件を追加する必要があることです。

プリファレンス経由

これを行う別の方法は、カテゴリビューアクションクラスの設定を使用することです。

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

次に、カスタムコントローラークラスでexecute()、元のメソッドをコピー/貼り付けしてメソッドをオーバーライドし、このメソッドに直接変更を追加します。

主な問題は、Magentoインストールをアップグレードするときに、元のネイティブMagentoアクションクラスに変更が追加された場合、カスタムアクションクラスに反映されないことです。


問題は..プログラムで追加する必要があります。ロードされるハンドルは、カテゴリが持つパラメータに依存するからです。
クリスチャンH.16年


@KristjanH。私のアップデートを参照してください
デジタルピアニズムのラファエル、

1
<preference> ..を使用します。つまり、ここで質問を書く直前に私は何をしたかですが、私はそれに満足していません。addPageLayoutHandlesでプラグインを使用する場合と同じように、パフォーマンスのペナルティが存在しない場合でも、常にプラグインを呼び出したくありません。それは正しくありません。他の解決策がここに表示されるかどうか確認してみましょう。
Kristjan H. 2016

この後、他の方法を試しましたか?
LM_Fielding

8

同様の問題がありました。商品リストが表示されないカテゴリでは、追加のハンドルが必要でした。カテゴリのカスタムレイアウトXMLを介してハンドルを追加できなかった後、layout_load_beforeイベントのオブザーバーに追加しました。

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

ページビューごとにオブザーバーが呼び出されるため、小さなパフォーマンスヒットが発生します。残念ながら、すべての「category_view」関連イベントは、早すぎる(カテゴリがまだロードされていない)か遅すぎる(レイアウトがすでに処理されている)ようです。


ありがとう!私は同様の問題(magento.stackexchange.com/questions/156231/…)とプラグインをオン\Magento\Cms\Controller\Page\View::execute()\Magento\Framework\View\Result\Page::addPageLayoutHandles() or render()していましたが、うまくいきませんでした。この最後の手段のソリューションは、私にとって有効な唯一のソリューションでした。
Giel Berkers 2017年

1

イベントlayout_load_beforeを観察してみましょう。実行関数はこれと同じになります:

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

これが役に立てば幸い

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.