Reference Mage_Catalog_Model_Resource_Eav_Attribute::isIndexable()
, which is used by the EAV indexer to check if a given attribute may be included in the layered navigation index.
public function isIndexable()
{
// exclude price attribute
if ($this->getAttributeCode() == 'price') {
return false;
}
if (!$this->getIsFilterableInSearch() && !$this->getIsVisibleInAdvancedSearch() && !$this->getIsFilterable()) {
return false;
}
$backendType = $this->getBackendType();
$frontendInput = $this->getFrontendInput();
if ($backendType == 'int' && $frontendInput == 'select') {
return true;
} else if ($backendType == 'varchar' && $frontendInput == 'multiselect') {
return true;
} else if ($backendType == 'decimal') {
return true;
}
return false;
}
To make other input types indexable, you need to rewrite this attribute resource model (or specify a custom model that refers to a custom resource model in the eav_attribute.attribute_model
property for your attribute.
The reason why the EAV indexer has this limitation, is because it only knows how to process integer values. The same is true for the layered navigation attribute filter model.
If your values are castable to integers, you will be able to get away with using a varchar or text value.
Otherwise you will have to rewrite the attribute filter model to correctly process your values, or implement your own custom filter model.
Yes, very possible, and I do exactly the same for a client site.
First I created a new attribute for categories, to allow me to set that a category needs to use the normal link. This is done via a module.
The module structure:
app/code/local/ProxiBlue/AttributeUseNormalFilterLink/
app/code/local/ProxiBlue/AttributeUseNormalFilterLink/Model/Mysql4/
app/code/local/ProxiBlue/AttributeUseNormalFilterLink/etc
app/code/local/ProxiBlue/AttributeUseNormalFilterLink/sql/proxiblue_filterlink_setup
In Model/Mysql4 I have file Setup.php
Contents:
class ProxiBlue_AttributeUseNormalFilterLink_Model_Mysql4_Setup extends Mage_Catalog_Model_Resource_Setup {
private $_category_attributes = array(
'use_normal_filter_link' => array(
'label' => 'Use normal filter link in left navigation',
'type' => 'int',
'input' => 'select',
'source' => 'eav/entity_attribute_source_boolean',
'default' => '0',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
'visible' => true,
'required' => false,
'user_defined' => false,
'visible_on_front' => true,
'is_visible_on_front' =>true,
'used_in_product_listing' => true,
)
);
public function getDefaultEntities() {
$entities = array();
$default_attribute_options = array(
'group' => 'General Information',
'required' => false,
);
/* Build Catalog Attributes */
$entities['catalog_category'] = array(
'entity_model' => 'catalog/category',
'attribute_model' => 'catalog/resource_eav_attribute',
'table' => 'catalog/category',
'additional_attribute_table' => 'catalog/eav_attribute',
'entity_attribute_collection' => 'catalog/category_attribute_collection',
'attributes' => array(),
);
foreach ($this->_category_attributes as $name => $options) {
/* Override values provided by the defaults */
$attribute_options = $default_attribute_options;
foreach ($options as $k => $v) {
$attribute_options[$k] = $v;
}
$entities['catalog_category']['attributes'][$name] = $attribute_options;
}
return $entities;
}
}
in etc folder I have the config.xml
contents:
<modules>
<ProxiBlue_AttributeUseNormalFilterLink>
<version>0.0.1</version>
</ProxiBlue_AttributeUseNormalFilterLink>
</modules>
<global>
<models>
<proxiblue_attributeusenormalfilterlink>
<class>ProxiBlue_AttributeUseNormalFilterLink_Model</class>
</proxiblue_attributeusenormalfilterlink>
</models>
<resources>
<proxiblue_filterlink_setup>
<setup>
<module>ProxiBlue_AttributeUseNormalFilterLink</module>
<class>ProxiBlue_AttributeUseNormalFilterLink_Model_Mysql4_Setup</class>
</setup>
</proxiblue_filterlink_setup>
</resources>
</global>
and in the sql fiolder I have the install script : mysql4-install-0.0.1.php
contents:
$installer = $this;
$installer->startSetup();
$installer->installEntities();
$installer->endSetup();
Now you can adjust the filter template to use this attribute, and any category can be set to display the actual category link, and not work as a filter.
Copy the template catalog/layer/filter.phtml to your custtom theme folder, then adjust as follows: (note this has some other customization, so pull the bits you need)
<?php $category = false; ?>
<?php if ($this instanceof Mage_Catalog_Block_Layer_Filter_Category): ?>
<?php $category = Mage::registry('current_category'); ?>
<?php if ($category): ?>
<h2>
<a class='level-top' href="<?php $category->getUrl(); ?>"><?php echo $category->getName(); ?></a>
</h2>
<?php endif; ?>
<?php endif; ?>
<ol>
<?php foreach ($this->getItems() as $_item): ?>
<li>
<?php if ($_item->getCount() > 0): ?>
<?php
$link = $_item->getUrl();
if(is_object($category) && !$category->getUseNormalFilterLink()){
$filter = $_item->getFilter();
if($filter instanceof Mage_Catalog_Model_Layer_Filter_Category) {
$linkCategory = mage::getModel('catalog/category')->load($_item->getValue());
if($linkCategory->getId()){
$link = $linkCategory->getUrl();
}
}
}
?>
<a href="<?php echo $this->urlEscape($link) ?>"><?php echo $_item->getLabel() ?></a>
<?php else: echo $_item->getLabel() ?>
<?php endif; ?>
<?php //echo $_item->getCount() ?>
</li>
<?php endforeach ?>
</ol>
Best Answer
From the documentation:
That means you can't filter by a textarea type attribute out of the box in Magento.