Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento - get filterable attributes by category

I have created a custom navigation module specifically for a website, but I really want to be able to list filterable attributes by a specific category. So for instance my main navigation is:

  • Category 1
  • Category 2
  • Category 3 etc.

I then that when a user mouses over a category, they are then presented with an expanded menu with a few filterable options e.g.:


Category 1

View by manufacturer:

  • Manufacturer 1
  • Manufacturer 2
  • Manufacturer 3 etc.

I am able to get all filterable attributes for the store, but I want this list to pull in only the filterable attributes per category, as for instance Category 1 may have different manufacturers to Category 2. I then need to cache these results as this will not change often.

like image 530
wiseguydigital Avatar asked Jul 01 '10 12:07

wiseguydigital


2 Answers

The answer that Joe gave was a good starting point, but the attributes didn't returned any options yet. After a lot of frustrations I solved the problem with the following code. Hope it helps all of you out.

$layer = Mage::getModel("catalog/layer");
foreach($categories as $categoryid) {
    $category = Mage::getModel("catalog/category")->load($categoryid);
    $layer->setCurrentCategory($category);
    $attributes = $layer->getFilterableAttributes();

    foreach ($attributes as $attribute) {
        if ($attribute->getAttributeCode() == 'price') {
            $filterBlockName = 'catalog/layer_filter_price';
        } elseif ($attribute->getBackendType() == 'decimal') {
            $filterBlockName = 'catalog/layer_filter_decimal';
        } else {
            $filterBlockName = 'catalog/layer_filter_attribute';
        }

        $result = $this->getLayout()->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();

        foreach($result->getItems() as $option) {
            echo $option->getLabel().'<br/>';
            echo $option->getValue();
        }
}

The only thing you'll need to do yourself is create the correct link using the getValue() functions.

This code has been tested in Magento 1.5

like image 146
Jasper Avatar answered Sep 20 '22 13:09

Jasper


Magento uses the model Catalog_Model_Layer to accomplish this, so I'm guessing this may be your best bet. Caveat emptor, I have not tested this code yet:

$layer = Mage::getModel("catalog/layer");
foreach($categories as $categoryid) {
    $category = Mage::getModel("catalog/category")->load($categoryid);
    $layer->setCurrentCategory($category);
    $attributes = $layer->getFilterableAttributes();
    // do something with your attributes
}

Each iteration here will give you an object of the class Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute_Collection, which you should be able to iterate over in a foreach loop to get your desired output.

For caching, try enabling block caching on your site and give the block a cache tag like the following. Magento will cache the HTML output and all will be right with the world:

protected function _construct() {
    $this->addData(array(
        'cache_lifetime' => 3600,
        'cache_tags'     => array(Mage_Catalog_Model_Product::CACHE_TAG),
        'cache_key'      => $someUniqueIdentifierYouCreate,
    ));
}

The cache will only be valid for the key you pass, so make sure that, if the menu is to change (w/o flushing the cache, for instance), that the cache key is different.

Hope that helps!

Thanks, Joe

like image 43
Joe Mastey Avatar answered Sep 20 '22 13:09

Joe Mastey