レイヤードナビゲーションにコレクション属性が設定されていない-CMSページ


7

カスタム製品コレクション(「新しい」製品)を含むウィジェットを含むCMSページにレイヤードナビゲーションを追加しようとしています。このウィジェット内には、適切なパラメーターを指定してこのコレクションをフィルターする機能があります。このコレクションをレイヤードナビゲーションブロックに渡し、その属性を表示するにはどうすればよいですか?

これは、CMSカスタムレイアウトXMLでレイヤードナビゲーションを呼び出す方法です。

<reference name="content">
        <!-- Layered Navigation Block -->
        <block type="catalog/layer_view" name="catalog.leftnav" before="-" template="catalog/layer/view.phtml" >
        </block>
</reference>

これは、CMSページで製品コレクションを呼び出す方法です。

{{widget type="catalog/product_widget_new" display_type="new_products" show_pager="1" products_count="60" template="catalog/product/widget/new/content/new_grid.phtml"}}

これは、ウィジェットブロックで製品コレクションを生成する方法です。

protected function _getProductCollection()
{
    $todayStartOfDayDate = Mage::app()->getLocale()->date()
        ->setTime('00:00:00')
        ->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
    $todayEndOfDayDate = Mage::app()->getLocale()->date()
        ->setTime('23:59:59')
        ->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
    /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
    $collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
    $this->_addProductAttributesAndPrices($collection)
        ->addStoreFilter()
        ->addAttributeToFilter('news_from_date', array('or' => array(
            0 => array('date' => true, 'to' => $todayEndOfDayDate),
            1 => array('is' => new Zend_Db_Expr('null')))
        ), 'left')
        ->addAttributeToFilter('news_to_date', array('or' => array(
            0 => array('date' => true, 'from' => $todayStartOfDayDate),
            1 => array('is' => new Zend_Db_Expr('null')))
        ), 'left')
        ->addAttributeToFilter(
            array(
                array('attribute' => 'news_from_date', 'is' => new Zend_Db_Expr('not null')),
                array('attribute' => 'news_to_date', 'is' => new Zend_Db_Expr('not null'))
            )
        )
        ->setPageSize($this->getProductsCount())
        ->setCurPage(1);
    return $collection;
}

ウィジェットのテンプレートページは、価格、レビュー、写真などをページサイズバリアント形式で表示するための標準的な方法です。


1
あなたが達成しようとしていることは不可能です、少なくともcmsページとウィジェット、そしてレイアウトの更新を少なくとも使用することで。これが理由です。Magentoには2つのレイヤーモデルがあります。1つはカテゴリのコンテキスト内で機能し、もう1つは検索結果のコンテキスト内で機能します。あなたの例はこれらのカテゴリーのどちらにも該当しません。コレクションタイプ(新製品)を処理するカスタムレイヤーモデルが必要になります。
マリウス

1
私は解決策を考え出すことができるかもしれませんが、これには、カスタムコントローラー、ブロックおよびレイヤーモデル(およびその他)を使用したカスタムモジュールの記述が含まれます。しかし、解決策を探す前に、これがあなたにとってうまくいくかどうか知りたいです。つまり、URLは引き続き使用できますがwww.mysite.com/new-products、これnew-productsはcmsページではありません。別のコントローラーで処理されます。そして、ページ付けされたすべての新製品が含まれます(方法がわかった場合は、おそらく並べ替えオプションが付いています)。これはうまくいきますか?または、単純なCMSページソリューションが必要ですか?
マリウス

妥当な解決策となる@Marius。ウィジェットをcmsページに挿入するのと同じように、そのソリューションを挿入できると思いますか?
easymoden00b 2015

1
あんまり。私が考えている解決策は、個別のコントローラーを備えた個別のページを作成することです(おそらくいくつかのテンプレートファイル)。csmページのように変更することはできません。それだけで動作します:)それだけです。新しいモジュールの作成
マリウス

@Mariusなるほど、うまくいくかもしれません。
easymoden00b 2015

回答:


7

レイヤードナビゲーションが機能するには、アクティブなカテゴリが必要です。cms-pagesのlayout-xmlに次のブロックを追加します。

<cms_page>
    <block type="catalog/layer_view" name="catalog.leftnav" before="-" template="catalog/layer/view.phtml">
        <action method="setCategoryId"><category_id>2</category_id></action>
    </block>
</cms_page>

1
他に何を使用して製品を投入しますか?
roman204 2015

1
はい、わかりました。この場合、Mage_Catalog_Model__Layer:getProductCollectionをオーバーライドする必要があります...ソリューションを提供するためにここで何ができるかを確認します。
roman204 2015

2
@ easymoden00bルートカテゴリIDを追加してみてください。そして、そのカテゴリに対して「Is Anchor」を「Yes」にしたことを確認してください。
MagePsycho 2015

1
@MagePsychoを選択すると、すべての製品のフィルター可能な属性をフィルターに掛けることができます。フィルターにウィジェットからの製品のみを含める必要があるという質問を理解しているので、間違っている場合は修正してください...
roman204

1
AFAIK、OPは、階層型ナビゲーションを備えた新製品のグローバルリストを求めています。
MagePsycho 2015

28

コメントで説明したように、cmsページを使用してこれを行う方法はないと思います。これは、新しい製品リストに関連付けられているレイヤーモデルがないためです。カテゴリコンテキストと検索コンテキストのレイヤーモデルのみがあります。
私の解決策(テストおよび動作)には、ページで新規としてマークされたすべての製品をリストするモジュールを作成し、新しい製品のコレクションを処理するレイヤーモデルを含めることが含まれます。
いきます それは長いものです。
拡張機能を呼び出しましたStackExchange_NewProductsが、名前を自由に変更できます。
次のファイルが必要になります。

app/etc/modules/StackExchange_NewProducts.xml -宣言ファイル:

<?xml version="1.0"?>
<config>
    <modules>
        <StackExchange_NewProducts>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Catalog />
            </depends>
        </StackExchange_NewProducts>
    </modules>
</config>

app/code/local/StackExchange/NewProducts/etc/config.xml -構成ファイル

<?xml version="1.0"?>
<config>
    <modules>
        <StackExchange_NewProducts>
            <version>1.0.0</version>
        </StackExchange_NewProducts>
    </modules>
    <global>
        <models>
            <stackexchange_newproducts>
                <class>StackExchange_NewProducts_Model</class>
            </stackexchange_newproducts>
        </models>
        <blocks>
            <stackexchange_newproducts>
                <class>StackExchange_NewProducts_Block</class>
            </stackexchange_newproducts>
        </blocks>
        <helpers>
            <stackexchange_newproducts>
                <class>StackExchange_NewProducts_Helper</class>
            </stackexchange_newproducts>
        </helpers>
        <events>
            <controller_front_init_routers> <!-- create a custom router to handle the 'new-products' url -->
                <observers>
                    <stackexchange_newproducts>
                        <class>StackExchange_NewProducts_Controller_Router</class>
                        <method>initControllerRouters</method>
                    </stackexchange_newproducts>
                </observers>
            </controller_front_init_routers>
        </events>
    </global>
    <frontend>
        <routers> <!-- declare a router -->
            <newproducts>
                <use>standard</use>
                <args>
                    <module>StackExchange_NewProducts</module>
                    <frontName>newproducts</frontName>
                </args>
            </newproducts>
        </routers>
        <layout>
            <updates>
                <stackexchange_newproducts>
                    <file>stackexchange_newproducts.xml</file>
                </stackexchange_newproducts>
            </updates>
        </layout>
    </frontend>
</config>

app/code/local/StackExchange/NewProducts/Controller/Router.php-URLを処理し、new-productsそれをコントローラーとアクションにマップするカスタムルーター

<?php
class StackExchange_NewProducts_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract
{
    const NEW_PRODUCTS_URL_KEY = 'new-products';
    public function initControllerRouters($observer)
    {
        $front = $observer->getEvent()->getFront();
        $front->addRouter('stackexchange_newproducts', $this);
        return $this;
    }

    public function match(Zend_Controller_Request_Http $request)
    {
        if (!Mage::isInstalled()) {
            Mage::app()->getFrontController()->getResponse()
                ->setRedirect(Mage::getUrl('install'))
                ->sendResponse();
            exit;
        }
        $urlKey = trim($request->getPathInfo(), '/');
        if ($urlKey == self::NEW_PRODUCTS_URL_KEY) {
            $request->setModuleName('newproducts')
                ->setControllerName('index')
                ->setActionName('index');
            $request->setAlias(
                Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
                $urlKey
            );
            return true;
        }
        return false;
    }
}

app/code/local/StackExchange/NewProducts/controllers/IndexController.php -新製品を表示する実際のコントローラー

<?php
class StackExchange_NewProducts_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
        $this->loadLayout();
        $this->renderLayout();
    }
}

app/code/local/StackExchange/NewProducts/Helper/Data.php -モジュールの一般的なヘルパー

<?php
class StackExchange_NewProducts_Helper_Data extends Mage_Core_Helper_Abstract
{

}

app/design/frontend/base/default/layout/stackexchange_newproducts.xml -ページのコンテンツを定義するモジュールレイアウトファイル

<?xml version="1.0"?>
<layout>
    <newproducts_index_index>
        <reference name="root">
            <action method="setTemplate">
                <template>page/2columns-left.phtml</template>
            </action>
        </reference>
        <reference name="left">
            <block type="stackexchange_newproducts/layer_new" name="catalog.leftnav" before="-" template="catalog/layer/view.phtml" />
        </reference>
        <reference name="content">
            <block type="core/template" name="new_products_container" as="new_products_container" template="stackexchange_newproducts/container.phtml">
                <action method="setTitle" translate="title" module="stackexchange_newproducts">
                    <title>New Products</title>
                </action>
                <block type="stackexchange_newproducts/new" name="new_product" as="new_products" template="catalog/product/list.phtml">
                    <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                        <block type="page/html_pager" name="product_list_toolbar_pager"/>
                    </block>
                    <action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
                    <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
                </block>
            </block>
        </reference>

    </newproducts_index_index>
</layout>

app/code/local/StackExchange/NewProducts/Block/New.php -新しい製品コレクションをレンダリングするブロック:

<?php
class StackExchange_NewProducts_Block_New extends Mage_Catalog_Block_Product_List
{
    public function __construct()
    {
        parent::__construct();
    }
    public function getModuleName()
    {
        return 'Mage_Catalog';
    }
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection)) {
            $this->_productCollection = $this->getLayer()->getProductCollection();
        }
        return $this->_productCollection;
    }
    public function getLayer()
    {
        $layer = Mage::registry('current_layer');
        if ($layer) {
            return $layer;
        }
        return Mage::getSingleton('stackexchange_newproducts/layer');
    }
}

app/code/local/StackExchange/NewProducts/Block/Layer/New.php -左側に表示する必要があるレイヤーブロック(フィルター)

<?php
class StackExchange_NewProducts_Block_Layer_New extends Mage_Catalog_Block_Layer_View
{
    public function getLayer()
    {
        if (!$this->hasData('_layer')){
            $layer = Mage::getSingleton('stackexchange_newproducts/layer');
            $this->setData('_layer', $layer);
        }
        return $this->getData('_layer');
    }
    protected function _initBlocks()
    {
        parent::_initBlocks();
        $this->_attributeFilterBlockName    = 'stackexchange_newproducts/layer_filter_attribute';
        $this->_priceFilterBlockName        = 'stackexchange_newproducts/layer_filter_price';
        $this->_decimalFilterBlockName      = 'stackexchange_newproducts/layer_filter_decimal';
    }
    protected function _prepareLayout()
    {
        $stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
            ->setLayer($this->getLayer());
        $this->setChild('layer_state', $stateBlock);

        $filterableAttributes = $this->_getFilterableAttributes();
        foreach ($filterableAttributes as $attribute) {
            if ($attribute->getAttributeCode() == 'price') {
                $filterBlockName = $this->_priceFilterBlockName;
            } elseif ($attribute->getBackendType() == 'decimal') {
                $filterBlockName = $this->_decimalFilterBlockName;
            } else {
                $filterBlockName = $this->_attributeFilterBlockName;
            }

            $this->setChild($attribute->getAttributeCode() . '_filter',
                $this->getLayout()->createBlock($filterBlockName)
                    ->setLayer($this->getLayer())
                    ->setAttributeModel($attribute)
                    ->init());
        }

        $this->getLayer()->apply();
        return $this;
    }
}

ここで、各属性タイプには、それに関連付けられたフィルターブロックが必要です。

app/code/local/StackExchange/NewProducts/Block/Layer/Filter/Attribute.php -属性の一般的なフィルターブロック

<?php 
class StackExchange_NewProducts_Block_Layer_Filter_Attribute extends Mage_Catalog_Block_Layer_Filter_Attribute
{
    public function __construct()
    {
        parent::__construct();
        $this->_filterModelName = 'stackexchange_newproducts/layer_filter_attribute';
    }
}

app/code/local/StackExchange/NewProducts/Block/Layer/Filter/Decimal.php -10進数属性のフィルターブロック

<?php 
class StackExchange_NewProducts_Block_Layer_Filter_Decimal extends Mage_Catalog_Block_Layer_Filter_Decimal
{
    public function __construct()
    {
        parent::__construct();
        $this->_filterModelName = 'stackexchange_newproducts/layer_filter_decimal';
    }
}

app/code/local/StackExchange/NewProducts/Block/Layer/Filter/Price.php -価格属性のフィルターブロック

<?php 
class StackExchange_NewProducts_Block_Layer_Filter_Price extends Mage_Catalog_Block_Layer_Filter_Price
{
    public function __construct()
    {
        parent::__construct();
        $this->_filterModelName = 'stackexchange_newproducts/layer_filter_price';
    }
}

app/code/local/StackExchange/NewProducts/Model/Layer.php -新製品を扱うためのレイヤーモデル

<?php
class StackExchange_NewProducts_Model_Layer extends Mage_Catalog_Model_Layer
{
    public function getStateKey()
    {
        if ($this->_stateKey === null) {
            $this->_stateKey = 'STORE_'.Mage::app()->getStore()->getId()
                . '_NEW_PRODUCTS_'
                . '_CUSTGROUP_' . Mage::getSingleton('customer/session')->getCustomerGroupId();
        }

        return $this->_stateKey;
    }

    public function getStateTags(array $additionalTags = array())
    {
        $additionalTags = array_merge($additionalTags, array('new_products'));
        return $additionalTags;
    }

    public function getProductCollection()
    {
        if (isset($this->_productCollections['new_products'])) {
            $collection = $this->_productCollections['new_products'];
        } else {
            $collection = $this->_getCollection();
            $this->prepareProductCollection($collection);
            $this->_productCollections['new_products'] = $collection;
        }

        return $collection;
    }
    public function prepareProductCollection($collection)
    {
        $collection
            ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
            ->addMinimalPrice()
            ->addFinalPrice()
            ->addTaxPercents()
            ->addUrlRewrite();

        Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
        Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
        return $this;
    }

    protected function _getCollection()
    {
        $todayStartOfDayDate  = Mage::app()->getLocale()->date()
            ->setTime('00:00:00')
            ->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);

        $todayEndOfDayDate  = Mage::app()->getLocale()->date()
            ->setTime('23:59:59')
            ->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);

        $collection = Mage::getModel('catalog/product')->getCollection()
            ->addStoreFilter()
            ->addAttributeToFilter('news_from_date', array('or'=> array(
                0 => array('date' => true, 'to' => $todayEndOfDayDate),
                1 => array('is' => new Zend_Db_Expr('null')))
            ), 'left')
            ->addAttributeToFilter('news_to_date', array('or'=> array(
                0 => array('date' => true, 'from' => $todayStartOfDayDate),
                1 => array('is' => new Zend_Db_Expr('null')))
            ), 'left')
            ->addAttributeToFilter(
                array(
                    array('attribute' => 'news_from_date', 'is'=>new Zend_Db_Expr('not null')),
                    array('attribute' => 'news_to_date', 'is'=>new Zend_Db_Expr('not null'))
                )
            )
            ->addAttributeToSort('news_from_date', 'desc');
        return $collection;
    }
}

各属性にはフィルター用のブロックが必要であるように、フィルターを処理するためのモデルも必要です。

app/code/local/StackExchange/NewProducts/Model/Layer/Filter/Attribute.php -一般属性フィルターモデル

<?php 
class StackExchange_NewProducts_Model_Layer_Filter_Attribute extends Mage_Catalog_Model_Layer_Filter_Attribute
{
    protected function _createItem($label, $value, $count = 0)
    {
        return Mage::getModel('stackexchange_newproducts/layer_filter_item')
            ->setFilter($this)
            ->setLabel($label)
            ->setValue($value)
            ->setCount($count);
    }
}

app/code/local/StackExchange/NewProducts/Model/Layer/Filter/Decimal.php -10進数属性フィルターモデル

<?php 
class StackExchange_NewProducts_Model_Layer_Filter_Decimal extends Mage_Catalog_Model_Layer_Filter_Attribute
{
    protected function _createItem($label, $value, $count = 0)
    {
        return Mage::getModel('stackexchange_newproducts/layer_filter_item')
            ->setFilter($this)
            ->setLabel($label)
            ->setValue($value)
            ->setCount($count);
    }
}

app/code/local/StackExchange/NewProducts/Model/Layer/Filter/Price.php -価格属性フィルターモデル

<?php 
class StackExchange_NewProducts_Model_Layer_Filter_Price extends Mage_Catalog_Model_Layer_Filter_Price
{
    protected function _createItem($label, $value, $count = 0)
    {
        return Mage::getModel('stackexchange_newproducts/layer_filter_item')
            ->setFilter($this)
            ->setLabel($label)
            ->setValue($value)
            ->setCount($count);
    }
}

app/code/local/StackExchange/NewProducts/Model/Layer/Filter/Item.php-フィルターには、アイテムオブジェクトのコレクションが必要です。これはアイテムオブジェクトです。これが必要かどうかは不明です。デフォルトのカタログアイテムモデルが使えると思います。

<?php 
class StackExchange_NewProducts_Model_Layer_Filter_Item extends Mage_Catalog_Model_Layer_Filter_Item
{

}

app/design/frontend/base/default/template/stackexchange_newproducts/container.phtml -タイトルを設定してセッションメッセージを表示できるように、新製品のコンテナとして機能するテンプレートファイル。

<?php if ($this->getTitle()) : ?>
    <div class="page-title category-title">
        <h1><?php echo $this->getTitle() ?></h1>
    </div>
<?php endif;?>
<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
<?php echo $this->getChildHtml();?>

それでおしまい。すべてのファイルを作成した後でキャッシュをクリアし、コンパイルを無効にします。
これは私の側でどのように見えるかのスクリーンショットです
スクリーンショット。(サンプルデータでce 1.7を使用)


4
不足しているのは翻訳ファイルだけです。
マリウス

1
そこに良いモジュールの名前が付けられています:)
David Manners

3
@DavidManners。うん。名前がどこに来たのかはわかりませんが、それは私を襲っただけです:)。著作権の補償を求めないでください。
マリウス

3
ビールはやります;)
デビッド・マナーズ

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