Exclude Categories from Search Results
By default, all categories indexed to Klevu have a visibility of search. There are 2 possible approaches to change this depending on your needs. The first is to exclude the category from the sync altogether using an isIndexableCondition. The second is to change the visibility sent in the data.
Is Indexable Condition
Excluding the category this way would result in no products showing for this category on the frontend of your store for Category Navigation.
To do this we inject an isIndexableCondition into the isIndexableConditions array for the virtual type Klevu\IndexingCategories\Service\Determiner\IsIndexableDeterminer
<virtualType name="Klevu\IndexingCategoriess\Service\Determiner\IsIndexableDeterminer">
<arguments>
<argument name="isIndexableConditions" xsi:type="array">
<item name="pageIsIndexableCondition"
xsi:type="object">Vendor\Module\Service\Determiner\CategoryIdIsIndexableCondition</item>
</argument>
</arguments>
</virtualType>
Create that class, which must implement the IsIndexableConditionInterface
<?php
namespace Vendor\Module\Service\Determiner;
use Klevu\IndexingApi\Service\Determiner\IsIndexableConditionInterface;
use Magento\Catalog\Api\Data\CategoryInterface;
class CategoryIdIsIndexableCondition implements IsIndexableConditionInterface
{
/**
* Edit routes as required
* Alternatively inject these via di.xml
*
* @param int[]
*/
private array $excludedCategories = [
4,
23,
];
public function execute(
ExtensibleDataInterface|PageInterface $entity,
StoreInterface $store,
): bool {
if (!($entity instanceof CategoryInterface)) {
throw new \InvalidArgumentException(
sprintf(
'Invalid argument provided for "$entity". Expected %s, received %s.',
CategoryInterface::class,
get_debug_type($entity),
),
);
}
return !in_array(
needle: (int)$entity->getId(),
haystack: $this->excludedCategories,
strict: true,
);
}
}
See Entities Is Indexable Determiner for more information.
Change Visibility in the Synced Data
To change the data synced we must override the pipeline YAML for categories.
Create the override YAML file
stages:
iterateIndexingRecordsBatch:
stages:
iterateIndexingRecords:
stages:
processCategory:
stages:
createRecord:
stages:
attributes:
stages:
visibility: Vendor_Module::etc/pipeline/category/attributes/visibility.yml Create the imported visibility YAML file. It is possible to do this all in one YAML file, but separating it into multiple files makes it easier to read. To remove all categories from search.
stages:
-
pipeline: Stage\StaticValue
args:
value: [""]To remove some categories from search. Take the current category and pass it into a transformer. This transformer should return an array of strings containing with or search.
stages:
-
pipeline: Stage\Extract
args:
extraction: currentCategory::
transformations:
- ToVisibilityCreate the transformer to handle the visibility
namespace Vendor\Module\Pipeline\Transformer;
use Klevu\Pipelines\Transformer\TransformerInterface;
use Magento\Catalog\Api\Data\CategoryInterface;
class ToVisibility implements TransformerInterface
{
/*
* @return string[]
*/
public function transform(
mixed $data,
?ArgumentIterator $arguments = null,
?\ArrayAccess $context = null,
): array {
if (!($data instanceof CategoryInterface)) {
throw new InvalidInputDataException(
transformerName: $this::class,
expectedType: CategoryInterface::class,
arguments: $arguments,
data: $data,
);
}
return $this->visibilityProvider->get(
category: data,
);
}If you create a transformer in a custom module it must be registered with the pipelines before it can be used. See Registering Transformers for more information.
Alternatively we could add an attribute to the category for visibility and use that instead of a transformer. e.g.
stages:
-
pipeline: Stage\Extract
args:
extraction: currentCategory::getVisibility()
Assumes getVisibility would return either or search. If it returned an integer then we'd have to map that. see the visibility YAML for products module-m2-indexing-products/etc/pipeline/product/attributes/visibility.yml
See Pipeline Customisation for more information on how to customise pipelines.