Common Customisations
Using Text Attributes as Klevu Facets
13 min
the klevu indexing functionality respects and uses core magento settings wherever possible when defining klevu attributes from magento data, we reference the “use in layered navigation” field when setting the filterable property unfortunately, there are types of magento attributes which cannot be defined for use in layered navigation which are still valid klevu facets for example, text attributes (as klevu generates its own enumerated index as part of the indexing process) example of magento select field attribute example of magento text field attribute where changes to automatically populated klevu attribute properties is required, we need to extend the core klevu functionality with a small bespoke module these changes can also be incorporated into existing customisation modules, though we recommend keeping customisations separate to allow easier maintenance, debugging, and removal if required building the extension this guide assumes you are familiar with creating a magento 2 extension if you work better with code in front of you to reference, there is an example module at the end of the article important this example module is not production ready and should not be used it is for reference and illustration purposes only and no guarantee is made to its reliability we strongly recommend testing it in your own environment before deploying it to production we will use the module name vendor klevuindexingattributedefinitions ; you should choose a namespace (and module name) suited to your installation dependencies we will reference the klevu indexing products and php sdk packages, so ensure you include the following in the extension’s composer json file composer json "require" { "php" " 8 1 0| 8 2 0| 8 3 0| 8 4 0", "klevu/module m2 indexing products" "^3 0 0", "klevu/php sdk" "^1 1 0" }, and the following in the extension’s etc/module xml file etc/module xml \<sequence> \<module name="klevu indexingproducts"/> \<module name="klevu phpsdk"/> \</sequence> overriding the attribute definition to implement our changes, we need to modify the klevu\indexingproducts\service\attributeindexingrecordcreatorservice return; this is the service responsible for converting a magento eav attribute into an object which can be used by the sdk to register attributes in klevu reference klevu/module m2 indexing products we’re simply going to take the sdk attribute and update its properties before it’s used by other parts of the system as such, we need to add an after plugin on the execute method, using the following di xml code (while you could add this to the adminhtml area, it’s safest to add it globally to ensure future compatibility) \<type name="klevu\indexingproducts\service\attributeindexingrecordcreatorservice"> \<plugin name="vendor klevuindexingattributedefinitions indexingproducts updateattributedefinitionplugin" type="vendor\klevuindexingattributedefinitions\plugin\indexingproducts\service\attributeindexingrecordcreatorservice\updateattributedefinitionplugin"/> \</type> our plugin will then need an afterexecute method to receive and modify the data; that class' skeleton should look something like plugin/ /updateattributedefinitionplugin php \<?php / this is a demonstration module provided by klevu with no guarantees, active support, or planned updates it should be used as a base to create your own extension implementing the specific functionality required for your installation, rather than being directly installed as an out of the box solution / declare(strict types=1); namespace vendor\klevuindexingattributedefinitions\plugin\indexingproducts\service\attributeindexingrecordcreatorservice; use klevu\indexingproducts\service\attributeindexingrecordcreatorservice; use klevu\phpsdk\api\model\indexing\attributeinterface as sdkattributeinterface; use magento\eav\api\data\attributeinterface; class updateattributedefinitionplugin { / @param attributeindexingrecordcreatorservice $subject @param sdkattributeinterface $result @param attributeinterface $attribute @param string $apikey @return sdkattributeinterface / public function afterexecute( attributeindexingrecordcreatorservice $subject, sdkattributeinterface $result, attributeinterface $attribute, string $apikey, // phpcs\ ignore slevomatcodingstandard functions unusedparameter unusedparameter ) sdkattributeinterface { // your modifications here return $result } } unless you want to change every registered attribute (bad idea), you will need a way of identifying which attribute you are currently dealing with the easiest and most reliable way is to use the magento attribute code, available via the $attribute variable ; eg switch ($attribute >getattributecode()) { case 'my text attribute' case 'another text attribute' // changes here break; } alternatively, you can retrieve the attribute code as it will be registered in klevu (ie, what you see in kmc) this value is usually the same as the magento attribute code, however it will differ if mapping has been performed reference klevu\indexingapi\service\mapper\magentotoklevuattributemapperinterface get called in attributeindexingrecordcreatorservice getattributename switch ($attribute >getattributecode()) { case 'klv text attribute' case 'klv text attribute2' // changes here break; } to modify the sdk attribute’s data (in this case, we will target the filterable property, but you can modify any sdk attribute property supported by the sdk), you need to set the value on $return prior to returning it back to the calling code while we should be able to rely on receiving an instance of the sdk indexing attribute model, we only stipulate the attributeinterface which does not mandate setters for properties as such, we should feature sniff before setting any values reference klevu\phpsdk\api\model\indexing\attributeinterface example preferred method public function afterexecute( attributeindexingrecordcreatorservice $subject, sdkattributeinterface $result, attributeinterface $attribute, string $apikey, // phpcs\ ignore slevomatcodingstandard functions unusedparameter unusedparameter ) sdkattributeinterface { switch ($result >getattributename()) { case 'klv text attribute' case 'klv text attribute2' if (method exists($result, 'setfilterable')) { // you could log if the method doesn't exist, but that should be // pretty obvious during development $result >setfilterable(true); } break; } return $return; } if you are dealing with an implementation of the sdk attributeinterface which does not have setters including trying to set attribute name or data type on klevu\phpsdk\model\indexing\attribute you will need to replace $return with a new instance and return that instance example 2 alternative implementation, using setters is preferred use klevu\phpsdk\model\indexing\attribute as sdkattribute; use klevu\phpsdk\model\indexing\attributefactory as sdkattributefactory; use klevu\phpsdk\model\indexing\datatype; class updateattributedefinitionplugin { private readonly sdkattributefactory $attributefactory; public function afterexecute( attributeindexingrecordcreatorservice $subject, sdkattributeinterface $result, attributeinterface $attribute, string $apikey, // phpcs\ ignore slevomatcodingstandard functions unusedparameter unusedparameter ) sdkattributeinterface { switch ($result >getattributename()) { case 'klv text attribute' case 'klv text attribute2' $result = $this >attributefactory >create( data \[ // you can change any of the attributes used to register the attribute sdkattribute field attribute name => $result >getattributename(), // including the data type sdkattribute field datatype => datatype number, // and just set any you don't wish to change to the existing value sdkattribute field label => $result >getlabel(), sdkattribute field searchable => false, sdkattribute field filterable => true, sdkattribute field returnable => $result >isreturnable(), sdkattribute field abbreviate => $result >isabbreviate(), sdkattribute field rangeable => true, ], ); break; } } } and that should be all the required changes, and you can recompile your magento installation at this point, the next time an attribute is modified and the attribute discovery process runs, your changes will be applied you can force this by either changing something in the attribute in the magento admin, or running an attribute update for all or some attributes via cli for example, to update product attributes with magento ids 1, 2, and 3 run /var/www/html$ php bin/magento klevu\ indexing\ attribute update attribute ids 1,2,3 attribute type klevu product example module vendor klevuindexingattributedefinitions on github further reading klevu custom attributes (indexing apis) registering attributes that are not magento attributes (klevu magento v4) attributes (klevu magento v4) add, update, or delete indexing attributes (klevu php sdk) managing attributes (klevu php sdk)