workarea 3.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +326 -0
- data/CHANGELOG.md +20501 -0
- data/README.md +163 -0
- data/docker-compose.yml +27 -0
- data/docs/Gemfile +8 -0
- data/docs/bin/middleman +29 -0
- data/docs/config.rb +87 -0
- data/docs/config.ru +7 -0
- data/docs/data/articles.yml +157 -0
- data/docs/package.json +15 -0
- data/docs/source/404.html.erb +13 -0
- data/docs/source/articles/access-routes-in-javascript.html.md +33 -0
- data/docs/source/articles/add-a-content-area.html.md +169 -0
- data/docs/source/articles/add-a-content-block-type.html.md +334 -0
- data/docs/source/articles/add-a-report.html.md +202 -0
- data/docs/source/articles/add-css-through-the-admin-ui.html.md +30 -0
- data/docs/source/articles/add-javascript-through-a-manifest.html.md +367 -0
- data/docs/source/articles/add-javascript-through-a-view.html.md +80 -0
- data/docs/source/articles/add-javascript-through-the-admin-ui.html.md +30 -0
- data/docs/source/articles/add-metrics.html.md +58 -0
- data/docs/source/articles/add-or-replace-a-pricing-calculator.html.md +150 -0
- data/docs/source/articles/add-remove-or-change-a-mongoid-validation.html.md +147 -0
- data/docs/source/articles/add-remove-or-change-a-product-template.html.md +142 -0
- data/docs/source/articles/add-remove-sort-and-group-storefront-search-filters.html.md +483 -0
- data/docs/source/articles/add-stylesheets-through-a-manifest.html.md +276 -0
- data/docs/source/articles/add-system-content.html.md +138 -0
- data/docs/source/articles/analytics-overview.html.md +51 -0
- data/docs/source/articles/analyze-storefront-search-results.html.md +261 -0
- data/docs/source/articles/api-overview.html.md +35 -0
- data/docs/source/articles/appending.html.md +506 -0
- data/docs/source/articles/application-document.html.md +88 -0
- data/docs/source/articles/automated-javascript-testing.html.md +162 -0
- data/docs/source/articles/b2b-overview.html.md +64 -0
- data/docs/source/articles/browser-and-device-support.html.md +47 -0
- data/docs/source/articles/change-product-placeholder-image.html.md +39 -0
- data/docs/source/articles/change-storefront-search-results.html.md +283 -0
- data/docs/source/articles/change-the-storefront-product-pricing-ui.html.md +348 -0
- data/docs/source/articles/change-the-storefront-search-filters-ui.html.md +103 -0
- data/docs/source/articles/checkout.html.md +479 -0
- data/docs/source/articles/commerce-model.html.md +164 -0
- data/docs/source/articles/configuration-for-hosting.html.md +106 -0
- data/docs/source/articles/configuration.html.md +406 -0
- data/docs/source/articles/configure-a-payment-gateway.html.md +58 -0
- data/docs/source/articles/configure-asset-storage.html.md +29 -0
- data/docs/source/articles/configure-asset-types.html.md +18 -0
- data/docs/source/articles/configure-contact-form-subjects-list.html.md +24 -0
- data/docs/source/articles/configure-imageoptim.html.md +23 -0
- data/docs/source/articles/configure-locales.html.md +45 -0
- data/docs/source/articles/configure-logins-and-authentication.html.md +42 -0
- data/docs/source/articles/configure-low-inventory-threshold.html.md +26 -0
- data/docs/source/articles/configure-product-image-sizes-and-processing.html.md +28 -0
- data/docs/source/articles/content.html.md +554 -0
- data/docs/source/articles/contentable.html.md +41 -0
- data/docs/source/articles/contribute-code.html.md +69 -0
- data/docs/source/articles/contribute-documentation.html.md +60 -0
- data/docs/source/articles/create-a-custom-discount.html.md +234 -0
- data/docs/source/articles/create-a-new-app.html.md +131 -0
- data/docs/source/articles/create-a-plugin.html.md +19 -0
- data/docs/source/articles/create-a-style-guide.html.md +71 -0
- data/docs/source/articles/create-a-theme.html.md +134 -0
- data/docs/source/articles/css-architectural-overview.html.md +89 -0
- data/docs/source/articles/customize-a-helper.html.md +91 -0
- data/docs/source/articles/decoration.html.md +415 -0
- data/docs/source/articles/define-and-configure-inventory-policies.html.md +107 -0
- data/docs/source/articles/documentation-style-guide.html.md +48 -0
- data/docs/source/articles/documentation.html.md +54 -0
- data/docs/source/articles/domain-modeling.html.md +82 -0
- data/docs/source/articles/error-pages.html.md.erb +95 -0
- data/docs/source/articles/extension-overview.html.md +152 -0
- data/docs/source/articles/favicon-support.html.md +112 -0
- data/docs/source/articles/feature-spec-helper-stylesheet.html.md +25 -0
- data/docs/source/articles/featurejs-and-feature-spec-helper.html.md +20 -0
- data/docs/source/articles/help-and-support.html.md +34 -0
- data/docs/source/articles/html-fragment-caching.html.md +46 -0
- data/docs/source/articles/http-caching.html.md +43 -0
- data/docs/source/articles/i18n.html.md +35 -0
- data/docs/source/articles/images-flow.html.md +10 -0
- data/docs/source/articles/index-storefront-search-documents.html.md +104 -0
- data/docs/source/articles/infrastructure.html.md +46 -0
- data/docs/source/articles/installing.html.md +61 -0
- data/docs/source/articles/integrate-a-payment-gateway.html.md +124 -0
- data/docs/source/articles/integrate-a-web-analytics-provider.html.md +35 -0
- data/docs/source/articles/integrate-an-inventory-management-system.html.md +88 -0
- data/docs/source/articles/integrating-with-other-software.html.md +59 -0
- data/docs/source/articles/inventory.html.md +352 -0
- data/docs/source/articles/javascript-coding-standards.html.md +30 -0
- data/docs/source/articles/javascript-modules.html.md +174 -0
- data/docs/source/articles/javascript-overview.html.md +62 -0
- data/docs/source/articles/javascript-reference-documentation.html.md +51 -0
- data/docs/source/articles/javascript-templates.html.md +52 -0
- data/docs/source/articles/low-level-caching.html.md +25 -0
- data/docs/source/articles/maintain-a-plugin.html.md +12 -0
- data/docs/source/articles/maintenance-policy.html.md +79 -0
- data/docs/source/articles/navigable.html.md +51 -0
- data/docs/source/articles/navigating-the-code.html.md +149 -0
- data/docs/source/articles/navigation.html.md +386 -0
- data/docs/source/articles/order-life-cycle.html.md +546 -0
- data/docs/source/articles/order-pricing.html.md +389 -0
- data/docs/source/articles/orders-and-items.html.md +210 -0
- data/docs/source/articles/orders.html.md +66 -0
- data/docs/source/articles/overriding.html.md +155 -0
- data/docs/source/articles/overview.html.md +43 -0
- data/docs/source/articles/plugins-overview.html.md +12 -0
- data/docs/source/articles/prerequisites-and-dependencies.html.md +202 -0
- data/docs/source/articles/products.html.md.erb +1270 -0
- data/docs/source/articles/progressive-web-application-support.html.md +148 -0
- data/docs/source/articles/rails-asset-manifests.html.md +33 -0
- data/docs/source/articles/rails-asset-view-helpers.html.md +25 -0
- data/docs/source/articles/reading-data.html.md +10 -0
- data/docs/source/articles/releasable.html.md +37 -0
- data/docs/source/articles/report-a-bug.html.md +75 -0
- data/docs/source/articles/ruby-coding-standards.html.md +10 -0
- data/docs/source/articles/run-sidekiq-in-a-local-environment.html.md +40 -0
- data/docs/source/articles/searching.html.md +1005 -0
- data/docs/source/articles/security-policy.html.md +42 -0
- data/docs/source/articles/seeds.html.md +345 -0
- data/docs/source/articles/shipping.html.md +756 -0
- data/docs/source/articles/sort-and-exclude-product-options.html.md +47 -0
- data/docs/source/articles/storefront-search-features.html.md +568 -0
- data/docs/source/articles/storefront-searches.html.md +126 -0
- data/docs/source/articles/style-guides.html.md +21 -0
- data/docs/source/articles/stylesheet-coding-standards.html.md +24 -0
- data/docs/source/articles/stylesheets-overview.html.md +67 -0
- data/docs/source/articles/swappable-list-data-structure.html.md +81 -0
- data/docs/source/articles/system-emails.html.md +102 -0
- data/docs/source/articles/taggable.html.md +8 -0
- data/docs/source/articles/test-a-credit-card-transaction.html.md +16 -0
- data/docs/source/articles/test-if-a-plugin-is-installed.html.md +34 -0
- data/docs/source/articles/testing.html.md +914 -0
- data/docs/source/articles/themes-overview.html.md +155 -0
- data/docs/source/articles/translate-administrable-content.html.md +14 -0
- data/docs/source/articles/translate-javascript-content.html.md +16 -0
- data/docs/source/articles/translate-or-customize-message-content.html.md +29 -0
- data/docs/source/articles/translate-or-customize-static-content.html.md +30 -0
- data/docs/source/articles/use-an-existing-workarea-app.html.md +108 -0
- data/docs/source/articles/view-models.html.md +509 -0
- data/docs/source/articles/views.html.md +14 -0
- data/docs/source/articles/workers.html.md +613 -0
- data/docs/source/articles/writing-data.html.md +10 -0
- data/docs/source/cli.html.md +163 -0
- data/docs/source/favicon.ico +0 -0
- data/docs/source/images/3-variants-1-option.png +0 -0
- data/docs/source/images/3-variants-3-options.png +0 -0
- data/docs/source/images/3-years-primary-image.png +0 -0
- data/docs/source/images/404-storefront-error-page.png +0 -0
- data/docs/source/images/404-system-content-admin.png +0 -0
- data/docs/source/images/404.jpg +0 -0
- data/docs/source/images/5-years-primary-image.png +0 -0
- data/docs/source/images/activity-dashboard.png +0 -0
- data/docs/source/images/activity-for-object.png +0 -0
- data/docs/source/images/activity-ui.png +0 -0
- data/docs/source/images/adding-captioned-image-block-custom-icon.png +0 -0
- data/docs/source/images/adding-captioned-image-block-default-icon.png +0 -0
- data/docs/source/images/admin-alerts-ui.png +0 -0
- data/docs/source/images/admin-category-range-filters.png +0 -0
- data/docs/source/images/admin-for-3-column-hero.png +0 -0
- data/docs/source/images/admin-help-index.png +0 -0
- data/docs/source/images/admin-help-ui.png +0 -0
- data/docs/source/images/admin-javascript.png +0 -0
- data/docs/source/images/admin-notification-for-deactivated-discount.png +0 -0
- data/docs/source/images/admin-notifications-ui.png +0 -0
- data/docs/source/images/admin-product-show-page.png +0 -0
- data/docs/source/images/admin-products-index-page.png +0 -0
- data/docs/source/images/admin-range-filters.png +0 -0
- data/docs/source/images/admin-style-guides-navigation.png +0 -0
- data/docs/source/images/after-re-seeding.png +0 -0
- data/docs/source/images/after-seeding-localhost-3000.png +0 -0
- data/docs/source/images/after-seeding.png +0 -0
- data/docs/source/images/arrow.svg +1 -0
- data/docs/source/images/arrow_white.svg +1 -0
- data/docs/source/images/aws-resource-map.png +0 -0
- data/docs/source/images/backordered-until-output-on-inventory-sku-card.png +0 -0
- data/docs/source/images/before-seeding-localhost-3000.png +0 -0
- data/docs/source/images/before-seeding.png +0 -0
- data/docs/source/images/browsing-workarea-versions-on-the-web.png +0 -0
- data/docs/source/images/bulk-asset-upload-on-assets-index-page.png +0 -0
- data/docs/source/images/bulk-asset-upload-while-editing-content.png +0 -0
- data/docs/source/images/bundle-show-workarea-core.png +0 -0
- data/docs/source/images/bundle-show-workarea.png +0 -0
- data/docs/source/images/calendar-for-backordered-until-field.png +0 -0
- data/docs/source/images/captioned-image-block-in-storefront.png +0 -0
- data/docs/source/images/captioned-image-content-block-storefront-component-style-guide.png +0 -0
- data/docs/source/images/cart-system-content-in-admin.png +0 -0
- data/docs/source/images/cart-system-content-in-storefront.png +0 -0
- data/docs/source/images/checkout-addresses-guest.png +0 -0
- data/docs/source/images/checkout-addresses-user.png +0 -0
- data/docs/source/images/checkout-confirmation.png +0 -0
- data/docs/source/images/checkout-flow-0.png +0 -0
- data/docs/source/images/checkout-flow-1.png +0 -0
- data/docs/source/images/checkout-flow-2.png +0 -0
- data/docs/source/images/checkout-flow-3.png +0 -0
- data/docs/source/images/checkout-flow-4.png +0 -0
- data/docs/source/images/checkout-payment-guest.png +0 -0
- data/docs/source/images/checkout-payment-user.png +0 -0
- data/docs/source/images/checkout-shipping.png +0 -0
- data/docs/source/images/color-picker-component-admin-style-guide.png +0 -0
- data/docs/source/images/color-picker-component-on-content-editing-screen.png +0 -0
- data/docs/source/images/commerce-model-carts-orders.png +0 -0
- data/docs/source/images/commerce-model-order-pricing.png +0 -0
- data/docs/source/images/commerce-model.png +0 -0
- data/docs/source/images/configuring-an-index-pattern-in-kibana.png +0 -0
- data/docs/source/images/content-block-presets.png +0 -0
- data/docs/source/images/content-search-customization.png +0 -0
- data/docs/source/images/country-with-region-data-in-address-form.png +0 -0
- data/docs/source/images/country-without-region-data-in-address-form.png +0 -0
- data/docs/source/images/create-content-block-preset-ui.png +0 -0
- data/docs/source/images/credit-card-icons.png +0 -0
- data/docs/source/images/css-added-through-admin.png +0 -0
- data/docs/source/images/css-admin-ui.png +0 -0
- data/docs/source/images/current-configuration-shown-in-admin-settings.png +0 -0
- data/docs/source/images/customer-impersonation-in-admin.png +0 -0
- data/docs/source/images/customer-impersonation-in-store-front.png +0 -0
- data/docs/source/images/date-filter-same-day.png +0 -0
- data/docs/source/images/developer-toolbar-in-store-front.png +0 -0
- data/docs/source/images/discounts-sorted-by-most-redeemed.png +0 -0
- data/docs/source/images/edit-help-article.png +0 -0
- data/docs/source/images/editing-content-for-search-customization.png +0 -0
- data/docs/source/images/editing-dynamic-captioned-image-block.png +0 -0
- data/docs/source/images/editing-product-fields-in-the-admin.png +0 -0
- data/docs/source/images/editing-search-system-content.png +0 -0
- data/docs/source/images/editing-static-captioned-image-block-custom-icon.png +0 -0
- data/docs/source/images/editing-static-captioned-image-block-default-icon.png +0 -0
- data/docs/source/images/external.svg +1 -0
- data/docs/source/images/favicon_16.png +0 -0
- data/docs/source/images/favicon_180.png +0 -0
- data/docs/source/images/favicon_32.png +0 -0
- data/docs/source/images/filters-all.png +0 -0
- data/docs/source/images/filters-control.png +0 -0
- data/docs/source/images/filters-custom.png +0 -0
- data/docs/source/images/filters-groups.png +0 -0
- data/docs/source/images/filters-material.png +0 -0
- data/docs/source/images/filters-omitted.png +0 -0
- data/docs/source/images/filters-pinned.png +0 -0
- data/docs/source/images/filters-range.png +0 -0
- data/docs/source/images/filters-sorted.png +0 -0
- data/docs/source/images/filters-wrapping-to-second-line-in-admin.png +0 -0
- data/docs/source/images/generic-product-template-images-no-options-selected.png +0 -0
- data/docs/source/images/generic-product-template-images-options-selected.png +0 -0
- data/docs/source/images/generic-template.png +0 -0
- data/docs/source/images/hosting.svg +1 -0
- data/docs/source/images/image-group-content-block-in-storefront.png +0 -0
- data/docs/source/images/images.svg +1 -0
- data/docs/source/images/import-export-screenshot.png +0 -0
- data/docs/source/images/invalid-display.png +0 -0
- data/docs/source/images/itcss.png +0 -0
- data/docs/source/images/kibana-dev-tools-console.png +0 -0
- data/docs/source/images/layout-content-admin-with-2-areas.png +0 -0
- data/docs/source/images/layout-content-admin-with-3-areas.png +0 -0
- data/docs/source/images/link-to-search-system-content.png +0 -0
- data/docs/source/images/logo.svg +1 -0
- data/docs/source/images/menu.svg +2 -0
- data/docs/source/images/mongo-replica-set.svg +1 -0
- data/docs/source/images/multi-column-hero-blocks.png +0 -0
- data/docs/source/images/option-selects-product-template-images-options-selected.png +0 -0
- data/docs/source/images/option-selects-template.png +0 -0
- data/docs/source/images/option-thumbnails-template.png +0 -0
- data/docs/source/images/order-item-total-price-diagram.png +0 -0
- data/docs/source/images/order-pricing-cart-example.png +0 -0
- data/docs/source/images/order-pricing-example-adjustments.png +0 -0
- data/docs/source/images/order-pricing-example-totals.png +0 -0
- data/docs/source/images/order-pricing-placed-order-example.png +0 -0
- data/docs/source/images/order-shipping-total-diagram.png +0 -0
- data/docs/source/images/order-show-with-multiple-tenders.png +0 -0
- data/docs/source/images/order-subtotal-price-diagram.png +0 -0
- data/docs/source/images/order-tax-total-diagram.png +0 -0
- data/docs/source/images/order-total-price-diagram.png +0 -0
- data/docs/source/images/order-total-value-diagram.png +0 -0
- data/docs/source/images/orders-dashboard-links.png +0 -0
- data/docs/source/images/oval.svg +1 -0
- data/docs/source/images/payment-icon-storefront-style-guide.png +0 -0
- data/docs/source/images/people-dashboard-links.png +0 -0
- data/docs/source/images/price-adjustments-diagram.png +0 -0
- data/docs/source/images/price-display-no-options.png +0 -0
- data/docs/source/images/price-display-options-selected.png +0 -0
- data/docs/source/images/pricing-calculators-diagram.png +0 -0
- data/docs/source/images/product-list-content-block-admin.png +0 -0
- data/docs/source/images/product-list-content-block-in-store-front.png +0 -0
- data/docs/source/images/promo-products-excluded-autocomplete-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-featured-category-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-recommendations-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-search-category-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-search-results-after.png +0 -0
- data/docs/source/images/promo-products-included-autocomplete-results-before.png +0 -0
- data/docs/source/images/promo-products-included-featured-category-results-before.png +0 -0
- data/docs/source/images/promo-products-included-recommendations-results-before.png +0 -0
- data/docs/source/images/promo-products-included-search-category-results-before.png +0 -0
- data/docs/source/images/promo-products-included-search-results-before.png +0 -0
- data/docs/source/images/rails-version-constraint.png +0 -0
- data/docs/source/images/re-enable-discount.png +0 -0
- data/docs/source/images/reading-data.svg +1 -0
- data/docs/source/images/readme-hero.png +0 -0
- data/docs/source/images/redesigned-customized-sort-for-search-results.png +0 -0
- data/docs/source/images/reviews-summary-above-share-buttons.png +0 -0
- data/docs/source/images/reviews-summary-below-product-name.png +0 -0
- data/docs/source/images/reviews-summary-below-share-buttons.png +0 -0
- data/docs/source/images/reviews-summary-removed.png +0 -0
- data/docs/source/images/rsa-fingerprint-for-stash.png +0 -0
- data/docs/source/images/ruby-version-constraint.png +0 -0
- data/docs/source/images/script-tag-added-through-admin.png +0 -0
- data/docs/source/images/search-analysis-admin-alternate-rendering.png +0 -0
- data/docs/source/images/search-analysis-admin.png +0 -0
- data/docs/source/images/search-quality-report.png +0 -0
- data/docs/source/images/search.svg +1 -0
- data/docs/source/images/searching-for-cart-system-content-in-admin.png +0 -0
- data/docs/source/images/searching-for-layout-system-content-in-admin.png +0 -0
- data/docs/source/images/seeded-admin.png +0 -0
- data/docs/source/images/seeds-from-plugins.png +0 -0
- data/docs/source/images/seo-metadata-automation-ui.png +0 -0
- data/docs/source/images/show-password-button.png +0 -0
- data/docs/source/images/storefront-autocomplete.png +0 -0
- data/docs/source/images/storefront-category-summary-content-block.png +0 -0
- data/docs/source/images/storefront-category.png +0 -0
- data/docs/source/images/storefront-product-after-overriding.png +0 -0
- data/docs/source/images/storefront-product-before-overriding.png +0 -0
- data/docs/source/images/storefront-product-browse-page.png +0 -0
- data/docs/source/images/storefront-product-recommendations.png +0 -0
- data/docs/source/images/storefront-product-show-page.png +0 -0
- data/docs/source/images/storefront-requests-and-search-requests.png +0 -0
- data/docs/source/images/storefront-search-request-handling.png +0 -0
- data/docs/source/images/storefront-search-response-creation.png +0 -0
- data/docs/source/images/storefront-search.png +0 -0
- data/docs/source/images/storefront-style-guides-navigation.png +0 -0
- data/docs/source/images/styles.css +3 -0
- data/docs/source/images/tax-categories-ui.png +0 -0
- data/docs/source/images/tax-rates-ui.png +0 -0
- data/docs/source/images/unpurchasable-product.png +0 -0
- data/docs/source/images/url-redirects-filtering.png +0 -0
- data/docs/source/images/utility-nav-area-in-admin.png +0 -0
- data/docs/source/images/utility-nav-area-in-storefront.png +0 -0
- data/docs/source/images/validation-message-in-storefront.png +0 -0
- data/docs/source/images/view-model-interface.png +0 -0
- data/docs/source/images/viewing-workarea-version-in-source.png +0 -0
- data/docs/source/images/workarea.svg +1 -0
- data/docs/source/images/worst-performing-searches-on-results-customization-page.png +0 -0
- data/docs/source/images/writing-data.svg +1 -0
- data/docs/source/index.html.erb +167 -0
- data/docs/source/javascripts/jquery.js +2 -0
- data/docs/source/javascripts/lunr.js +7 -0
- data/docs/source/javascripts/site.js +299 -0
- data/docs/source/javascripts/vendor/highlight.pack.js +2 -0
- data/docs/source/layouts/article.erb +106 -0
- data/docs/source/layouts/bare.erb +46 -0
- data/docs/source/layouts/layout.erb +43 -0
- data/docs/source/release-notes.html.md +258 -0
- data/docs/source/release-notes/workarea-3-0-0.html.md +146 -0
- data/docs/source/release-notes/workarea-3-0-1.html.md +161 -0
- data/docs/source/release-notes/workarea-3-0-10.html.md +39 -0
- data/docs/source/release-notes/workarea-3-0-11.html.md +277 -0
- data/docs/source/release-notes/workarea-3-0-12.html.md +14 -0
- data/docs/source/release-notes/workarea-3-0-13.html.md +153 -0
- data/docs/source/release-notes/workarea-3-0-14.html.md +93 -0
- data/docs/source/release-notes/workarea-3-0-15.html.md +107 -0
- data/docs/source/release-notes/workarea-3-0-16.html.md +36 -0
- data/docs/source/release-notes/workarea-3-0-17.html.md +141 -0
- data/docs/source/release-notes/workarea-3-0-18.html.md +123 -0
- data/docs/source/release-notes/workarea-3-0-19.html.md +160 -0
- data/docs/source/release-notes/workarea-3-0-2.html.md +222 -0
- data/docs/source/release-notes/workarea-3-0-20.html.md +95 -0
- data/docs/source/release-notes/workarea-3-0-21.html.md +168 -0
- data/docs/source/release-notes/workarea-3-0-22.html.md +268 -0
- data/docs/source/release-notes/workarea-3-0-23.html.md +173 -0
- data/docs/source/release-notes/workarea-3-0-24.html.md +19 -0
- data/docs/source/release-notes/workarea-3-0-25.html.md +26 -0
- data/docs/source/release-notes/workarea-3-0-26.html.md +199 -0
- data/docs/source/release-notes/workarea-3-0-27.html.md +113 -0
- data/docs/source/release-notes/workarea-3-0-28.html.md +39 -0
- data/docs/source/release-notes/workarea-3-0-29.html.md +73 -0
- data/docs/source/release-notes/workarea-3-0-3.html.md +35 -0
- data/docs/source/release-notes/workarea-3-0-30.html.md +186 -0
- data/docs/source/release-notes/workarea-3-0-31.html.md +125 -0
- data/docs/source/release-notes/workarea-3-0-32.html.md +73 -0
- data/docs/source/release-notes/workarea-3-0-33.html.md +137 -0
- data/docs/source/release-notes/workarea-3-0-34.html.md +203 -0
- data/docs/source/release-notes/workarea-3-0-35.html.md +205 -0
- data/docs/source/release-notes/workarea-3-0-36.html.md +105 -0
- data/docs/source/release-notes/workarea-3-0-37.html.md +144 -0
- data/docs/source/release-notes/workarea-3-0-38.html.md +73 -0
- data/docs/source/release-notes/workarea-3-0-39.html.md +77 -0
- data/docs/source/release-notes/workarea-3-0-4.html.md +14 -0
- data/docs/source/release-notes/workarea-3-0-40.html.md +130 -0
- data/docs/source/release-notes/workarea-3-0-41.html.md +70 -0
- data/docs/source/release-notes/workarea-3-0-42.html.md +52 -0
- data/docs/source/release-notes/workarea-3-0-43.html.md +72 -0
- data/docs/source/release-notes/workarea-3-0-44.html.md +93 -0
- data/docs/source/release-notes/workarea-3-0-45.html.md +61 -0
- data/docs/source/release-notes/workarea-3-0-46.html.md +171 -0
- data/docs/source/release-notes/workarea-3-0-47.html.md +130 -0
- data/docs/source/release-notes/workarea-3-0-48.html.md +160 -0
- data/docs/source/release-notes/workarea-3-0-49.html.md +28 -0
- data/docs/source/release-notes/workarea-3-0-5.html.md +225 -0
- data/docs/source/release-notes/workarea-3-0-50.html.md +74 -0
- data/docs/source/release-notes/workarea-3-0-51.html.md +61 -0
- data/docs/source/release-notes/workarea-3-0-52.html.md +76 -0
- data/docs/source/release-notes/workarea-3-0-53.html.md +126 -0
- data/docs/source/release-notes/workarea-3-0-54.html.md +112 -0
- data/docs/source/release-notes/workarea-3-0-55.html.md +105 -0
- data/docs/source/release-notes/workarea-3-0-56.html.md +56 -0
- data/docs/source/release-notes/workarea-3-0-57.html.md +82 -0
- data/docs/source/release-notes/workarea-3-0-58.html.md +153 -0
- data/docs/source/release-notes/workarea-3-0-59.html.md +78 -0
- data/docs/source/release-notes/workarea-3-0-6.html.md +165 -0
- data/docs/source/release-notes/workarea-3-0-60.html.md +43 -0
- data/docs/source/release-notes/workarea-3-0-61.html.md +46 -0
- data/docs/source/release-notes/workarea-3-0-62.html.md +23 -0
- data/docs/source/release-notes/workarea-3-0-63.html.md +25 -0
- data/docs/source/release-notes/workarea-3-0-64.html.md +25 -0
- data/docs/source/release-notes/workarea-3-0-65.html.md +37 -0
- data/docs/source/release-notes/workarea-3-0-7.html.md +207 -0
- data/docs/source/release-notes/workarea-3-0-8.html.md +337 -0
- data/docs/source/release-notes/workarea-3-0-9.html.md +196 -0
- data/docs/source/release-notes/workarea-3-1-0.html.md +414 -0
- data/docs/source/release-notes/workarea-3-1-1.html.md +139 -0
- data/docs/source/release-notes/workarea-3-1-10.html.md +19 -0
- data/docs/source/release-notes/workarea-3-1-11.html.md +27 -0
- data/docs/source/release-notes/workarea-3-1-12.html.md +216 -0
- data/docs/source/release-notes/workarea-3-1-13.html.md +113 -0
- data/docs/source/release-notes/workarea-3-1-14.html.md +39 -0
- data/docs/source/release-notes/workarea-3-1-15.html.md +107 -0
- data/docs/source/release-notes/workarea-3-1-16.html.md +188 -0
- data/docs/source/release-notes/workarea-3-1-17.html.md +141 -0
- data/docs/source/release-notes/workarea-3-1-18.html.md +73 -0
- data/docs/source/release-notes/workarea-3-1-19.html.md +137 -0
- data/docs/source/release-notes/workarea-3-1-2.html.md +55 -0
- data/docs/source/release-notes/workarea-3-1-20.html.md +203 -0
- data/docs/source/release-notes/workarea-3-1-21.html.md +205 -0
- data/docs/source/release-notes/workarea-3-1-22.html.md +121 -0
- data/docs/source/release-notes/workarea-3-1-23.html.md +144 -0
- data/docs/source/release-notes/workarea-3-1-24.html.md +94 -0
- data/docs/source/release-notes/workarea-3-1-25.html.md +77 -0
- data/docs/source/release-notes/workarea-3-1-26.html.md +130 -0
- data/docs/source/release-notes/workarea-3-1-27.html.md +70 -0
- data/docs/source/release-notes/workarea-3-1-28.html.md +52 -0
- data/docs/source/release-notes/workarea-3-1-29.html.md +44 -0
- data/docs/source/release-notes/workarea-3-1-3.html.md +185 -0
- data/docs/source/release-notes/workarea-3-1-30.html.md +72 -0
- data/docs/source/release-notes/workarea-3-1-31.html.md +93 -0
- data/docs/source/release-notes/workarea-3-1-32.html.md +61 -0
- data/docs/source/release-notes/workarea-3-1-33.html.md +171 -0
- data/docs/source/release-notes/workarea-3-1-34.html.md +130 -0
- data/docs/source/release-notes/workarea-3-1-35.html.md +179 -0
- data/docs/source/release-notes/workarea-3-1-36.html.md +28 -0
- data/docs/source/release-notes/workarea-3-1-37.html.md +74 -0
- data/docs/source/release-notes/workarea-3-1-38.html.md +61 -0
- data/docs/source/release-notes/workarea-3-1-39.html.md +96 -0
- data/docs/source/release-notes/workarea-3-1-4.html.md +148 -0
- data/docs/source/release-notes/workarea-3-1-40.html.md +126 -0
- data/docs/source/release-notes/workarea-3-1-41.html.md +128 -0
- data/docs/source/release-notes/workarea-3-1-42.html.md +105 -0
- data/docs/source/release-notes/workarea-3-1-43.html.md +37 -0
- data/docs/source/release-notes/workarea-3-1-44.html.md +82 -0
- data/docs/source/release-notes/workarea-3-1-45.html.md +153 -0
- data/docs/source/release-notes/workarea-3-1-46.html.md +91 -0
- data/docs/source/release-notes/workarea-3-1-47.html.md +65 -0
- data/docs/source/release-notes/workarea-3-1-48.html.md +46 -0
- data/docs/source/release-notes/workarea-3-1-49.html.md +23 -0
- data/docs/source/release-notes/workarea-3-1-5.html.md +169 -0
- data/docs/source/release-notes/workarea-3-1-50.html.md +42 -0
- data/docs/source/release-notes/workarea-3-1-51.html.md +25 -0
- data/docs/source/release-notes/workarea-3-1-52.html.md +57 -0
- data/docs/source/release-notes/workarea-3-1-6.html.md +117 -0
- data/docs/source/release-notes/workarea-3-1-7.html.md +176 -0
- data/docs/source/release-notes/workarea-3-1-8.html.md +283 -0
- data/docs/source/release-notes/workarea-3-1-9.html.md +212 -0
- data/docs/source/release-notes/workarea-3-2-0.html.md +1705 -0
- data/docs/source/release-notes/workarea-3-2-1.html.md +216 -0
- data/docs/source/release-notes/workarea-3-2-10.html.md +237 -0
- data/docs/source/release-notes/workarea-3-2-11.html.md +121 -0
- data/docs/source/release-notes/workarea-3-2-12.html.md +145 -0
- data/docs/source/release-notes/workarea-3-2-13.html.md +138 -0
- data/docs/source/release-notes/workarea-3-2-14.html.md +77 -0
- data/docs/source/release-notes/workarea-3-2-15.html.md +130 -0
- data/docs/source/release-notes/workarea-3-2-16.html.md +111 -0
- data/docs/source/release-notes/workarea-3-2-17.html.md +52 -0
- data/docs/source/release-notes/workarea-3-2-18.html.md +44 -0
- data/docs/source/release-notes/workarea-3-2-19.html.md +72 -0
- data/docs/source/release-notes/workarea-3-2-2.html.md +145 -0
- data/docs/source/release-notes/workarea-3-2-20.html.md +93 -0
- data/docs/source/release-notes/workarea-3-2-21.html.md +61 -0
- data/docs/source/release-notes/workarea-3-2-22.html.md +154 -0
- data/docs/source/release-notes/workarea-3-2-23.html.md +130 -0
- data/docs/source/release-notes/workarea-3-2-24.html.md +200 -0
- data/docs/source/release-notes/workarea-3-2-25.html.md +28 -0
- data/docs/source/release-notes/workarea-3-2-26.html.md +94 -0
- data/docs/source/release-notes/workarea-3-2-27.html.md +61 -0
- data/docs/source/release-notes/workarea-3-2-28.html.md +96 -0
- data/docs/source/release-notes/workarea-3-2-29.html.md +126 -0
- data/docs/source/release-notes/workarea-3-2-30.html.md +112 -0
- data/docs/source/release-notes/workarea-3-2-31.html.md +105 -0
- data/docs/source/release-notes/workarea-3-2-32.html.md +56 -0
- data/docs/source/release-notes/workarea-3-2-33.html.md +82 -0
- data/docs/source/release-notes/workarea-3-2-34.html.md +153 -0
- data/docs/source/release-notes/workarea-3-2-35.html.md +91 -0
- data/docs/source/release-notes/workarea-3-2-36.html.md +118 -0
- data/docs/source/release-notes/workarea-3-2-37.html.md +46 -0
- data/docs/source/release-notes/workarea-3-2-38.html.md +23 -0
- data/docs/source/release-notes/workarea-3-2-39.html.md +42 -0
- data/docs/source/release-notes/workarea-3-2-4.html.md +109 -0
- data/docs/source/release-notes/workarea-3-2-40.html.md +25 -0
- data/docs/source/release-notes/workarea-3-2-41.html.md +90 -0
- data/docs/source/release-notes/workarea-3-2-5.html.md +186 -0
- data/docs/source/release-notes/workarea-3-2-6.html.md +173 -0
- data/docs/source/release-notes/workarea-3-2-7.html.md +89 -0
- data/docs/source/release-notes/workarea-3-2-8.html.md +137 -0
- data/docs/source/release-notes/workarea-3-2-9.html.md +219 -0
- data/docs/source/release-notes/workarea-3-3-0.html.md +1272 -0
- data/docs/source/release-notes/workarea-3-3-1.html.md +324 -0
- data/docs/source/release-notes/workarea-3-3-10.html.md +69 -0
- data/docs/source/release-notes/workarea-3-3-11.html.md +72 -0
- data/docs/source/release-notes/workarea-3-3-12.html.md +136 -0
- data/docs/source/release-notes/workarea-3-3-13.html.md +61 -0
- data/docs/source/release-notes/workarea-3-3-14.html.md +196 -0
- data/docs/source/release-notes/workarea-3-3-15.html.md +167 -0
- data/docs/source/release-notes/workarea-3-3-16.html.md +234 -0
- data/docs/source/release-notes/workarea-3-3-17.html.md +82 -0
- data/docs/source/release-notes/workarea-3-3-18.html.md +165 -0
- data/docs/source/release-notes/workarea-3-3-19.html.md +106 -0
- data/docs/source/release-notes/workarea-3-3-2.html.md +72 -0
- data/docs/source/release-notes/workarea-3-3-20.html.md +116 -0
- data/docs/source/release-notes/workarea-3-3-21.html.md +228 -0
- data/docs/source/release-notes/workarea-3-3-22.html.md +125 -0
- data/docs/source/release-notes/workarea-3-3-23.html.md +154 -0
- data/docs/source/release-notes/workarea-3-3-24.html.md +70 -0
- data/docs/source/release-notes/workarea-3-3-25.html.md +114 -0
- data/docs/source/release-notes/workarea-3-3-26.html.md +260 -0
- data/docs/source/release-notes/workarea-3-3-27.html.md +138 -0
- data/docs/source/release-notes/workarea-3-3-28.html.md +147 -0
- data/docs/source/release-notes/workarea-3-3-29.html.md +63 -0
- data/docs/source/release-notes/workarea-3-3-3.html.md +153 -0
- data/docs/source/release-notes/workarea-3-3-30.html.md +102 -0
- data/docs/source/release-notes/workarea-3-3-31.html.md +57 -0
- data/docs/source/release-notes/workarea-3-3-32.html.md +44 -0
- data/docs/source/release-notes/workarea-3-3-33.html.md +114 -0
- data/docs/source/release-notes/workarea-3-3-4.html.md +332 -0
- data/docs/source/release-notes/workarea-3-3-5.html.md +242 -0
- data/docs/source/release-notes/workarea-3-3-6.html.md +100 -0
- data/docs/source/release-notes/workarea-3-3-7.html.md +148 -0
- data/docs/source/release-notes/workarea-3-3-8.html.md +163 -0
- data/docs/source/release-notes/workarea-3-3-9.html.md +93 -0
- data/docs/source/release-notes/workarea-3-4-0.html.md +580 -0
- data/docs/source/release-notes/workarea-3-4-1.html.md +150 -0
- data/docs/source/release-notes/workarea-3-4-10.html.md +72 -0
- data/docs/source/release-notes/workarea-3-4-11.html.md +60 -0
- data/docs/source/release-notes/workarea-3-4-12.html.md +155 -0
- data/docs/source/release-notes/workarea-3-4-2.html.md +188 -0
- data/docs/source/release-notes/workarea-3-4-3.html.md +136 -0
- data/docs/source/release-notes/workarea-3-4-4.html.md +114 -0
- data/docs/source/release-notes/workarea-3-4-5.html.md +275 -0
- data/docs/source/release-notes/workarea-3-4-6.html.md +169 -0
- data/docs/source/release-notes/workarea-3-4-7.html.md +162 -0
- data/docs/source/release-notes/workarea-3-4-8.html.md +95 -0
- data/docs/source/release-notes/workarea-3-4-9.html.md +135 -0
- data/docs/source/search.html.erb +34 -0
- data/docs/source/shared/_header.erb +61 -0
- data/docs/source/shared/_svgs.erb +17 -0
- data/docs/source/style_guide/index.html.erb +382 -0
- data/docs/source/stylesheets/_base.scss +125 -0
- data/docs/source/stylesheets/_components.scss +669 -0
- data/docs/source/stylesheets/_helpers.scss +10 -0
- data/docs/source/stylesheets/_opinions.scss +42 -0
- data/docs/source/stylesheets/_settings.scss +56 -0
- data/docs/source/stylesheets/_typography.scss +119 -0
- data/docs/source/stylesheets/site.css.scss +14 -0
- data/docs/source/stylesheets/vendor/_avalanche.scss +328 -0
- data/docs/source/stylesheets/vendor/_normalize.scss +341 -0
- data/docs/source/stylesheets/vendor/highlight/_tomorrow_night_blue.scss +75 -0
- data/docs/source/upgrade-guides.html.md +18 -0
- data/docs/source/upgrade-guides/workarea-3-4-0.html.md +152 -0
- data/docs/workarea_renderer.rb +8 -0
- data/docs/yarn.lock +2522 -0
- metadata +669 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
---
|
2
|
+
title: Add, Remove, or Change a Product Template
|
3
|
+
excerpt: Product Templates are useful to change how the product is displayed on its detail page. This guide will show you how to manipulate these templates both within a plugin and in an application.
|
4
|
+
---
|
5
|
+
|
6
|
+
# Add, Remove, or Change a Product Template
|
7
|
+
|
8
|
+
Product Templates are useful for changing how products are displayed on their detail pages. They allow the same site to serve several "editions" of a product detail page, for clients with very diverse offerings of products. Workarea provides full control over how the product detail page is displayed, allowing developers to make both logical and cosmetic customizations to different classes of products. Product Templates can originate in the core Workarea platform, a Workarea plugin you install, or customized specifically for your application. This guide will show you how to manipulate those templates both within a plugin and in an application.
|
9
|
+
|
10
|
+
## Creating a Product Template
|
11
|
+
|
12
|
+
To create a new product template, you can run the `workarea:product_template` generator that comes bundled with Workarea. This generator is responsible for doing three things:
|
13
|
+
|
14
|
+
1. Add the template's **slug** (a human-readable unique identifier used to select the template) to `Workarea.config.product_templates`
|
15
|
+
2. Create the **partial template** from Workarea's generic template
|
16
|
+
3. Define a **view model** that inherits from `Storefront::ProductViewModel` for encapsulating view-level logic concerns. This step is optional, and the `Storefront::ProductViewModel` will be used if your template's view model is not defined.
|
17
|
+
|
18
|
+
To learn more about the various options of this generator, run the generator without arguments:
|
19
|
+
|
20
|
+
```
|
21
|
+
cd path/to/your_app
|
22
|
+
bin/rails g workarea:product_template
|
23
|
+
```
|
24
|
+
|
25
|
+
This should result in the following:
|
26
|
+
|
27
|
+
```
|
28
|
+
Usage:
|
29
|
+
rails generate workarea:product_template NAME [options]
|
30
|
+
|
31
|
+
Options:
|
32
|
+
[--skip-namespace], [--no-skip-namespace] # Skip namespace (affects only isolated applications)
|
33
|
+
[--skip-view-model], [--no-skip-view-model] # Indicates when to generate skip-view-model
|
34
|
+
|
35
|
+
Runtime options:
|
36
|
+
-f, [--force] # Overwrite files that already exist
|
37
|
+
-p, [--pretend], [--no-pretend] # Run but do not make any changes
|
38
|
+
-q, [--quiet], [--no-quiet] # Suppress status output
|
39
|
+
-s, [--skip], [--no-skip] # Skip files that already exist
|
40
|
+
|
41
|
+
Description:
|
42
|
+
Boilerplate set up for a custom product template.
|
43
|
+
|
44
|
+
Example:
|
45
|
+
rails generate workarea:product_template TemplateName
|
46
|
+
|
47
|
+
modifies:
|
48
|
+
config/initializers/workarea.rb
|
49
|
+
creates:
|
50
|
+
app/views/workarea/storefront/products/templates/_template_name.html.haml
|
51
|
+
app/view_models/workarea/storefront/template_name_view_model.rb
|
52
|
+
```
|
53
|
+
|
54
|
+
You also have the option of implementing each step of this yourself. Below is an overview of each step in the creation process.
|
55
|
+
|
56
|
+
### Create Partial Template
|
57
|
+
|
58
|
+
The partial template you create must be placed in `app/views/workarea/storefront/products/templates`, and must be named matching the configuration. For instance, if your template's name is `your_template_name`, your partial filename would be `_your_template_name.html.haml`. The example below is the minimum viable implementation of a product detail template (the form that adds the SKU to the cart):
|
59
|
+
|
60
|
+
```haml
|
61
|
+
= form_tag cart_items_path, method: 'post' do
|
62
|
+
= hidden_field_tag :product_id, product.id, id: dom_id(product, 'product_id')
|
63
|
+
= hidden_field_tag :sku, product.sku_options.first.second
|
64
|
+
= number_field_tag :quantity, 1, required: true, min: 1
|
65
|
+
= button_tag t('workarea.storefront.products.add_to_cart'), value: 'add_to_cart'
|
66
|
+
```
|
67
|
+
|
68
|
+
The template includes a `product` local variable, passed in via the `storefront/products#show` template. This local is set to the `Workarea::Storefront::ProductViewModel` (or a child class of `ProductViewModel`, as explained below) representing the `Workarea::Catalog::Product` being rendered on the current page.
|
69
|
+
|
70
|
+
### Create View Model (Optional)
|
71
|
+
|
72
|
+
Often times, a different product template will require different presentation logic for how to display attributes/images/variants for the product. This can be done by defining a class in the `Workarea::Storefront::ProductTemplates` module, which inherits from `Workarea::Storefront::ProductViewModel`. When wrapping the `Workarea::Catalog::Product`, the system will use the name of the template to determine whether a view model is defined for this template, and wrap the `Workarea::Catalog::Product` accordingly. Otherwise, `Workarea::Storefront::ProductViewModel` will be used as the default product view model.
|
73
|
+
|
74
|
+
In `app/view_models/workarea/storefront/product_templates/your_template_view_model.rb`:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
module Workarea
|
78
|
+
module Storefront
|
79
|
+
module ProductTemplates
|
80
|
+
class YourTemplateViewModel < ProductViewModel
|
81
|
+
def your_special_logic
|
82
|
+
# ...
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
### Add Configuration
|
91
|
+
|
92
|
+
In order to make the template usable, an identifier to it must be added to the `Workarea.config.product_templates` collection. In a plugin, this is typically a file like **config/initializers/configuration.rb**, but it can be named anything you want. In an application, this configuration typically lives in **config/initializers/workarea.rb**. The configuration for adding a product template is as follows:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
Workarea.configure do |config|
|
96
|
+
config.product_templates << :your_template_name
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
## Remove a Product Template
|
101
|
+
|
102
|
+
To prevent products from taking on a given product template, you can remove the template from the `config.product_templates`. Prior to doing this, however, you might want to make sure that `Catalog::Product` records which already exist in the database do not have this product template set, otherwise an error will occur when someone tries to visit the product's detail page. Make sure products for your omitted template are set to something that will display on the PDP, like `generic`, using the following line of code in the `rails console`:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Workarea::Catalog::Product.where(template: :omitted).update_all(template: :generic)
|
106
|
+
```
|
107
|
+
|
108
|
+
If you're in a Workarea application, you can use the following code in an initializer to omit a given product template from being usable:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
Workarea.configure do |config|
|
112
|
+
config.product_templates.reject! { |template| template == :omitted }
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
## Changing a Product Template
|
117
|
+
|
118
|
+
Product templates from base or acquired through a plugin may still require some changes in order for products to display according to your specifications. To accomplish this, you can decorate the view model provided by the template or override its product template to accomplish your goals. Note that most templates, as well as the `workarea/storefront/products#show` view, include append points so you don't have to override the entire template, as full view overrides tend to cause problems when upgrading between minor versions of either a plugin or the core platform.
|
119
|
+
|
120
|
+
To add logic to a plugin's product template, for example `Swatches`, decorate its product template by running the generator:
|
121
|
+
|
122
|
+
```
|
123
|
+
./bin/rails generate workarea:decorator storefront/product_templates/swatches_view_model
|
124
|
+
```
|
125
|
+
|
126
|
+
Then, edit the generated `.decorator` file to add custom attributes to `#browse_link_options`:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
module Workarea
|
130
|
+
decorate Storefront::ProductTemplates::SwatchesViewModel do
|
131
|
+
def browse_link_options
|
132
|
+
super.merge(foo: 'bar')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
You can also override an entire product template with the `workarea:override` generator:
|
139
|
+
|
140
|
+
```
|
141
|
+
./bin/rails generate workarea:override views workarea/storefront/products/templates/_swatches
|
142
|
+
```
|
@@ -0,0 +1,483 @@
|
|
1
|
+
---
|
2
|
+
title: Add, Remove, Sort, and Group Storefront Search Filters
|
3
|
+
excerpt: Learn how to programmatically manipulate and customize rendering filters on the storefront
|
4
|
+
---
|
5
|
+
|
6
|
+
# Add, Remove, Sort, and Group Storefront Search Filters
|
7
|
+
|
8
|
+
In the course of developing a Workarea application, you may need to customize the UI for search filters on category browse and search results pages.
|
9
|
+
|
10
|
+

|
11
|
+
|
12
|
+
In this example, the filters shown are "Category", "Color", "Size", and "Price". Although "Category" is a special case, the "Color" and "Size" filters are configurable terms filters, while "Price" is exposed as a range filter.
|
13
|
+
|
14
|
+
You may need to add a new filter...
|
15
|
+
|
16
|
+

|
17
|
+
|
18
|
+
...remove an existing filter...
|
19
|
+
|
20
|
+

|
21
|
+
|
22
|
+
...sort them in a different order...
|
23
|
+
|
24
|
+

|
25
|
+
|
26
|
+
..."pin" the filter to the top of the page, treating it like a special case...
|
27
|
+
|
28
|
+

|
29
|
+
|
30
|
+
...or, arrange them into groups or some other custom design:
|
31
|
+
|
32
|
+

|
33
|
+
|
34
|
+
This guide will show you how to do all of these things, and by the end of it, you'll be a Workarea filter expert!
|
35
|
+
|
36
|
+
## Etymology
|
37
|
+
|
38
|
+
Although the user sees these objects as "filters", you may see the word "facet" referring to the same feature, especially in the backend Ruby code (for example, the `Facet` class). The term "faceted search" is derived from Elasticsearch, which originally implemented a feature called "facets" (now replaced with "aggregations") that enabled filtering a resultset by various parameters. Workarea's implementation of filters echoes and compliments this functionality provided out-of-the-box by Elasticsearch. You'll see the terms "filter" and "facet" used interchangeably in this guide, but they refer to the same feature.
|
39
|
+
|
40
|
+
## Implementation
|
41
|
+
|
42
|
+
The API calls for the above customizations are mostly contained within the view model for the given page, so either `Storefront::SearchViewModel` or `Storefront::CategoryViewModel`. Workarea iterates over the `#facets` method for the view model in the view. This represents the collection of filters (as well as their returned data) in storefront search and category browse pages. These are the points at which one must extend in order to customize how filter display works.
|
43
|
+
|
44
|
+
The data for the `#facets` method is derived from the `#terms_facets` and `#range_facets` methods on `Search::Settings` and `Catalog::Category` (again, dependent on whether you're browsing a category or viewing search results).
|
45
|
+
|
46
|
+
To summarize, here are the relevant API calls for this guide:
|
47
|
+
|
48
|
+
- `Workarea::Storefront::SearchViewModel#facets`
|
49
|
+
- `Workarea::Storefront::CategoryViewModel#facets`
|
50
|
+
- `Workarea::Search::Settings#terms_facets`
|
51
|
+
- `Workarea::Search::Settings#range_facets`
|
52
|
+
- `Workarea::Catalog::Category#terms_facets`
|
53
|
+
- `Workarea::Catalog::Category#range_facets`
|
54
|
+
|
55
|
+
## Add a Search Filter
|
56
|
+
|
57
|
+
The attributes to filter on are enumerated in the site's global `Search::Settings` configuration, which is editable in the admin by visiting **/admin/search_settings**. There are two types of filters provided out-of-the-box for you, **Terms** filters and **Range** filters. Let's learn more about how to manipulate both kinds:
|
58
|
+
|
59
|
+
### Add a Terms Filter
|
60
|
+
|
61
|
+
Terms filters are completely configurable in the admin's "Search Settings" page, and require no developer assistance to configure. However, developers setting up an application for the very first time may want to decorate the `Workarea::SearchSettingsSeeds` from core to add their own filterable attributes like so:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
module Workarea
|
65
|
+
decorate SearchSettingsSeeds do
|
66
|
+
def perform
|
67
|
+
Search::Settings.current.update_attributes!(
|
68
|
+
terms_facets: %w(Color Size Material)
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
This will result in the "Material" filter rendering on the storefront below "Color" and "Size", since that's the order they were configured in:
|
76
|
+
|
77
|
+

|
78
|
+
|
79
|
+
### Add a Range Filter
|
80
|
+
|
81
|
+
The only range filter provided out-of-the-box for you by Workarea is the "Price" filter. This is configurable through the admin, but requires developer intervention to customize the admin UI so the data for these filters can be entered in.
|
82
|
+
|
83
|
+
First, configure the range facet within search settings:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
module Workarea
|
87
|
+
decorate SearchSettingsSeeds do
|
88
|
+
def perform
|
89
|
+
Search::Settings.current.update_attributes!(
|
90
|
+
range_facets: %w(Price Height)
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
Also, ensure that the search mapper for storefront products knows about the height and treats it as a numeric field.
|
98
|
+
|
99
|
+
```bash
|
100
|
+
$ bin/rails generate workarea:decorator app/models/workarea/search/storefront/product.rb
|
101
|
+
```
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
module Workarea
|
105
|
+
decorate Search::Storefront::Product do
|
106
|
+
def height
|
107
|
+
model.filters['Height'].first || 0
|
108
|
+
end
|
109
|
+
|
110
|
+
def numeric
|
111
|
+
super.merge(height: height)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
Optionally, define some tests in **test/models/workarea/search/storefront/product_test.decorator** for the new method(s) you've added:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
require 'test_helper'
|
121
|
+
|
122
|
+
module Workarea
|
123
|
+
decorate Search::Storefront::ProductTest, with: :store do
|
124
|
+
def test_height
|
125
|
+
product = create_product(filters: { 'Height' => [6] })
|
126
|
+
mapper = Search::Storefront::Product.new(product)
|
127
|
+
|
128
|
+
assert_equal(mapper.height, product.filters['Height'].first)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_numeric
|
132
|
+
product = create_product(filters: { 'Height' => [6] })
|
133
|
+
mapper = Search::Storefront::Product.new(product)
|
134
|
+
|
135
|
+
assert_includes(mapper.numeric.keys, :height)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
Run these tests against the rest of the tests in the file by performing the following command:
|
142
|
+
|
143
|
+
```bash
|
144
|
+
$ ./bin/rails test $(bundle show workarea-core)/test/models/workarea/search/storefront/product_test.rb
|
145
|
+
```
|
146
|
+
|
147
|
+
Next, extend the admin UI to allow admins to update the range filter values. First, you'll learn how to add this UI to the global search settings, then you'll learn how new range facets can be added to category edit pages.
|
148
|
+
|
149
|
+
To get started, decorate `Admin::SearchSettingsController` to output the data for your custom range facet:
|
150
|
+
|
151
|
+
```bash
|
152
|
+
$ bin/rails generate workarea:decorator app/controllers/workarea/admin/search_settings_controller.rb
|
153
|
+
```
|
154
|
+
|
155
|
+
Replace the generated file with:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
module Workarea
|
159
|
+
decorate Admin::SearchSettingsController do
|
160
|
+
def show
|
161
|
+
super
|
162
|
+
@height_facets = @settings.range_facets['height'] || []
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
You'll now need to update the markup to add the fields necessary for editing the various range values for the filter. The easiest way to do this is to override the **workarea/admin/facets/price_inputs** partial and _rename_ it to match your new filter, like **workarea/admin/facets/height_inputs**...
|
169
|
+
|
170
|
+
```bash
|
171
|
+
$ bin/rails generate workarea:override views workarea/admin/facets/_price_inputs.html.haml
|
172
|
+
$ cp app/views/workarea/admin/facets/_price_inputs.html.haml app/views/workarea/admin/facets/_height_inputs.html.haml
|
173
|
+
$ rm -f app/views/workarea/admin/facets/_price_inputs.html.haml
|
174
|
+
```
|
175
|
+
|
176
|
+
This Haml template includes code specific to filtering by price, so you'll need to go through the partial and change those spots to match your new filter:
|
177
|
+
|
178
|
+
```diff
|
179
|
+
@@ -1,5 +1,5 @@
|
180
|
+
.property
|
181
|
+
- = label_tag 'range_facets', t('workarea.admin.facets.price_inputs.height_ranges_label'), class: 'property__name'
|
182
|
+
+ = label_tag 'range_facets', t('workarea.admin.facets.price_inputs.price_ranges_label'), class: 'property__name'
|
183
|
+
%table
|
184
|
+
%thead
|
185
|
+
%tr
|
186
|
+
@@ -10,14 +10,14 @@
|
187
|
+
%tr
|
188
|
+
%td
|
189
|
+
- = currency_symbol
|
190
|
+
- = text_field_tag 'range_facets[height][][from]', range['from'], title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small', id: "range_facets[height][][from][#{index}]"
|
191
|
+
+ = text_field_tag 'range_facets[price][][from]', range['from'], title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small', id: "range_facets[price][][from][#{index}]"
|
192
|
+
%td
|
193
|
+
- = currency_symbol
|
194
|
+
- = text_field_tag 'range_facets[height][][to]', range['to'], title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small', id: "range_facets[height][][to][#{index}]"
|
195
|
+
+ = text_field_tag 'range_facets[price][][to]', range['to'], title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small', id: "range_facets[price][][to][#{index}]"
|
196
|
+
%tr{ data: { cloneable_row: '' } }
|
197
|
+
%td
|
198
|
+
- = currency_symbol
|
199
|
+
- = text_field_tag 'range_facets[height][][from]', nil, title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small'
|
200
|
+
+ = text_field_tag 'range_facets[price][][from]', nil, title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small'
|
201
|
+
%td
|
202
|
+
- = currency_symbol
|
203
|
+
- = text_field_tag 'range_facets[height][][to]', nil, title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small'
|
204
|
+
+ = text_field_tag 'range_facets[price][][to]', nil, title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small'
|
205
|
+
```
|
206
|
+
|
207
|
+
To display this new markup on the search settings page, override the **workarea/admin/search_settings/show.html.haml** partial to render your new range filter:
|
208
|
+
|
209
|
+
```bash
|
210
|
+
$ bin/rails generate workarea:override views workarea/admin/search_settings/show.html.haml
|
211
|
+
```
|
212
|
+
|
213
|
+
Then, on line 60 of the overridden file...
|
214
|
+
|
215
|
+
```diff
|
216
|
+
.tabs__panel
|
217
|
+
%h2.tabs__heading= t('workarea.admin.search_settings.show.filters.title')
|
218
|
+
%p= t('workarea.admin.search_settings.show.filters.description')
|
219
|
+
|
220
|
+
.property
|
221
|
+
= label_tag 'terms_facets_list', t('workarea.admin.search_settings.show.filters.title'), class: 'property__name'
|
222
|
+
= text_field_tag 'terms_facets_list', @settings.terms_facets_list, class: 'text-box'
|
223
|
+
%span.property__note= t('workarea.admin.form.csv_field_note')
|
224
|
+
|
225
|
+
= render 'workarea/admin/facets/price_inputs', facet: @price_facets
|
226
|
+
+ = render 'workarea/admin/facets/height_inputs', facet: @height_facets
|
227
|
+
```
|
228
|
+
|
229
|
+
Finally, create a new label for the field and restart your server:
|
230
|
+
|
231
|
+
```yaml
|
232
|
+
en:
|
233
|
+
workarea:
|
234
|
+
admin:
|
235
|
+
facets:
|
236
|
+
price_inputs:
|
237
|
+
height_ranges_label: Height Ranges
|
238
|
+
```
|
239
|
+
|
240
|
+
The search settings page on admin will now look like this:
|
241
|
+
|
242
|
+

|
243
|
+
|
244
|
+
Now that you've added a range filter to global search settings, you'll need to add it to the category edit page in order to allow categories to override the global search settings. To do this, you'll follow a slightly different path than what was described above, but the concepts are the same.
|
245
|
+
|
246
|
+
Start off by decorating `Admin::CategoryViewModel`
|
247
|
+
|
248
|
+
```bash
|
249
|
+
$ bin/rails generate workarea:decorator app/view_models/workarea/admin/category_view_model.rb
|
250
|
+
```
|
251
|
+
|
252
|
+
Add a new method called `#height_facet`, similar to the `@height_facet` instance variable you created in the last exercise:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
module Workarea
|
256
|
+
decorate Admin::CategoryViewModel do
|
257
|
+
def height_facet
|
258
|
+
@height_facet ||= price_facets['height'] || []
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
```
|
263
|
+
|
264
|
+
Then, override **workarea/admin/catalog_categories/edit.html.haml** to add your new inputs partial right after line 70:
|
265
|
+
|
266
|
+
```bash
|
267
|
+
$ bin/rails generate workarea:override views workarea/admin/catalog_categories/edit.html.haml
|
268
|
+
```
|
269
|
+
|
270
|
+
```diff
|
271
|
+
= t('workarea.admin.catalog_categories.edit.filters_note_html', search_settings_link: link_to(t('workarea.admin.catalog_categories.edit.search_settings'), search_settings_path(anchor: 'filters-tab-panel')))
|
272
|
+
|
273
|
+
= render 'workarea/admin/facets/price_inputs', facet: @category.price_facet
|
274
|
+
+ = render 'workarea/admin/facets/height_inputs', facet: @category.height_facet
|
275
|
+
|
276
|
+
.grid.grid--huge
|
277
|
+
.grid__cell.grid__cell--50.grid__cell--25-at-medium
|
278
|
+
```
|
279
|
+
|
280
|
+
Now, when you restart your server and refresh the category edit page in admin, you'll see your new range filter!
|
281
|
+
|
282
|
+

|
283
|
+
|
284
|
+
Add in the ranges you wish to filter on, ensure there's product data for that filter, and then you'll be ready to show it on the storefront.
|
285
|
+
|
286
|
+

|
287
|
+
|
288
|
+
You may have to prevent the existing price filter from showing twice, as well:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
module Workarea
|
292
|
+
decorate Storefront::CategoryViewModel, Storefront::SearchViewModel do
|
293
|
+
def facets
|
294
|
+
super.uniq(&:system_name)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
```
|
299
|
+
|
300
|
+
## Remove a Search Filter
|
301
|
+
|
302
|
+
Filters can be omitted from display on the storefront by removing them from the search settings. But this will remove the filter from displaying at all. You may want to display the filter in certain cases, for example, on a category browse page but not on a search results page. To do this, you'll need to decorate the relevant view model. Here's an example of removing the price filter from category browse pages in **app/view_models/workarea/storefront/category_view_model.decorator**:
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
module Workarea
|
306
|
+
decorate Storefront::CategoryViewModel do
|
307
|
+
def facets
|
308
|
+
super.delete_if do |facet|
|
309
|
+
facet.system_name == 'price'
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
```
|
315
|
+
|
316
|
+
Before applying this decoration, filters might look like something like this:
|
317
|
+
|
318
|
+

|
319
|
+
|
320
|
+
After the decoration is applied, you should see the price filter omitted on category pages...
|
321
|
+
|
322
|
+

|
323
|
+
|
324
|
+
...but not on search pages!
|
325
|
+
|
326
|
+

|
327
|
+
|
328
|
+
## Sort Filters
|
329
|
+
|
330
|
+
Out of the box, Workarea provides the following default sort order for your filters:
|
331
|
+
|
332
|
+
1. Category (when searching)
|
333
|
+
2. Terms filters in the order they appear in the `Search::Settings#terms_facets` Array
|
334
|
+
3. Range filters in the order they appear in the `Search::Settings#range_facets` Array
|
335
|
+
|
336
|
+
Sorting filters can be done by manipulating the order that filters appear in the collection:
|
337
|
+
|
338
|
+
```bash
|
339
|
+
$ bin/rails generate workarea:decorator app/seeds/workarea/search_settings_seeds.rb
|
340
|
+
```
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
module Workarea
|
344
|
+
decorate SearchSettingsSeeds do
|
345
|
+
def perform
|
346
|
+
Search::Settings.current.update_attributes!(
|
347
|
+
terms_facets: %w(Size Color) # original order was "Color", "Size"
|
348
|
+
)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
```
|
353
|
+
|
354
|
+
Your filters should now look something like this:
|
355
|
+
|
356
|
+

|
357
|
+
|
358
|
+
### "Special Case" Sorting
|
359
|
+
|
360
|
+
It is also possible to sort filters programmatically in the codebase to treat these filters like a "special case", for example in the case of category filtering only applying on search pages, and always sticking to the top of the filter navigation. To do so, follow the logic in "Remove a Search Filter" to decorate the appropriate view models' `#facets` method. Here's an example of "pinning" the price filter to the top of the sidebar:
|
361
|
+
|
362
|
+
```ruby
|
363
|
+
module Workarea
|
364
|
+
decorate Storefront::CategoryViewModel, Storefront::SearchViewModel do
|
365
|
+
def facets
|
366
|
+
all_facets = super
|
367
|
+
pinned_facet = all_facets.find { |facet| facet.system_name == 'price' }
|
368
|
+
|
369
|
+
return all_facets unless pinned_facet.present?
|
370
|
+
|
371
|
+
[pinned_facet] + all_facets.delete_if { |facet| facet.system_name == 'price' }
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
```
|
376
|
+
|
377
|
+
This multiple decoration is best defined in the file **app/view_models/workarea/storefront/product_browsing.decorator**. While you can't actually decorate the `ProductBrowsing` module, this file path will be looked up if `ProductBrowsing` is decorated, and thus your multiple decorations will apply cleanly without the need to manually load them at app initialization.
|
378
|
+
|
379
|
+
Before applying this decoration, your filters might look like something like this:
|
380
|
+
|
381
|
+

|
382
|
+
|
383
|
+
After the decoration is applied, you should see the price filters appearing first:
|
384
|
+
|
385
|
+

|
386
|
+
|
387
|
+
## Grouping Filters
|
388
|
+
|
389
|
+
A growing trend for retailers is to group multiple filters together in the UI. For example, a shoe retailer might want to express "Color" and "Material" within the same filter group, even though these are two distinct facets of the items in search results. In this example, you'll learn how to combine these filter values together visually, and call it "Style". To accomplish this, you'll need to override the **workarea/storefront/categories/show.html.haml** and **workarea/storefront/searches/show.html.haml** to render these filters in a slightly different way. To provide the data for this special filter group, you'll also need to override `Storefront::SearchViewModel` and `Storefront::CategoryViewModel`.
|
390
|
+
|
391
|
+
First, create a decorator at **app/view_models/workarea/storefront/product_browsing.decorator** to decorate and provide facet data for search & category browse:
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
module Workarea
|
395
|
+
decorate Storefront::CategoryViewModel, Storefront::SearchViewModel do
|
396
|
+
def style_facet
|
397
|
+
facets.find { |facet| facet.system_name == 'style' }
|
398
|
+
end
|
399
|
+
|
400
|
+
def facets_without_style
|
401
|
+
facets.reject { |facet| facet.system_name == 'style' }
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
```
|
406
|
+
|
407
|
+
Create a new partial at **app/views/workarea/storefront/facets/_style.html.haml**, this is the partial that will be used to render your new grouped facet. Here's an example of what that might look like:
|
408
|
+
|
409
|
+
```haml
|
410
|
+
.result-filters__section{ class: "result-filters__section--style" }
|
411
|
+
%h2= t('workarea.storefront.products.filter_title', name: 'Style')
|
412
|
+
- [color_facet, material_facet].compact.each do |facet|
|
413
|
+
%h3= facet.name
|
414
|
+
%ul.result-filters__group
|
415
|
+
- facet.results.each do |value_name, count|
|
416
|
+
%li.result-filters__filter{ class: ('result-filters__filter--selected' if facet.selected?(value_name)) }
|
417
|
+
= link_to facet_path(facet, value_name), rel: 'nofollow', class: 'result-filters__link' do
|
418
|
+
= value_name.titleize
|
419
|
+
- if facet.selected?(value_name)
|
420
|
+
%strong.result-filters__remove= t('workarea.storefront.products.remove_filter')
|
421
|
+
- else
|
422
|
+
%span.result-filters__count (#{count})
|
423
|
+
```
|
424
|
+
|
425
|
+
It's heavily based on the out-of-box **workarea/storefront/facets/_terms.html.haml** partial, but includes two separate dependencies (`color_facet` and `material_facet`) rather than the general `facet` used in the terms filter.
|
426
|
+
|
427
|
+
Now that your partial is defined, you'll need a way to render it. Begin by generating overrides for the aforementioned views:
|
428
|
+
|
429
|
+
```bash
|
430
|
+
$ ./bin/rails generate workarea:override views workarea/storefront/categories/show.html.haml
|
431
|
+
$ ./bin/rails generate workarea:override views workarea/storefront/searches/show.html.haml
|
432
|
+
```
|
433
|
+
|
434
|
+
Finally, update the view to add your new facet. Here's an example of what the override to **workarea/storefront/searches#show** might look like:
|
435
|
+
|
436
|
+
```diff
|
437
|
+
diff --git a/storefront/app/views/workarea/storefront/searches/show.html.haml b/storefront/app/views/workarea/storefront/searches/show.html.haml
|
438
|
+
index d90fcb09a..99453b389 100644
|
439
|
+
--- a/storefront/app/views/workarea/storefront/searches/show.html.haml
|
440
|
+
+++ b/storefront/app/views/workarea/storefront/searches/show.html.haml
|
441
|
+
@@ -19,12 +19,18 @@
|
442
|
+
%span.breadcrumbs__node{ itemprop: 'breadcrumb' }
|
443
|
+
%span.breadcrumbs__text= @search.query_string
|
444
|
+
|
445
|
+
- content_for :page_aside do
|
446
|
+
- if @search.facets.any?
|
447
|
+
.result-filters
|
448
|
+
- - @search.facets.each do |facet|
|
449
|
+
+ - @search.facets_without_style.each do |facet|
|
450
|
+
- unless @search.autoselected_filter?(facet.system_name)
|
451
|
+
- = render "workarea/storefront/facets/#{facet.type}", facet: facet
|
452
|
+
+ - if facet.system_name == 'color' && @search.style_facet.present?
|
453
|
+
+ = render "workarea/storefront/facets/style", facet: facet, size_group: @search.style_facet
|
454
|
+
+ - else
|
455
|
+
+ = render "workarea/storefront/facets/#{facet.type}", facet: facet
|
456
|
+
|
457
|
+
.view{ data: { analytics: search_results_view_analytics_data(@search).to_json } }
|
458
|
+
|
459
|
+
@@ -81,10 +87,12 @@
|
460
|
+
.mobile-filters__content
|
461
|
+
- if @search.facets.any?
|
462
|
+
.result-filters
|
463
|
+
- - @search.facets.each do |facet|
|
464
|
+
+ - @search.facets_without_style.each do |facet|
|
465
|
+
- unless @search.autoselected_filter?(facet.system_name)
|
466
|
+
- = render "workarea/storefront/facets/#{facet.type}", facet: facet
|
467
|
+
-
|
468
|
+
+ - if facet.system_name == 'size' && @search.style_facet.present?
|
469
|
+
+ = render "workarea/storefront/facets/style", facet: facet, size_group: @search.style_facet
|
470
|
+
+ - else
|
471
|
+
+ = render "workarea/storefront/facets/#{facet.type}", facet: facet
|
472
|
+
.pagination{ data: { analytics: product_list_analytics_data("Search Results for \"#{@search.query_string}\"").to_json, pagination: pagination_data(@search.products), back_to_top_button: '' } }
|
473
|
+
.grid
|
474
|
+
- @search.products.each_with_index do |product, position|
|
475
|
+
```
|
476
|
+
|
477
|
+
Make sure `Search::Settings#terms_facets` includes the "Material" filter, and your new grouped filter will render in the storefront!
|
478
|
+
|
479
|
+

|
480
|
+
|
481
|
+
## Additional Considerations
|
482
|
+
|
483
|
+
The storefront search filter UI is heavily cached on category browse pages. Some changes you make may not be visible until those caches expire, which can be anywhere from 15 minutes (HTTP page cache) to 1 hour (fragment cache for category pages). For this reason, Workarea developers typically favor testing changes to the filter UI on the search pages, but some special cases may force you to test on the category pages. In these cases, it's best to wait for the cache to expire.
|