├── .gitignore ├── LICENSE.txt ├── Observer ├── UpdateFrontendConfiguration.php └── UpdateProductsSettings.php ├── README.md ├── composer.json ├── etc ├── events.xml └── module.xml ├── registration.php └── view └── frontend ├── layout └── algolia_search_handle.xml ├── requirejs-config.js ├── templates └── instant │ └── facet.phtml └── web ├── css └── customalgolia.css └── js ├── autocomplete-mixin.js ├── hooks.js ├── instantsearch-mixin.js ├── internals ├── common-mixin.js └── template-engine-mixin.js ├── lib ├── algolia-instantsearch.local.min.js └── autocomplete-plugin-recent-searches.js └── template └── autocomplete ├── additional-section-mixin.js ├── categories-mixin.js ├── pages-mixin.js ├── products-mixin.js └── suggestions-mixin.js /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor/ 3 | .vscode 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Algolia 4 | http://www.algolia.com/ 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /Observer/UpdateFrontendConfiguration.php: -------------------------------------------------------------------------------- 1 | getData('configuration'); 23 | // $configuration['foo'] = 'bar'; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Observer/UpdateProductsSettings.php: -------------------------------------------------------------------------------- 1 | getData('index_settings'); 23 | // $productsSettings['foo'] = 'bar'; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Custom boilerplate module to extend Algolia Magento 2 module 2 | 3 | [Magento 2](https://magento.com/) module for easy extension of [Algolia's Magento 2 module](https://github.com/algolia/algoliasearch-magento-2). 4 | 5 | ## Guides 6 | 7 | - [Backend custom events](https://community.algolia.com/magento/doc/m2/backend/) 8 | - [Frontend custom events](https://community.algolia.com/magento/doc/m2/frontend-events/) 9 | 10 | ## Installation 11 | 12 | The template module can be installed via [Composer](https://getcomposer.org/): 13 | 14 | ```sh 15 | $ cd /path/to/your/magento2/directory 16 | $ composer require algolia/algoliasearch-custom-algolia-magento-2 17 | $ php bin/magento setup:upgrade 18 | ``` 19 | 20 | > Please note that this is a starter module. Composer will install this code to your local `app/code` directory where you can make further modifications to the implementation and commit to your own project repository. 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algolia/algoliasearch-custom-algolia-magento-2", 3 | "description": "Custom boilerplate module to extend Algolia Magento 2 extension", 4 | "type": "magento2-module", 5 | "license": [ 6 | "MIT" 7 | ], 8 | "version": "1.4.0", 9 | "require": { 10 | "algolia/algoliasearch-magento-2": "^3.15.0", 11 | "magento/magento-composer-installer": "*" 12 | }, 13 | "extra": { 14 | "map": [ 15 | [ 16 | "*", 17 | "Algolia/CustomAlgolia" 18 | ] 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /etc/events.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /view/frontend/requirejs-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Documentation: https://www.algolia.com/doc/integration/magento-2/customize/autocomplete-menu 3 | **/ 4 | 5 | /** 6 | * This starter file provides a means to override the Algolia search experience using RequireJS. 7 | * 8 | * You can customize Algolia's JavaScript in one of 3 ways: 9 | * 1. Via a complete override of the underlying dependency 10 | * 2. Via a JavaScript mixin (recommended especially for templates) 11 | * 3. Via front end custom events (hooks.js is included to demonstrate how to handle custom front end events) 12 | */ 13 | const config = { 14 | map: { 15 | "*": { 16 | // Include your own hooks to handle front end events - see https://www.algolia.com/doc/integration/magento-2/customize/custom-front-end-events/ 17 | algoliaHooks: 'Algolia_CustomAlgolia/js/hooks', 18 | 19 | // Add any dependencies you might need for your own customizations 20 | // For instance, this lib supplies the "recent searches" plugin 21 | // How this might be used is demonstrated in hooks.js using the `afterAutocompletePlugins` event 22 | algoliaRecentSearchesPluginLib: 'Algolia_CustomAlgolia/js/lib/autocomplete-plugin-recent-searches', 23 | 24 | //////////////////////////////////// 25 | // ALGOLIA FRONTEND LIB OVERRIDE // 26 | //////////////////////////////////// 27 | 28 | // Uncomment to load your own specific version of InstantSearch e.g. 4.65.0 29 | // algoliaInstantSearchLib: 'Algolia_CustomAlgolia/js/lib/algolia-instantsearch.local.min', 30 | 31 | /** 32 | * This can be done for other libraries as well such as Autocomplete, Recommend etc. 33 | * Check the `lib` directory in the core module for versioned dependency source files 34 | */ 35 | 36 | //////////////////////////////////// 37 | // AUTOCOMPLETE TEMPLATE OVERRIDE // 38 | //////////////////////////////////// 39 | 40 | // Uncomment the following line to override the products.js functional template 41 | // productsHtml: 'Algolia_CustomAlgolia/js/internals/template/autocomplete/products' 42 | }, 43 | }, 44 | 45 | config: { 46 | // Use mixins where possible to only override *specific functions* within the Algolia implementation 47 | // This makes upgrades easier in the future since you will not have to merge all changes into your template overrides 48 | mixins: { 49 | ////////////////////////////////// 50 | // AUTOCOMPLETE TEMPLATE MIXINS // 51 | ////////////////////////////////// 52 | 53 | /** 54 | * You can add a mixin to customize only a single portion of a template based on the corresponding function. 55 | * Use the `html` tagged template literal supplied via the function arguments to return your custom content as HTML. 56 | */ 57 | 58 | // Uncomment the following mixins to override the hit template via a JavaScript mixin for a given source 59 | // "Algolia_AlgoliaSearch/js/template/autocomplete/products": { 60 | // "Algolia_CustomAlgolia/js/template/autocomplete/products-mixin": true, 61 | // }, 62 | // "Algolia_AlgoliaSearch/js/template/autocomplete/categories": { 63 | // "Algolia_CustomAlgolia/js/template/autocomplete/categories-mixin": true, 64 | // }, 65 | // "Algolia_AlgoliaSearch/js/template/autocomplete/pages": { 66 | // "Algolia_CustomAlgolia/js/template/autocomplete/pages-mixin": true, 67 | // }, 68 | // "Algolia_AlgoliaSearch/js/template/autocomplete/additional-section": { 69 | // "Algolia_CustomAlgolia/js/template/autocomplete/additional-section-mixin": true, 70 | // }, 71 | // "Algolia_AlgoliaSearch/js/template/autocomplete/suggestions": { 72 | // "Algolia_CustomAlgolia/js/template/autocomplete/suggestions-mixin": true, 73 | // }, 74 | 75 | ////////////////////////////////// 76 | // OTHER AUTOCOMPLETE MIXINS // 77 | ////////////////////////////////// 78 | 79 | // Uncomment the following mixin to see a demonstration of how you can modify the logic behind how Autocomplete functions 80 | // "Algolia_AlgoliaSearch/js/autocomplete": { 81 | // "Algolia_CustomAlgolia/js/autocomplete-mixin": true, 82 | // }, 83 | 84 | ////////////////////////////////// 85 | // INSTANTSEARCH MIXINS // 86 | ////////////////////////////////// 87 | 88 | // Uncomment the following mixin to see a demonstration of how you can modify the logic behind how InstantSearch functions 89 | // Some examples include: Changing runtime behaviors and adding libraries to the algoliaBundle used in legacy front end hooks 90 | // "Algolia_AlgoliaSearch/js/instantsearch": { 91 | // "Algolia_CustomAlgolia/js/instantsearch-mixin": true, 92 | // }, 93 | 94 | ////////////////////////////////// 95 | // INTERNAL LIB MIXINS // 96 | ////////////////////////////////// 97 | 98 | // Uncomment the following mixin to change the template parsing engine from Mustache to Hogan 99 | // "Algolia_AlgoliaSearch/js/internals/template-engine": { 100 | // "Algolia_CustomAlgolia/js/internals/template-engine-mixin": true, 101 | // }, 102 | 103 | // Uncomment the following mixin to change the behavior of common util functions 104 | // "Algolia_AlgoliaSearch/js/internals/common": { 105 | // "Algolia_CustomAlgolia/js/internals/common-mixin": true, 106 | // }, 107 | }, 108 | } 109 | }; 110 | -------------------------------------------------------------------------------- /view/frontend/templates/instant/facet.phtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /view/frontend/web/css/customalgolia.css: -------------------------------------------------------------------------------- 1 | /* Define your custom CSS here */ -------------------------------------------------------------------------------- /view/frontend/web/js/autocomplete-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE AUTOCOMPLETE MIXIN 2 | // These mixins demonstrate ways that you can override behaviors and configurations in the core Autocomplete implementation 3 | 4 | define(['uiComponent'], function (Component) { 5 | "use strict"; 6 | 7 | return function (target) { 8 | const mixin = { 9 | initialize: function () { 10 | this._super(); 11 | console.log("The original debounce was:", target.prototype.DEBOUNCE_MS); 12 | console.log("The updated debounce is:", this.DEBOUNCE_MS); 13 | 14 | console.log("The original minimum characters before search was:", target.prototype.MIN_SEARCH_LENGTH_CHARS); 15 | console.log("The updated minimum characters before search is:", this.MIN_SEARCH_LENGTH_CHARS); 16 | 17 | }, 18 | // Set debounce to 600ms 19 | DEBOUNCE_MS: 600, 20 | // Set minimum number of characters before search to 5 21 | MIN_SEARCH_LENGTH_CHARS: 5, 22 | 23 | handleAutocompleteStateChange: function(state) { 24 | console.log("In mixin to listen to changes to Autocomplete state:", state); 25 | } 26 | }; 27 | 28 | return target.extend(mixin); 29 | }; 30 | }); 31 | -------------------------------------------------------------------------------- /view/frontend/web/js/hooks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Documentation: https://www.algolia.com/doc/integration/magento-2/customize/custom-front-end-events/ 3 | **/ 4 | 5 | /** 6 | * NOTE: This module is for demonstration purposes only and is intended to show how front end event hooks might be used. 7 | * Be mindful that introducing things like new sources and plugins can affect the layout of your final render. 8 | * Utilize DOM or CSS to control the final presentation as needed. 9 | **/ 10 | 11 | /** 12 | * Inject your dependencies as needed 13 | * e.g. algoliaRecentSearchesPluginLib are only supplied for demonstration of inclusion of the recent searches plugin 14 | * You can specify additional dependencies via your local module's requirejs-config.js 15 | */ 16 | define([ 17 | 'jquery', 18 | 'algoliaCommon', 19 | 'algoliaInstantSearchLib', // inject core Algolia frontend libraries as needed 20 | 'algoliaQuerySuggestionsPluginLib', 21 | 'algoliaAutocompleteSuggestionsHtml', 22 | 'algoliaRecentSearchesPluginLib' 23 | ], function ( 24 | $, 25 | algolia, 26 | instantsearch, 27 | querySuggestionsPlugin, 28 | suggestionsHtml, 29 | algoliaRecentSearches 30 | ) { 31 | 32 | ////////////////////////////////// 33 | // AUTOCOMPLETE HOOKS // 34 | ////////////////////////////////// 35 | 36 | /** 37 | * Autocomplete documentation: https://github.com/algolia/autocomplete 38 | */ 39 | 40 | algolia.registerHook( 41 | "afterAutocompleteSources", 42 | (sources, searchClient) => { 43 | console.log("In hook method to modify Autocomplete data sources"); 44 | 45 | // Use the global window variable `algoliaConfig` to see what has been configured in the system configuration 46 | console.log("Algolia config:", algoliaConfig); 47 | 48 | // Modify autocomplete data sources 49 | 50 | /* 51 | // Add new source 52 | sources.push({ 53 | sourceId : "custom-source", 54 | // Use algoliaConfig.indexName to utilize index prefix by store scope 55 | indexName: // algoliaConfig.indexName + '_', 56 | options : {hitsPerPage: 3}, 57 | // templates: null, 58 | templates: { 59 | noResults() { 60 | return "No results found"; 61 | }, 62 | header() { 63 | return 'CUSTOM SOURCE'; 64 | }, 65 | item({item, html}) { 66 | console.log("Your custom item:", item); 67 | return html`${item.label}`; 68 | } 69 | } 70 | }); 71 | */ 72 | 73 | // modify an existing source 74 | // const pages = sources.find(source => source.sourceId === 'pages'); 75 | // console.log("Pages:", pages); 76 | 77 | return sources; 78 | } 79 | ); 80 | 81 | algolia.registerHook( 82 | 'afterAutocompletePlugins', 83 | (plugins, searchClient) => { 84 | console.log("In hook method to modify Autocomplete plugins"); 85 | 86 | // Modify an existing plugin like Query Suggestions (use Algolia instead of Magento) 87 | // See https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js/ 88 | /* 89 | const pluginIndex = plugins.findIndex(plugin => plugin.name === 'aa.querySuggestionsPlugin'); 90 | if (pluginIndex > -1) { 91 | // Replace the entire plugin 92 | plugins[pluginIndex] = querySuggestionsPlugin.createQuerySuggestionsPlugin({ 93 | searchClient, 94 | // Build your suggestions index per https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js/#implementing-query-suggestions 95 | indexName: '', 96 | getSearchParams() { 97 | return {hitsPerPage: algoliaConfig.autocomplete.nbOfProductsSuggestions}; 98 | }, 99 | transformSource({source}) { 100 | return { 101 | ...source, 102 | getItemUrl({item}) { 103 | return algoliaConfig.resultPageUrl + `?q=${item.query}`; 104 | }, 105 | templates: { 106 | noResults({html}) { 107 | return suggestionsHtml.getNoResultHtml({html}); 108 | }, 109 | header({html, items}) { 110 | return suggestionsHtml.getHeaderHtml({html}); 111 | }, 112 | item({item, components, html}) { 113 | return suggestionsHtml.getItemHtml({item, components, html}) 114 | }, 115 | footer({html, items}) { 116 | return suggestionsHtml.getFooterHtml({html}) 117 | }, 118 | }, 119 | }; 120 | }, 121 | }); 122 | } 123 | */ 124 | 125 | // Install a new plugin like "recent searches" 126 | // See: https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-recent-searches/createLocalStorageRecentSearchesPlugin/ 127 | /* 128 | const recentSearchesPlugin = algoliaRecentSearches.createLocalStorageRecentSearchesPlugin({ 129 | key: 'navbar', 130 | transformSource({source}) { 131 | return { 132 | ...source, 133 | templates: { 134 | ...source.templates, 135 | header: () => 'Recent searches', 136 | item: ({item, html}) => { 137 | // console.log("Item:", item); 138 | return html`${item.label}`; 139 | } 140 | } 141 | } 142 | } 143 | }); 144 | */ 145 | 146 | // Replace existing plugins completely (e.g. to replace query suggestions) 147 | // return [recentSearchesPlugin]; 148 | 149 | // or add to existing plugins (requires additional front end formatting via CSS etc.) 150 | // plugins.unshift(recentSearchesPlugin); 151 | 152 | return plugins; 153 | } 154 | ); 155 | 156 | algolia.registerHook( 157 | "afterAutocompleteOptions", 158 | (options) => { 159 | console.log("In hook method to modify Autocomplete options"); 160 | 161 | // Modify autocomplete options 162 | // options.openOnFocus = true; 163 | 164 | return options; 165 | } 166 | ); 167 | 168 | ////////////////////////////////// 169 | // INSTANTSEARCH HOOKS // 170 | ////////////////////////////////// 171 | 172 | /** 173 | * InstantSearch hook methods 174 | * IS.js v4 documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/ 175 | **/ 176 | 177 | algolia.registerHook( 178 | "beforeInstantsearchInit", 179 | function (instantsearchOptions) { 180 | console.log("In method to modify InstantSearch options"); 181 | 182 | // Modify instant search options 183 | // console.log("InstantSearch options:", instantsearchOptions); 184 | 185 | return instantsearchOptions; 186 | } 187 | ); 188 | 189 | algolia.registerHook( 190 | "beforeWidgetInitialization", 191 | function (allWidgetConfiguration, algoliaBundle) { 192 | console.log("In hook method to modify InstantSearch widgets"); 193 | 194 | // Here you can modify the instant search widgets configuration before InstantSearch is initialized 195 | 196 | // For instance uncomment the following to see how you can easily modify the standard price slider 197 | // const rangeSlider = allWidgetConfiguration.rangeSlider[0]; 198 | // rangeSlider.panelOptions.templates.header = `
Price [This is a custom header]
`; 199 | // rangeSlider.panelOptions.templates.footer = "[This is a custom footer]"; 200 | 201 | // The algoliaBundle has been discontinued in the core extension and its use in frontend hooks is accordingly deprecated 202 | // If the bundle is still needed, a lightweight version can be accessed in 3.15.0 203 | // console.log("Algolia bundle:", algoliaBundle); 204 | 205 | return allWidgetConfiguration; 206 | } 207 | ); 208 | 209 | algolia.registerHook( 210 | "beforeInstantsearchStart", 211 | function (search) { 212 | console.log( 213 | "In hook method to modify the InstantSearch instance before search has started" 214 | ); 215 | 216 | // Modify instant search instance before search started 217 | // For instance you can add a secondary set of hits to your InstantSearch UI 218 | // search.addWidgets([ 219 | // instantsearch.widgets.hits({ 220 | // container: '#custom-second-hits', // This element must be present in the DOM - can be added via wrapper.phtml 221 | // }) 222 | // ]); 223 | 224 | return search; 225 | } 226 | ); 227 | 228 | algolia.registerHook( 229 | "afterInstantsearchStart", 230 | function (search) { 231 | console.log( 232 | "In hook method to modify the InstantSearch instance after search has started" 233 | ); 234 | 235 | // Modify instant search instance after search started 236 | 237 | return search; 238 | } 239 | ); 240 | }); 241 | -------------------------------------------------------------------------------- /view/frontend/web/js/instantsearch-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE INSTANTSEARCH MIXIN 2 | // These mixins demonstrate ways that you can override behaviors and configurations in the core InstantSearch implementation 3 | // More mixin support to come... 4 | 5 | define(['algoliaHoganLib'], function (Hogan) { 6 | "use strict"; 7 | 8 | return function (target) { 9 | const mixin = { 10 | // Demonstrates how to load legacy bundle with additional libs for older front end hook API 11 | mockAlgoliaBundle: function () { 12 | console.log("Customizing the algoliaBundle..."); 13 | const algoliaBundle = this._super(); 14 | algoliaBundle.Hogan = Hogan; 15 | return algoliaBundle; 16 | }, 17 | 18 | /** 19 | * Demonstrates how to modify params like typo tolerance at runtime via the InstantSearch configure widget 20 | * https://www.algolia.com/doc/api-reference/search-api-parameters/ 21 | */ 22 | getSearchParameters: function () { 23 | const searchParameters = this._super(); 24 | searchParameters.typoTolerance = false; 25 | return searchParameters; 26 | } 27 | }; 28 | 29 | return target.extend(mixin); 30 | }; 31 | }); 32 | -------------------------------------------------------------------------------- /view/frontend/web/js/internals/common-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE COMMON LIB MIXIN 2 | // These mixins demonstrate ways that you can modify the behavior of core utility libraries that Algolia uses under the hood 3 | 4 | define(function () { 5 | "use strict"; 6 | 7 | return function (target) { 8 | const mixin = { 9 | isMobile() { 10 | console.log("Mobile user agent?", target.isMobileUserAgent()); 11 | console.log("Touch device?", target.isTouchDevice()); // This example implementation ignores this criteria for isMobile 12 | return target.isMobile(); 13 | }, 14 | 15 | getCookie(name) { 16 | // Here you can hook into how cookies are retrieved for the Algolia extension 17 | console.log("Retrieving cookie:", name); 18 | return target.getCookie(); 19 | } 20 | }; 21 | 22 | return { ...target, ...mixin }; 23 | }; 24 | }); 25 | -------------------------------------------------------------------------------- /view/frontend/web/js/internals/template-engine-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE TEMPLATE ENGINE MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | return function (target) { 6 | const mixin = { 7 | getSelectedEngineType: function () { 8 | return target.ENGINE_TYPE_HOGAN; 9 | }, 10 | }; 11 | 12 | return { ...target, ...mixin }; 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /view/frontend/web/js/lib/autocomplete-plugin-recent-searches.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Skipped minification because the original files appears to be already minified. 3 | * Original file: /npm/@algolia/autocomplete-plugin-recent-searches@1.8.3/dist/umd/index.production.js 4 | * 5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files 6 | */ 7 | /*! @algolia/autocomplete-plugin-recent-searches 1.8.3 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */ 8 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@algolia/autocomplete-plugin-recent-searches"]={})}(this,(function(e){"use strict";function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(e){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return Array.isArray(u.current)?n(n({},r),{},{facetFilters:[].concat(o(null!==(e=r.facetFilters)&&void 0!==e?e:[]),o(u.current.map((function(e){return["objectID:-".concat(e.label)]})))),hitsPerPage:Math.max(1,(null!==(t=r.hitsPerPage)&&void 0!==t?t:10)-u.current.length)}):r}}),__autocomplete_pluginOptions:e}}function g(e){var t=e.query,n=e.items,r=e.limit;return t?n.filter((function(e){return e.label.toLowerCase().includes(t.toLowerCase())})).slice(0,r).map((function(e){return i({item:e,query:t})})):n.slice(0,r).map((function(e){return i({item:e,query:t})}))}function v(e){return n({limit:5,search:g,transformSource:function(e){return e.source}},e)}e.addHighlightedAttribute=i,e.createLocalStorageRecentSearchesPlugin=function(e){var t=v(e),r=t.key,a=t.limit,i=t.transformSource,u=t.search,s=t.subscribe,m=function(e){var t=e.key,n=e.limit,r=e.search,a=l({key:t});return{onAdd:function(e){a.setItem([e].concat(o(a.getItem())))},onRemove:function(e){a.setItem(a.getItem().filter((function(t){return t.id!==e})))},getAll:function(){return r({query:arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",items:a.getItem(),limit:n}).slice(0,n)}}}({key:[c,r].join(":"),limit:a,search:u});return n(n({},f({transformSource:i,storage:m,subscribe:s})),{},{name:"aa.localStorageRecentSearchesPlugin",__autocomplete_pluginOptions:e})},e.createRecentSearchesPlugin=f,e.getTemplates=s,e.search=g,Object.defineProperty(e,"__esModule",{value:!0})})); 9 | //# sourceMappingURL=index.production.js.map 10 | -------------------------------------------------------------------------------- /view/frontend/web/js/template/autocomplete/additional-section-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE ADDITIONAL SECTION MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | const mixin = { 6 | getHeaderHtml: function ({ section }) { 7 | return `This ${section.name} template was customized!`; 8 | }, 9 | }; 10 | 11 | return function (target) { 12 | return { ...target, ...mixin }; 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /view/frontend/web/js/template/autocomplete/categories-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE CATEGORIES MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | const mixin = { 6 | getHeaderHtml: function () { 7 | return "This category template was customized!"; 8 | }, 9 | }; 10 | 11 | return function (target) { 12 | return { ...target, ...mixin }; 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /view/frontend/web/js/template/autocomplete/pages-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE PAGES MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | const mixin = { 6 | getHeaderHtml: function () { 7 | return "This page template was customized!"; 8 | }, 9 | }; 10 | 11 | return function (target) { 12 | return { ...target, ...mixin }; 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /view/frontend/web/js/template/autocomplete/products-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE PRODUCT MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | const mixin = { 6 | getHeaderHtml: function () { 7 | return "This product template was customized!"; 8 | }, 9 | 10 | getItemHtml: function ({item, components, html}) { 11 | // Take first SKU on configurable / bundle / group 12 | const sku = Array.isArray(item.sku) && item.sku.length ? item.sku[0] : item.sku; 13 | return html` 19 |
20 | ${item.name || 21 |
22 |
23 | ${components.Highlight({hit: item, attribute: "name"})} 24 | 25 | 26 | 27 |
${sku}
28 | 29 | 30 |
31 | ${this.getColorHtml(item, components, html)} 32 | ${this.getCategoriesHtml(item, components, html)} 33 |
34 | 35 | ${this.getPricingHtml(item, html)} 36 |
37 |
`; 38 | }, 39 | }; 40 | 41 | return function (target) { 42 | return {...target, ...mixin}; 43 | }; 44 | }); 45 | -------------------------------------------------------------------------------- /view/frontend/web/js/template/autocomplete/suggestions-mixin.js: -------------------------------------------------------------------------------- 1 | // SAMPLE SUGGESTIONS MIXIN 2 | define(function () { 3 | "use strict"; 4 | 5 | const mixin = { 6 | getHeaderHtml: function () { 7 | return "This suggestions template was customized!"; 8 | }, 9 | }; 10 | 11 | return function (target) { 12 | return { ...target, ...mixin }; 13 | }; 14 | }); 15 | --------------------------------------------------------------------------------