Magento – Product Filtering—all Products with attribute value based on the admin value name

collection-filteringfiltered-navmodule

I have created a custom attribute for a Product, with the code »gender«, as a dropdown list. I has, unsurprisingly, two possible values: »male« and »female« and the properties table looks like this:

enter image description here

I have created a custom block, extending Mage_Catalog_Block_Product_List and added a method addFilterAttribute($key, $value), so that I can instantiate the block like that in the modules layout update:

<reference name="content">
  <block type="mymodule/page_filtered" name="mymodule.men.content">
    <action method="addFilterAttribute">
      <key>gender</key>
      <value>male</value>
    </action>
  </block>
</reference>

So as one might expect, I would like to create a list/grid of Products containing all the products for male customers. But since the value I pass to the block is the admin label for the corresponding value, I do not get any products listed.

Here is the code I am using in the block:

class Namepace_Module_Block_Page_Filtered
    extends Mage_Catalog_Block_Product_List
{
    private $attributes;

    public function _construct()
    {
        $this->attributes = array();
        $this->setTemplate = 'page/list.phtml';
    }

    public function addFilterAttribute($key, $value)
    {
        $this->attributes[$key] = $value;
    }

    public function getProducts()
    {
        $collection = Mage::getModel('catalog/product')->getCollection();
        $collection->addAttributeToSelect('*');

        foreach($this->attributes as $key => $value)
        {
            $collection->addAttributeToFilter($key, array('eq' => $value));
        }

        $collection->load();
        return $collection;
    }
}

But as I said, the list is empty, what can I do?

EDIT

I tested some values, and if I change the xml to:

<reference name="content">
  <block type="mymodule/page_filtered" name="mymodule.men.content">
    <action method="addFilterAttribute">
      <key>gender</key>
      <value>9</value>
    </action>
  </block>
</reference>

I does the Job, but I do not want to fiddle with numerical attribute values, since the would be very inconvenient in configuration.

Best Answer

If the only options you are going to have are Male and Female, and you need to be able to filter those by those values, you need to have them not depend on the environment. I mean, if you move your website somewhere else, you might get different ids.
To avoid this you should use a custom source model for your attribute.
Create your own extension and change the source model for your gender attribute like this:

$installer->updateAttribute('catalog_product', 'gender', 'source_model', '[module]/source_gender'); 

Then create the source model.

class [Namespace]_[Module]_Model_Source_Gender extends Mage_Eav_Model_Entity_Attribute_Source_Abstract 
{
    const GENDER_MALE = 1;
    const GENDER_FEMALE = 2;

    public function getAllOptions()
    {
        $options = array(
            array(
                'value' => self::GENDER_MALE;
                'label' => Mage::helper('catalog')->__('Male')
            ),
            array(
                'value' => self::GENDER_FEMALE;
                'label' => Mage::helper('catalog')->__('Female')
            ),
        );
        return $options;
    }
}

Now you can use the value 1 and 2 for filtering because you know they will never change.