Skip to content

Commit 13e8c2d

Browse files
committed
MAGE-644 Add configurable category separator
1 parent 018aeaa commit 13e8c2d

File tree

9 files changed

+46
-19
lines changed

9 files changed

+46
-19
lines changed

Block/Configuration.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ public function getConfiguration()
9494
$level = -1;
9595
foreach ($category->getPathIds() as $treeCategoryId) {
9696
if ($path !== '') {
97-
$path .= ' /// ';
98-
}else{
97+
$path .= $config->getCategorySeparator();
98+
} else {
9999
$parentCategoryName = $categoryHelper->getCategoryName($treeCategoryId, $this->getStoreId());
100100
}
101101

@@ -154,6 +154,7 @@ public function getConfiguration()
154154
'infiniteScrollEnabled' => $config->isInfiniteScrollEnabled(),
155155
'urlTrackedParameters' => $this->getUrlTrackedParameters(),
156156
'isSearchBoxEnabled' => $config->isInstantSearchBoxEnabled(),
157+
'categorySeparator' => $config->getCategorySeparator()
157158
],
158159
'autocomplete' => [
159160
'enabled' => $config->isAutoCompleteEnabled(),
@@ -382,4 +383,4 @@ protected function getLandingPageConfiguration()
382383
{
383384
return $this->isLandingPage() ? $this->getCurrentLandingPage()->getConfiguration() : json_encode([]);
384385
}
385-
}
386+
}

Helper/Adapter/FiltersHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public function getFacetFilters($storeId, $parameters = null)
166166

167167
if ($facet['attribute'] == 'categories') {
168168
$level = '.level' . (count($facetValues) - 1);
169-
$facetFilters[] = $facet['attribute'] . $level . ':' . implode(' /// ', $facetValues);
169+
$facetFilters[] = $facet['attribute'] . $level . ':' . implode($this->config->getCategorySeparator($storeId), $facetValues);
170170

171171
continue;
172172
}

Helper/ConfigHelper.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ConfigHelper
5656
public const CATEGORY_CUSTOM_RANKING = 'algoliasearch_categories/categories/custom_ranking_category_attributes';
5757
public const SHOW_CATS_NOT_INCLUDED_IN_NAV = 'algoliasearch_categories/categories/show_cats_not_included_in_navigation';
5858
public const INDEX_EMPTY_CATEGORIES = 'algoliasearch_categories/categories/index_empty_categories';
59+
public const CATEGORY_SEPARATOR = 'algoliasearch_categories/categories/category_separator';
5960

6061
public const IS_ACTIVE = 'algoliasearch_queue/queue/active';
6162
public const NUMBER_OF_JOB_TO_RUN = 'algoliasearch_queue/queue/number_of_job_to_run';
@@ -1463,6 +1464,15 @@ public function getCategoryAdditionalAttributes($storeId = null)
14631464
return [];
14641465
}
14651466

1467+
/**
1468+
* @param $storeId
1469+
* @return string
1470+
*/
1471+
public function getCategorySeparator($storeId = null): string
1472+
{
1473+
return (string) $this->configInterface->getValue(self::CATEGORY_SEPARATOR, ScopeInterface::SCOPE_STORE, $storeId);
1474+
}
1475+
14661476
/**
14671477
* @param $groupId
14681478
* @return array

Helper/Entity/ProductHelper.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535

3636
class ProductHelper
3737
{
38-
public const CATEGORY_SEPARATOR = ' /// ';
39-
4038
/**
4139
* @var CollectionFactory
4240
*/
@@ -828,10 +826,10 @@ protected function buildCategoryData(Product $product): array
828826
* @param array $paths
829827
* @return array
830828
*/
831-
protected function flattenCategoryPaths(array $paths): array
829+
protected function flattenCategoryPaths(array $paths, int $storeId): array
832830
{
833831
return array_map(
834-
function ($path) { return implode(self::CATEGORY_SEPARATOR, $path); },
832+
function ($path) use ($storeId) { return implode($this->configHelper->getCategorySeparator($storeId), $path); },
835833
$paths
836834
);
837835
}
@@ -845,24 +843,27 @@ function ($path) { return implode(self::CATEGORY_SEPARATOR, $path); },
845843
*/
846844
protected function addCategoryData(array $algoliaData, Product $product): array
847845
{
846+
$storeId = $product->getStoreId();
847+
848848
$categoryData = $this->buildCategoryData($product);
849-
$hierarchicalCategories = $this->getHierarchicalCategories($categoryData['categoriesWithPath']);
849+
$hierarchicalCategories = $this->getHierarchicalCategories($categoryData['categoriesWithPath'], $storeId);
850850
$algoliaData['categories'] = $hierarchicalCategories;
851851
$algoliaData['categories_without_path'] = $categoryData['categoryNames'];
852852
$algoliaData['categoryIds'] = array_values(array_unique($categoryData['categoryIds']));
853853

854-
if ($this->configHelper->isVisualMerchEnabled($product->getStoreId())) {
855-
$algoliaData[$this->configHelper->getCategoryPageIdAttributeName($product->getStoreId())] = $this->flattenCategoryPaths($categoryData['categoriesWithPath']);
854+
if ($this->configHelper->isVisualMerchEnabled($storeId)) {
855+
$algoliaData[$this->configHelper->getCategoryPageIdAttributeName($storeId)] = $this->flattenCategoryPaths($categoryData['categoriesWithPath'], $storeId);
856856
}
857857

858858
return $algoliaData;
859859
}
860860

861861
/**
862-
* @param $categoriesWithPath
862+
* @param array $categoriesWithPath
863+
* @param int $storeId
863864
* @return array
864865
*/
865-
protected function getHierarchicalCategories($categoriesWithPath): array
866+
protected function getHierarchicalCategories(array $categoriesWithPath, int $storeId): array
866867
{
867868
$hierarchicalCategories = [];
868869

@@ -879,7 +880,7 @@ protected function getHierarchicalCategories($categoriesWithPath): array
879880
continue;
880881
}
881882

882-
$hierarchicalCategories[$levelName . $i][] = implode(self::CATEGORY_SEPARATOR, array_slice($category, 0, $i + 1));
883+
$hierarchicalCategories[$levelName . $i][] = implode($this->configHelper->getCategorySeparator($storeId), array_slice($category, 0, $i + 1));
883884
}
884885
}
885886

etc/adminhtml/system.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,19 @@
531531
]]>
532532
</comment>
533533
</field>
534+
<field id="category_separator" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
535+
<label>Category separator</label>
536+
<validate>required-entry</validate>
537+
<comment>
538+
<![CDATA[
539+
The separator is used when serializing category data to your Algolia index and is used to build hierarchical facets and for visual merchandising rules.
540+
You should use a separator that is unlikely to occur within your category data. <strong>Spaces matter!</strong> Default is " /// ".
541+
542+
<br><span class="algolia-config-warning">&#9888;</span> Do not forget to reindex the Algolia Search Products indexer after you've modified this value.
543+
544+
]]>
545+
</comment>
546+
</field>
534547
</group>
535548
</section>
536549
<section id="algoliasearch_recommend" translate="label" type="text" sortOrder="45" showInDefault="1" showInWebsite="1" showInStore="1">

etc/config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<categories>
3535
<category_additional_attributes><![CDATA[{"_1582212881657_657":{"attribute":"name","searchable":"1","order":"unordered","retrievable":"1"},"_1582212904351_351":{"attribute":"path","searchable":"1","order":"unordered","retrievable":"1"},"_1582212910660_660":{"attribute":"meta_title","searchable":"1","order":"unordered","retrievable":"1"},"_1582212915890_890":{"attribute":"meta_keywords","searchable":"1","order":"unordered","retrievable":"1"},"_1582212922533_533":{"attribute":"meta_description","searchable":"1","order":"unordered","retrievable":"1"},"_1582212927307_307":{"attribute":"product_count","searchable":"2","order":"unordered","retrievable":"1"}}]]></category_additional_attributes>
3636
<custom_ranking_category_attributes><![CDATA[{"_1600352142072_72":{"attribute":"product_count","order":"desc"}}]]></custom_ranking_category_attributes>
37+
<category_separator> /// </category_separator>
3738
</categories>
3839
</algoliasearch_categories>
3940
<algoliasearch_personalization>

view/adminhtml/templates/landingpage/search-configuration.phtml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ $isConfig = [
1919
'currencyCode' => $configHelper->getCurrencyCode(),
2020
'maxValuesPerFacet' => (int) $configHelper->getMaxValuesPerFacet(),
2121
'landingPageConfig' => json_decode($landingPage->getConfiguration()),
22+
'categorySeparator' => $configHelper->getCategorySeparator(),
2223
'searchParameters' => [
2324
'query' => $landingPage->getQuery(),
2425
'hitsPerPage' => 10,
@@ -483,7 +484,7 @@ $isConfig = [
483484
var hierarchicalMenuParams = {
484485
container: facet.wrapper.appendChild(createISWidgetContainer(facet.attribute)),
485486
attributes: hierarchical_levels,
486-
separator: ' /// ',
487+
separator: config.categorySeparator,
487488
alwaysGetRootLevel: true,
488489
limit: config.maxValuesPerFacet,
489490
templates: templates,

view/frontend/web/instantsearch.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ requirejs(['algoliaBundle', 'Magento_Catalog/js/price-utils'], function (algolia
271271
item.label = attribute.label;
272272
item.refinements.forEach(function (refinement) {
273273
if (refinement.type !== 'hierarchical') return refinement;
274-
var levels = refinement.label.split('///');
274+
var levels = refinement.label.split(algoliaConfig.instant.categorySeparator);
275275
var lastLevel = levels[levels.length - 1];
276276
refinement.label = lastLevel;
277277
});
@@ -430,7 +430,7 @@ requirejs(['algoliaBundle', 'Magento_Catalog/js/price-utils'], function (algolia
430430
var hierarchicalMenuParams = {
431431
container: facet.wrapper.appendChild(createISWidgetContainer(facet.attribute)),
432432
attributes: hierarchical_levels,
433-
separator: ' /// ',
433+
separator: algoliaConfig.instant.categorySeparator,
434434
templates: templates,
435435
alwaysGetRootLevel: false,
436436
showParentLevel:false,
@@ -670,4 +670,4 @@ requirejs(['algoliaBundle', 'Magento_Catalog/js/price-utils'], function (algolia
670670

671671
return options;
672672
}
673-
});
673+
});

view/frontend/web/internals/common.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ requirejs(['algoliaBundle'], function(algoliaBundle) {
404404
if (algoliaConfig.isLandingPage &&
405405
typeof uiStateProductIndex['hierarchicalMenu']['categories.level0'] === 'undefined' &&
406406
'categories.level0' in landingPageConfig) {
407-
uiStateProductIndex['hierarchicalMenu']['categories.level0'] = landingPageConfig['categories.level0'].split(' /// ');
407+
uiStateProductIndex['hierarchicalMenu']['categories.level0'] = landingPageConfig['categories.level0'].split(algoliaConfig.instant.categorySeparator);
408408
}
409409
}
410410
if (currentFacet.attribute == 'categories' && algoliaConfig.isCategoryPage) {

0 commit comments

Comments
 (0)