TL;DR
you need to override method _getDefaultCollection
in Mage_Catalog_Model_Resource_Category_Tree
:
protected function _getDefaultCollection($sorted = false)
{
$this->_joinUrlRewriteIntoCollection = true;
$collection = Mage::getModel('catalog/category')->getCollection();
/** @var $collection Mage_Catalog_Model_Resource_Category_Collection */
// your filters here
$collection = $collection->addAttributeToFilter('attribute_code', 'attribute_value');
...
}
More detailed description:
The category tree rendering on frontend starts in app/code/core/Mage/Page/Block/Html/Topmenu.php
when event page_block_html_topmenu_gethtml_before
is fired:
public function getHtml($outermostClass = '', $childrenWrapClass = '')
{
Mage::dispatchEvent('page_block_html_topmenu_gethtml_before', array(
'menu' => $this->_menu,
'block' => $this
));
...
This event is listened by observer in Mage_Catalog_Block_Category::addCatalogToTopmenuItems
which calls method getStoreCategories
of catalog/category
helper:
public function addCatalogToTopmenuItems(Varien_Event_Observer $observer)
{
...
$this->_addCategoriesToMenu(
Mage::helper('catalog/category')->getStoreCategories(), $observer->getMenu(), $block
);
}
Which eventually leads to :
public function getStoreCategories($sorted=false, $asCollection=false, $toLoad=true)
{
...
$storeCategories = $category->getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad);
...
}
Where getCategories
method is lead to Mage_Catalog_Model_Resource_Category_Tree
resource model method.