Listing Sub-Categories

Let’s say you have a Category Set called Products. And you have a first-level category called Shoes, which has several sub-categories such as Running, Football, Dress, etc.

One way to display the sub-categories of Shoes is:

perch_categories([
    'filter' => 'catPath',
    'match' => 'contains',
    'value' => 'products/shoes/?'
]);

However, the above includes the parent category Shoes too. If I’m listing what types of shoes a store sells, I don’t want to list “shoes” as a type of shoes.

One option is to apply multiple filters to exclude the first level category. Each sub-category has a parent category and has a record of the parent category ID catParentID. The first level category doesn’t have a parent category so its catParentID is always 0.

So given that product/shoes/ is a first level category, we can exclude it by filtering for categories that have a parent ID that is greater than 0:

perch_categories([
    'filter' => [
        [
            'filter' => 'catPath',
            'match' => 'contains',
            'value' => 'products/shoes/?'
        ],
        [
            'filter' => 'catParentID',
            'match' => 'gt',
            'value' => 0
        ]
    ]
]);

What if the parent category we want to exclude is at a deeper level? Let’s say the category products/shoes/running/ has sub-categories such as products/shoes/running/cushioned/ and products/shoes/running/trail/ and we want to display the type or running shoes the store sells. The above approach won’t work. Even if we set the value of the first filter to products/shoes/running/?, it would display “running” as a type of running shoes which is not what we want.

A more practical approach that works for all category levels is to use a regex filter:

$catPath = 'products/shoes/running/';

perch_categories([
    'filter' => 'catPath',
    'match' => 'regex',
    'value' => '^' . $catPath . '([a-z])+' 
]);
link

Related articles