We want a filter in layered navigation that filters for new products. Our idea is to base it on the magento default attributes news_from_date and news_to_date. I found an example in the wiki under Query Filters. But what is a good way to implement it?
Hello @DanieliMi,
There are several steps if you want to take inspiration on the wiki page you mentioned.
A "by the book" approach is a bit complex...
A filter in the layered navigation is represented by two components : a layer filter model and its layer filter renderer (in M1, it was a block)
The layer filter renderers are children block of the layer Navigation block and displays what the layer filters pulls from the DB/ElasticSearch.
Usually (native ES or Solr implementation), the layer filter model has three tasks :
layer state block In ElasticSuite, it's slightly different, but not by much :
is_filterable = 1 or is_filterable_in_search = 1) are aggregations that are automatically added to the ES request by providers, so it's not longer the job of the filter models to do itvendor/smile/elasticsuite/src/module-elasticsuite-catalog/etc/elasticsuite_search_request.xmlfor aggregations/provider nodesattribute_set_id being added to search (quick_search_container request) and catalog navigation (catalog_view_container).is_new custom aggregation there.\Smile\ElasticsuiteCore\Search\Request\Aggregation\Bucket\QueryGroup bucket aggregation type (but I'm not 100% sure).\Smile\ElasticsuiteCatalog\Block\Navigation::getFilters (\Magento\LayeredNavigation\Block\Navigation::getFilters) to inject your layer filter model because it will not be returned by the filter list modelsThe trickiest part will be the filter model in itself :
\Smile\ElasticsuiteCatalog\Model\Layer\Filter\Attribute / \Smile\ElasticsuiteCatalog\Model\Layer\Filter\Boolean but might not be able to extend those classes because you will not have an attribute per se.\Magento\Catalog\Model\Layer\Filter\AbstractFilter::getAttributeModel will throw an exception, but on the other hand, you're not supposed to need the behavior of \Smile\ElasticsuiteCatalog\Model\Layer\Filter\Attribute::getFilterField : etc/elasticsuite_search_request.xml, so \Smile\ElasticsuiteCatalog\Model\Layer\Filter\Attribute::_getItemsData could be made to work\Smile\ElasticsuiteCatalog\Model\Layer\Filter\Boolean and \Smile\ElasticsuiteCatalog\Model\Layer\Filter\Category to write the apply and _getItemsData methods (having toyed with layered navigation filters in M1 is a plus)$productCollection->addFieldToFilter($this->getFilterField(), $attributeValue); is out of question$this->getLayer()->getProductCollection()->addQueryFilter)We do not provide (yet) the functionnality of "Virtual Attributes" that were written for the M1 version of the module, if we did, you would have had a lot less code to write.
I'll try to think about an alternative way of doing things (adding a filterable + frontendInput=hidden "is_new" real product attribute + tweaking the models to select the specific filter model/renderer).
Regards
Closed as being answered
So, we added our filter via a custom plugin with elasticsuite_search_request.xml. The filter works pretty good, however, we're having trouble to add it to the layered navigation. We tried plugging Smile\ElasticsuiteCatalog\Block\Navigation::getFilters, but it looks like getFilters returns an array of filter items which are strictly tied to attributes, which we don't have.
We tried something like this:
private function createAttribute()
{
$filter = $this->filterItemFactory->create()
//->setFilter($this)
->setLabel('New Product')
->setValue(1)
->setCount(0);
$layer = $this->getLayer()->getState()->addFilter($filter);
return $this->objectManager->create(
Attribute::class,
['data' => ['attribute_model' => null], 'layer' => $layer]
);
}
Do you have an idea how to add a filter without an eav attribute?
@rbayet Do you maybe have an idea for a solution?
For our Filter we used so \Smile\ElasticsuiteCore\Api\Search\Request\Container\FilterInterface so far I think that's a point we need to change to add it to \Smile\ElasticsuiteCatalog\Block\Navigation::getFilters