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,19 @@
|
|
1
|
+
---
|
2
|
+
title: Create a Plugin
|
3
|
+
created_at: 2018/09/17
|
4
|
+
excerpt: To create a Workarea plugin, use the rails plugin new command with a Workarea plugin template.
|
5
|
+
---
|
6
|
+
|
7
|
+
# Create a Plugin
|
8
|
+
|
9
|
+
To create a Workarea plugin, use the _rails plugin new_ command with a Workarea plugin template.
|
10
|
+
|
11
|
+
```bash
|
12
|
+
$ rails plugin new path/to/my_plugin --full -m path/to/plugin_template.rb --skip-spring --skip-active-record --skip-action-cable
|
13
|
+
```
|
14
|
+
|
15
|
+
This template can be found in the [workarea repository](https://github.com/workarea-commerce/workarea) at [https://github.com/workarea-commerce/workarea/blob/master/plugin_template.rb](https://github.com/workarea-commerce/workarea/blob/master/plugin_template.rb).
|
16
|
+
|
17
|
+
After creating the plugin, edit the gemspec file to set relevant plugin meta data.
|
18
|
+
|
19
|
+
Plugins may be developed within their own git repository or as part of an existing repository, such as a host application built on the Workarea platform. If developing the plugin within an existing repository, be sure to change the `s.files` logic within the gemspec to include only files relevant to the plugin. For example, `Dir.glob` over a given array of directory globs rather than including all files with `git ls-files`.
|
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
title: Create a Style Guide
|
3
|
+
excerpt: To add a style guide, use the style guide generator.
|
4
|
+
---
|
5
|
+
|
6
|
+
# Create a Style Guide
|
7
|
+
|
8
|
+
To add a [style guide](style-guides.html), use the style guide generator.
|
9
|
+
|
10
|
+
Run the generator without arguments to view help:
|
11
|
+
|
12
|
+
```
|
13
|
+
cd path/to/your_app
|
14
|
+
bin/rails g workarea:style_guide
|
15
|
+
```
|
16
|
+
|
17
|
+
Your results will look something like this:
|
18
|
+
|
19
|
+
```
|
20
|
+
Usage:
|
21
|
+
rails generate workarea:style_guide ENGINE SECTION NAME [options]
|
22
|
+
|
23
|
+
Runtime options:
|
24
|
+
-f, [--force] # Overwrite files that already exist
|
25
|
+
-p, [--pretend], [--no-pretend] # Run but do not make any changes
|
26
|
+
-q, [--quiet], [--no-quiet] # Suppress status output
|
27
|
+
-s, [--skip], [--no-skip] # Skip files that already exist
|
28
|
+
|
29
|
+
Options:
|
30
|
+
ENGINE is either:
|
31
|
+
- admin
|
32
|
+
- storefront
|
33
|
+
|
34
|
+
SECTION is an existing section, the workarea gem offers these sections out of the box:
|
35
|
+
- settings
|
36
|
+
- base
|
37
|
+
- typography
|
38
|
+
- objects
|
39
|
+
- components
|
40
|
+
- trumps
|
41
|
+
|
42
|
+
NAME is the name of your partial, separated with dashes:
|
43
|
+
- button
|
44
|
+
- button--large
|
45
|
+
- table--prices
|
46
|
+
|
47
|
+
Description:
|
48
|
+
Creates a new Style Guide entry for your application.
|
49
|
+
|
50
|
+
Examples:
|
51
|
+
rails g workarea:style_guide storefront components button
|
52
|
+
rails g workarea:style_guide admin components button--large
|
53
|
+
```
|
54
|
+
|
55
|
+
## Style Guide Partial Paths
|
56
|
+
|
57
|
+
The style guide generator creates a new style guide partial at the correct path in your app (corresponding to the arguments you pass it).
|
58
|
+
|
59
|
+
For example, the partial for an Admin component goes here:
|
60
|
+
|
61
|
+
```
|
62
|
+
your_app/views/workarea/admin/style_guides/components/_foo.html.haml
|
63
|
+
```
|
64
|
+
|
65
|
+
The contents of that partial are viewable in the browser at the following paths:
|
66
|
+
|
67
|
+
```
|
68
|
+
/admin/style_guides
|
69
|
+
/admin/style_guides/components/foo
|
70
|
+
```
|
71
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
---
|
2
|
+
title: Create a Theme
|
3
|
+
excerpt: Developing your own Workarea theme is similar in many ways to developing a plugin.
|
4
|
+
---
|
5
|
+
|
6
|
+
# Create a theme
|
7
|
+
|
8
|
+
Developing your own Workarea theme is similar in many ways to developing a plugin.
|
9
|
+
Some additional tools are provided to expedite theme development and make it easy
|
10
|
+
to customize the storefront.
|
11
|
+
|
12
|
+
## Create a new theme
|
13
|
+
|
14
|
+
To create a Workarea theme use the _rails plugin new_ command with the Workarea
|
15
|
+
theme template which is part of the workarea-theme engine.
|
16
|
+
|
17
|
+
``` bash
|
18
|
+
rails plugin new /path/to/new-theme --full -m /path/to/theme-template.rb --skip-spring --skip-active-record --skip-action-cable
|
19
|
+
```
|
20
|
+
|
21
|
+
This template can be found in the [workarea-theme repository](https://github.com/workarea-commerce/workarea-theme) at [https://github.com/workarea-commerce/workarea-theme/docs/guides/source/theme_template.rb](https://github.com/workarea-commerce/workarea-theme/docs/guides/source/theme_template.rb).
|
22
|
+
|
23
|
+
After creating the theme, edit the gemspec file to set relevant metadata.
|
24
|
+
|
25
|
+
### Theme development workflow
|
26
|
+
|
27
|
+
Once you've created your theme engine and edited the gemspec you can start
|
28
|
+
developing your theme. Theme development relies heavily on overriding views,
|
29
|
+
stylesheets, and javascripts from Workarea Storefront. To jump-start your theme
|
30
|
+
development run the theme override generator to override all of the files you're
|
31
|
+
likely to need in your theme.
|
32
|
+
|
33
|
+
To use the theme override generator run
|
34
|
+
|
35
|
+
```bash
|
36
|
+
bin/rails generate workarea:theme_override
|
37
|
+
```
|
38
|
+
|
39
|
+
This will override every view file, along with most Sass and JS files from
|
40
|
+
workarea-storefront. The generator also commits these overrides and stores the
|
41
|
+
commit SHA in `lib/workarea/theme/override_commit`. This file is used by the
|
42
|
+
Workarea `theme_cleanup` rake task and should not be deleted.
|
43
|
+
|
44
|
+
Having overridden most of the files you will need to develop your theme, you are
|
45
|
+
now ready to start implementing your designs. Should you need to override other
|
46
|
+
files from Storefront, or another plugin, you should use the [Workarea override
|
47
|
+
generator](https://developer.workarea.com/workarea-3/guides/overriding).
|
48
|
+
|
49
|
+
Once you have implemented your theme you should run the Workarea `theme_cleanup` rake
|
50
|
+
task. This will remove any files in `/app` that have not changed since you ran the
|
51
|
+
theme_override generator. To execute `theme_cleanup` run:
|
52
|
+
|
53
|
+
```bash
|
54
|
+
bin/rails workarea:theme_cleanup
|
55
|
+
```
|
56
|
+
|
57
|
+
Be sure to check the files that have been removed, and test that your theme runs
|
58
|
+
and looks correct before committing this change.
|
59
|
+
|
60
|
+
Once your theme is cleaned up you're done, congratulations! Now head over to the
|
61
|
+
[Workarea plugin documentation](https://developer.workarea.com/workarea-3/guides/plugins-overview)
|
62
|
+
to learn how to release your theme for use!
|
63
|
+
|
64
|
+
### Theme requirements
|
65
|
+
|
66
|
+
In order for your theme to be registered correctly within the host application it
|
67
|
+
must depend on workarea-theme and have the following include in your plugin's
|
68
|
+
engine.rb file:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
include Workarea::Theme
|
72
|
+
```
|
73
|
+
|
74
|
+
This is necessary for the `starter_store` generator to work.
|
75
|
+
|
76
|
+
In addition your theme must:
|
77
|
+
|
78
|
+
- Include a theme.rb initializer.
|
79
|
+
- Allow the host application to configure the color scheme.
|
80
|
+
- Allow the host application to configure fonts.
|
81
|
+
|
82
|
+
The theme_template will take care of setting these things up for you, be sure to
|
83
|
+
follow the instructions for creating a new Workarea theme to ensure your theme is
|
84
|
+
configured properly.
|
85
|
+
|
86
|
+
It is recommended that your theme's README include the following information:
|
87
|
+
|
88
|
+
- Optimal image sizes.
|
89
|
+
- Compatible Workarea plugins and dependencies.
|
90
|
+
- Browser support, preferably supplemented with a browserlist file in the theme's
|
91
|
+
root directory.
|
92
|
+
- Instructions for any additional configuration or features specific to your theme.
|
93
|
+
|
94
|
+
### Theme plugin dependencies
|
95
|
+
|
96
|
+
Your theme may include dependencies on other Workarea plugins. This allows you to
|
97
|
+
ship a theme with support for popular functionality out of the box, and to benefit
|
98
|
+
from pluginized UI components and functionality.
|
99
|
+
|
100
|
+
To add support for another plugin, first add it to your theme's gemspec like this:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
s.add_dependency 'workarea-swatches', '1.0.0'
|
104
|
+
```
|
105
|
+
|
106
|
+
Next you will need to override the relevant files from the plugin to your theme.
|
107
|
+
You should use the [workarea override generator](https://developer.workarea.com/workarea-3/guides/overriding) to do this.
|
108
|
+
Once you have overridden all of the necessary files you can adjust styles, markup,
|
109
|
+
and functionality as required to meet your requirements.
|
110
|
+
|
111
|
+
_Note:_ dependencies of a theme cannot be removed when using
|
112
|
+
the theme as a gem, so it is best to keep dependencies to a minimum. The only way
|
113
|
+
to remove a theme's dependencies within a host application is to use the `starter_store`
|
114
|
+
generator, then remove the unwanted dependency from the application gemfile along
|
115
|
+
with any related app files (views, styles etc.).
|
116
|
+
|
117
|
+
### Maintaining your theme
|
118
|
+
|
119
|
+
A theme is like a baby, you spend a while making one, then you have a lifetime
|
120
|
+
of taking care of it.
|
121
|
+
|
122
|
+
Maintaining your theme means fixing bugs as they come in, and keeping your theme
|
123
|
+
up to date with the latest versions of Workarea. If your theme is not kept up to
|
124
|
+
date you will cause great pain and sadness for developers that have used your theme
|
125
|
+
in their applications. You might prevent them from being able to take upgrades.
|
126
|
+
|
127
|
+
#### Upgrading for minor-version compatibility
|
128
|
+
|
129
|
+
Upgrading your theme for compatibility with Workarea is important. At a minimum
|
130
|
+
all themes should be upgraded with the latest changes in each new minor version
|
131
|
+
of Workarea.
|
132
|
+
|
133
|
+
The Workarea upgrade tool will be very useful and allow you to
|
134
|
+
upgrade your theme in the same way you upgrade a Workarea application.
|
@@ -0,0 +1,89 @@
|
|
1
|
+
---
|
2
|
+
title: CSS Architectural Overview
|
3
|
+
excerpt: The main principals of the Workarea CSS architecture were modeled after OOCSS and ITCSS best practices. You will find that the architecture is layered. Each layer has a specific purpose and is naturally more specific than the layer it proceeds. This a
|
4
|
+
---
|
5
|
+
|
6
|
+
# CSS Architectural Overview
|
7
|
+
|
8
|
+
The main principals of the Workarea CSS architecture were modeled after OOCSS and ITCSS best practices. You will find that the architecture is layered. Each layer has a specific purpose and is naturally more specific than the layer it proceeds. This allows a developer to think about the purpose of the CSS he or she is writing before dropping it in a corresponding layer, keeping the application manifest direct and to the point.
|
9
|
+
|
10
|
+
## _Cascading_ Style Sheets
|
11
|
+
|
12
|
+
[Stylesheet manifests](add-stylesheets-through-a-manifest.html) take your referenced CSS files and produce a concatenated, production-ready file. It's important to note that the order of these files is honored during the concatenation process. This just means that the contents of the files at the top of your manifest will be output before those listed at the bottom of the manifest.
|
13
|
+
|
14
|
+
A main pillar of the Workarea CSS architecture is to harness and reinforce the natural cascade of CSS. CSS files are parsed top-to-bottom and precedence is given to CSS rules that appear lower in the code, as seen in this very simple example:
|
15
|
+
|
16
|
+
`.component { background: red; }
|
17
|
+
|
18
|
+
.component { background: blue; }`
|
19
|
+
|
20
|
+
When this code reaches the browser the component is blue, because of the cascade.
|
21
|
+
|
22
|
+
Therefore, your most general CSS rules should be found at the top of the manifest, and your most specific CSS rules should be found at the bottom. By always keeping this in mind, you enable yourself to write scalable, purposeful and technically correct CSS.
|
23
|
+
|
24
|
+
## Layers
|
25
|
+
|
26
|
+
To reinforce the cascade of increasing specificity, the Workarea platform defines specific various CSS layers. All of the CSS files that you write should live in directories named after the file's intended layer. For example, if you create a component for the Storefront called `toggle-button`, that file should live within `workarea/storefront/components/_toggle_button.scss`. This files reference should then be added to the Components layer of the manifest.
|
27
|
+
|
28
|
+
I've listed the main layers below. By "main layers" I mean they are the layers that define the core architecture. There are a few plugin-specific layers offered (which I'll cover in a bit), in addition to the following:
|
29
|
+
|
30
|
+
1. The Settings Layer
|
31
|
+
2. The Tools Layer
|
32
|
+
3. The Generic Layer
|
33
|
+
4. The Base Layer
|
34
|
+
5. The Objects Layer
|
35
|
+
6. The Typography Layer
|
36
|
+
7. The Components Layer
|
37
|
+
8. The Trumps Layer
|
38
|
+
|
39
|
+
### The Settings Layer
|
40
|
+
|
41
|
+
This layer contains variables which are meant to be globally available. They are considered safe for general use and you'll find them peppered throughout the proceeding Sass files.
|
42
|
+
|
43
|
+
Each carry a `!default` flag, allowing Theme plugins or multi-site configuration to override their values, if necessary.
|
44
|
+
|
45
|
+
### The Tools Layer
|
46
|
+
|
47
|
+
This layer contains only functions and mixins. They're helpers that let you dry up your code or perform more complex calculations.
|
48
|
+
|
49
|
+
### The Generic Layer
|
50
|
+
|
51
|
+
This is the first layer where we start to see some CSS. The Generic Layer is the most global CSS you'll find in the project. We start off with including the [Normalize](https://necolas.github.io/normalize.css/) library, which we tweak the configuration of just a bit in our own reset.css file.
|
52
|
+
|
53
|
+
Here is where we set up our global page box-sizing and whatever fonts we'll be using for the project.
|
54
|
+
|
55
|
+
### The Base Layer
|
56
|
+
|
57
|
+
Now that a sane foundation has been laid, we can begin to apply some default styling to element selectors.
|
58
|
+
|
59
|
+
The biggest element we style is the `html` element (in `_page.scss`). Then we ask ourselves what should specific elements look like if we were to just drop them on a page, devoid of classes. This is where your default `table` element and `ul` element styling lives. Each file is grouped thematically, by usage. So the `_forms.scss` file contains default styles for `form`, `input`, and `textarea` tags, for example.
|
60
|
+
|
61
|
+
### The Objects Layer
|
62
|
+
|
63
|
+
Objects are probably the hardest part of the architecture to grasp. They are intended to be design-free classes and placeholder selectors that allow you to DRY up your codebase. An `inline-list` should remove the bullets of a list and make it's children display horizontally rather than vertically. A `button-reset` should remove all browser styling of a button, so that a component class can start applying design styles in a clear an direct manner.
|
64
|
+
|
65
|
+
### The Typography Layer
|
66
|
+
|
67
|
+
Here we find all of the text-based styles in the app. All headings are defined here. Utility classes to easily allow a developer to left, right, or center-justify some text are defined here. Links and paragraphs are defined here as well.
|
68
|
+
|
69
|
+
### The Components Layer
|
70
|
+
|
71
|
+
All of the styles leading up to this layer have ensured that our document looks just like a well formatted document. The Components layer takes that document and makes it into a real website. It provides each of the building blocks needed to achieve layout, the design, and the pleasurable user experience your customers will enjoy.
|
72
|
+
|
73
|
+
### The Trumps Layer
|
74
|
+
|
75
|
+
Lastly we have the Trumps layer. Trumps are the law. When their classes are applied to an element they are expected to react accordingly. There is no ambiguity in this layer. It contains styles that must be applied, at any cost. If you need to use the `!important` flag on a value, feel free, but you shouldn't have to, since these styles are naturally the most specific.
|
76
|
+
|
77
|
+
## Plugin-Specific Layers
|
78
|
+
|
79
|
+
In addition to the aforementioned layers, there are a few layers used only by Plugins.
|
80
|
+
|
81
|
+
### The Theme Config Layer
|
82
|
+
|
83
|
+
Theme Plugins are a special type of plugin who's primary purpose is to make the default Storefront look vastly different. These plugins make use of the Theme Config layer, which appears just before the Settings layer. Theme Plugins can override any Sass variable that carries a `!default` declaration which, out of the box, is every declared variable.
|
84
|
+
|
85
|
+
### The Theme Layer
|
86
|
+
|
87
|
+
Theme Plugins use this layer to further augment the styling of the system. The Theme layer appears directly after the Components layer, and right above the Trumps layer, to allow increased specificity beyond that of the Components layer.
|
88
|
+
|
89
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
---
|
2
|
+
title: Customize a Helper
|
3
|
+
excerpt: Workarea developers can use the following two-step procedure to add or change helper methods
|
4
|
+
---
|
5
|
+
|
6
|
+
Customize a Helper
|
7
|
+
======================================================================
|
8
|
+
|
9
|
+
[Rails helpers](https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers.html) are modules that define methods for use in views and controllers (helper methods).
|
10
|
+
Occasionally, you may encounter the following use cases involving helper methods:
|
11
|
+
|
12
|
+
* From a plugin, you need to define a new helper method
|
13
|
+
* From a plugin or application, you need to re-define a helper method originally defined by Workarea
|
14
|
+
|
15
|
+
The Rails engine architecture does not provide an extension mechanism to enable these use cases.
|
16
|
+
However, Workarea developers can use the following two-step procedure to satisfy these requirements:
|
17
|
+
|
18
|
+
1. Define or re-define the helper method (depending on use case)
|
19
|
+
2. Add the helper module to the ancestors of either the Admin or Storefront application controller
|
20
|
+
|
21
|
+
|
22
|
+
1\. (Re)Define the Helper Method
|
23
|
+
----------------------------------------------------------------------
|
24
|
+
|
25
|
+
For a new helper method (from a plugin), define a new helper and method.
|
26
|
+
The following example defines a new helper method within the _Blogs_ plugin:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
# workarea-blog/app/helpers/workarea/storefront/blogs_helper.rb
|
30
|
+
module Workarea
|
31
|
+
module Storefront
|
32
|
+
module BlogsHelper
|
33
|
+
def blog_posting_schema(entry)
|
34
|
+
# implementation of new helper method
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
To redefine an existing method (from an app or a plugin), define a method with the same name within a new module.
|
42
|
+
The following example re-defines a method from the _Blogs_ plugin from the _Boardgamez_ app:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# boardgamez/app/helpers/workarea/storefront/blogs_helper.rb
|
46
|
+
module Workarea
|
47
|
+
module Storefront
|
48
|
+
module BoardgamezBlogsHelper
|
49
|
+
def blog_posting_schema(entry)
|
50
|
+
# re-implementation of helper method
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
|
58
|
+
2\. Add the Helper to an Application Controller
|
59
|
+
----------------------------------------------------------------------
|
60
|
+
|
61
|
+
In both cases above, a new module is defined.
|
62
|
+
Add that module to the ancestors of either the Storefront or Admin application controller, depending on where you intend to use the helper method.
|
63
|
+
Do this using the `.helper` class method on the controller.
|
64
|
+
|
65
|
+
The following examples accomplish this in different ways, and both techniques are applicable to applications and plugins.
|
66
|
+
|
67
|
+
The first [decorates](decoration.html) the chosen controller:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
# workarea-blog/app/controllers/workarea/storefront/application_controller.decorator
|
71
|
+
module Workarea
|
72
|
+
decorate Storefront::ApplicationController, with: :blog do
|
73
|
+
decorated { helper Storefront::BlogsHelper }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
While the following example does the work in a configuration file:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
# boardgamez/config/application.rb
|
82
|
+
module Boardgamez
|
83
|
+
class Application < Rails::Application
|
84
|
+
config.to_prepare do
|
85
|
+
Workarea::Storefront::ApplicationController.helper(
|
86
|
+
Workarea::Storefront::BoardgamezBlogsHelper
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
@@ -0,0 +1,415 @@
|
|
1
|
+
---
|
2
|
+
title: Decoration
|
3
|
+
excerpt: Decoration is an extension technique that allows Workarea applications and plugins to modify Ruby classes provided by the Workarea platform and other Ruby libraries. Ruby is a dynamic language that allows classes (and their instances) to be modifie
|
4
|
+
---
|
5
|
+
|
6
|
+
# Decoration
|
7
|
+
|
8
|
+
<dfn>Decoration</dfn> is an extension technique that allows Workarea applications and plugins to modify Ruby classes provided by the Workarea platform and other Ruby libraries. Ruby is a dynamic language that allows classes (and their instances) to be modified during runtime, however the syntax and APIs that Ruby provides for this purpose can be confusing to less experienced Ruby developers. Workarea therefore leverages <cite>Rails::Decorators</cite> ([gem](https://rubygems.org/gems/rails-decorators/versions/0.1.2), [docs](http://www.rubydoc.info/gems/rails-decorators/0.1.2), [source](https://github.com/weblinc/rails-decorators)), an open source Ruby library also maintained by Workarea, to simplify the process of extending classes.
|
9
|
+
|
10
|
+
Rails::Decorators specifies a DSL (based on Rails' [ActiveSupport::Concern](http://www.rubydoc.info/gems/activesupport/5.1.4/ActiveSupport/Concern)) to be used within <dfn>decorators</dfn>, which are Ruby files whose names end with _.decorator_. Each decorator extends one or more Ruby classes. Rails::Decorators ensures decorators within applications and plugins are autoloaded _after_ Rails autoloads the class definitions from the application and its dependencies.
|
11
|
+
|
12
|
+
## Decorators
|
13
|
+
|
14
|
+
Decorators allow application and plugin authors to extend existing Ruby classes in the following ways.
|
15
|
+
|
16
|
+
- Add new instance and class methods to a class
|
17
|
+
- Modify existing instance and class methods, with access to the pre-decoration implementation via `super`
|
18
|
+
- Execute class macros or other code as if you were in the original class definition
|
19
|
+
|
20
|
+
Because decorators contain only _differences_ from the classes they are extending, they are more lightweight than other extension techniques that completely replace the code to be customized. During an upgrade, if code you've decorated has changed, you may need to update your decorators. However, code changes you haven't decorated will be applied seamlessly to your application without additional upgrade cost.
|
21
|
+
|
22
|
+
## Decorator Example
|
23
|
+
|
24
|
+
I extracted the following example from the [Workarea Package Products](https://github.com/workarea-commerce/workarea-package-products) plugin and present it here with minor edits and annotations to demonstrate the structure of a decorator. Review the [Rails::Decorators documentation](http://www.rubydoc.info/gems/rails-decorators/0.1.2) for more details.
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# workarea-package_products-3.1.0/app/models/workarea/catalog/product.decorator
|
28
|
+
# The path of the decorator mimics the path of the class to be decorated
|
29
|
+
|
30
|
+
# Open namespace for convenience (to avoid fully qualified constants)
|
31
|
+
module Workarea
|
32
|
+
# Pass the classes to be decorated and any options to 'decorate', along with a block
|
33
|
+
# Decorators within plugins use the 'with' option to avoid naming collisions (see text below)
|
34
|
+
decorate Catalog::Product, with: :package_products do
|
35
|
+
# Code within the 'decorated' block is executed as if it were included in the class definition
|
36
|
+
# Use this block to execute class macros or other metaprogramming
|
37
|
+
decorated do
|
38
|
+
include FeaturedProducts
|
39
|
+
|
40
|
+
scope :packages_containing, ->(id) { where('product_ids' => id) }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Use the 'class_methods' block to add and modify class methods
|
44
|
+
class_methods do
|
45
|
+
def find_for_update_by_sku(sku)
|
46
|
+
where('variants.sku' => sku).flat_map do |product|
|
47
|
+
[product] + packages_containing(product.id)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Add and modify instance methods directly within the 'decorate' block
|
53
|
+
|
54
|
+
def package?
|
55
|
+
template == 'package' || product_ids.present?
|
56
|
+
end
|
57
|
+
|
58
|
+
def family?
|
59
|
+
template == 'family'
|
60
|
+
end
|
61
|
+
|
62
|
+
def active?
|
63
|
+
(read_attribute(:active) && variants.active.any? || product_ids.present?)
|
64
|
+
end
|
65
|
+
|
66
|
+
def purchasable?
|
67
|
+
# Use 'super' to find the same method in the ancestor chain and invoke it
|
68
|
+
# This provides access to the "pre-decorated" implementation (see examples below)
|
69
|
+
super && package?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
## Decorating Tests
|
76
|
+
|
77
|
+
Because [tests](testing.html) are Ruby methods, you can extend tests by decorating test cases, the classes in which test methods are defined. When decorating features, you should always decorate the corresponding tests as well.
|
78
|
+
|
79
|
+
The following examples from [Workarea Browse Option](https://github.com/workarea-commerce/workarea-browse-option) demonstrate the need to decorate a feature and its tests together. In the first example, Browse Option decorates `Search::ProductEntries` so that products that "browse by option" are represented by multiple documents in Elasticsearch. This is new functionality, not covered by the existing test suite, so the plugin also decorates `Search::ProductEntriesTest` adding a new test to confirm the behavior.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# workarea-browse_option-1.1.0/app/queries/search/product_entries.decorator
|
83
|
+
|
84
|
+
module Workarea
|
85
|
+
decorate Search::ProductEntries, with: :browse_option do
|
86
|
+
def index_entries_for(product)
|
87
|
+
if product.browses_by_option?
|
88
|
+
product.browse_options.map do |value|
|
89
|
+
Search::Storefront::ProductOption.new(
|
90
|
+
product,
|
91
|
+
option: product.browse_option,
|
92
|
+
value: value
|
93
|
+
)
|
94
|
+
end
|
95
|
+
else
|
96
|
+
super
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# workarea-browse_option-1.1.0/test/queries/workarea/search/product_entries_test.decorator
|
103
|
+
|
104
|
+
require 'test_helper'
|
105
|
+
|
106
|
+
module Workarea
|
107
|
+
decorate Search::ProductEntriesTest, with: :browse_option do
|
108
|
+
def test_browse_option_entries
|
109
|
+
products = Array.new(2) { create_product }
|
110
|
+
|
111
|
+
products.first.update_attributes!(
|
112
|
+
browse_option: 'color',
|
113
|
+
variants: [
|
114
|
+
{ sku: 'SKU1', details: { color: ['Red'] } },
|
115
|
+
{ sku: 'SKU2', details: { color: ['Blue'] } }
|
116
|
+
]
|
117
|
+
)
|
118
|
+
|
119
|
+
assert(3, Search::ProductEntries.new(products).entries.size)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
In the next example, Browse Option decorates `BulkIndexProducts`, changing the behavior of `perform_by_models`. This change breaks an existing test for `perform`, since `perform_by_models` is used in that method's implementation. The plugin therefore decorates `BulkIndexProductsTest` as well, in order to fix the test for `perform`.
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
# workarea-browse_option-1.1.0/app/workers/workarea/bulk_index_products.decorator
|
129
|
+
|
130
|
+
module Workarea
|
131
|
+
decorate BulkIndexProducts, with: :browse_option do
|
132
|
+
class_methods do
|
133
|
+
def perform_by_models(products)
|
134
|
+
return if products.blank?
|
135
|
+
|
136
|
+
documents = delete_actions(products) +
|
137
|
+
Search::ProductEntries.new(products).map(&:as_bulk_document)
|
138
|
+
|
139
|
+
Search::Storefront.bulk(documents)
|
140
|
+
products.each { |p| p.set(last_indexed_at: Time.current) }
|
141
|
+
end
|
142
|
+
|
143
|
+
# ...
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# workarea-browse_option-1.1.0/test/workers/workarea/bulk_index_products_test.decorator
|
149
|
+
|
150
|
+
require 'test_helper'
|
151
|
+
|
152
|
+
module Workarea
|
153
|
+
decorate BulkIndexProductsTest, with: :browse_option do
|
154
|
+
def test_peform
|
155
|
+
Workarea::Search::Storefront.reset_indexes!
|
156
|
+
|
157
|
+
Sidekiq::Callbacks.disable(IndexProduct) do
|
158
|
+
products = Array.new(2) { create_product }
|
159
|
+
|
160
|
+
assert_equal(0, Search::Storefront.count)
|
161
|
+
BulkIndexProducts.new.perform(products.map(&:id))
|
162
|
+
assert_equal(2, Search::Storefront.count)
|
163
|
+
|
164
|
+
products.first.update_attributes!(
|
165
|
+
browse_option: 'color',
|
166
|
+
variants: [
|
167
|
+
{ sku: 'SKU1', details: { color: ['Red'] } },
|
168
|
+
{ sku: 'SKU2', details: { color: ['Blue'] } }
|
169
|
+
]
|
170
|
+
)
|
171
|
+
|
172
|
+
assert_equal(2, Search::Storefront.count)
|
173
|
+
BulkIndexProducts.new.perform(products.map(&:id))
|
174
|
+
assert_equal(3, Search::Storefront.count)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# ...
|
179
|
+
end
|
180
|
+
end
|
181
|
+
```
|
182
|
+
|
183
|
+
Also see [Writing Test Decorators](testing.html#writing-test-decorators) within the [Testing](testing.html) guide for more on this topic.
|
184
|
+
|
185
|
+
## Compounding Decorators
|
186
|
+
|
187
|
+
Multiple engines may decorate the same class, in which case the effects of the decorators are cumulative. Decorators within the application are prepended last, giving them the opportunity to modify their classes after all plugin decorators.
|
188
|
+
|
189
|
+
For example, I've created a new application and added the following decorator within my app to begin implementing a loyalty program.
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
# app/models/workarea/catalog/product.decorator
|
193
|
+
|
194
|
+
module Workarea
|
195
|
+
decorate Catalog::Product do
|
196
|
+
decorated do
|
197
|
+
field :loyalty_points, type: Integer, default: 100
|
198
|
+
end
|
199
|
+
|
200
|
+
def loyalty_promo?
|
201
|
+
loyalty_points > 100
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
```
|
206
|
+
|
207
|
+
My application depends on several Workarea plugins.
|
208
|
+
|
209
|
+
```bash
|
210
|
+
$ grep 'workarea' Gemfile
|
211
|
+
gem 'workarea', '~> 3.1.0'
|
212
|
+
gem 'workarea-blog'
|
213
|
+
gem 'workarea-browse_option'
|
214
|
+
gem 'workarea-clothing'
|
215
|
+
gem 'workarea-content_search'
|
216
|
+
gem 'workarea-package_products'
|
217
|
+
gem 'workarea-reviews'
|
218
|
+
gem 'workarea-share'
|
219
|
+
```
|
220
|
+
|
221
|
+
Most of these plugins include the same decorator I've included in my application. In the example below, I search for the path _workarea/catalog/product_ within my application and its dependencies. In the results, you can see the following.
|
222
|
+
|
223
|
+
- The original Product model from Workarea Core
|
224
|
+
- The Product decorator I added to my application
|
225
|
+
- Four additional Product decorators, one each from Workarea Browse Option, Workarea Clothing, Workarea Package Products, and Workarea Reviews
|
226
|
+
|
227
|
+
```bash
|
228
|
+
$ find . -path '*workarea/catalog/product.*'
|
229
|
+
./app/models/workarea/catalog/product.decorator
|
230
|
+
./vendor/ruby/2.4.0/gems/workarea-browse_option-1.1.0/app/models/workarea/catalog/product.decorator
|
231
|
+
./vendor/ruby/2.4.0/gems/workarea-clothing-2.1.0/app/models/workarea/catalog/product.decorator
|
232
|
+
./vendor/ruby/2.4.0/gems/workarea-core-3.1.1/app/models/workarea/catalog/product.rb
|
233
|
+
./vendor/ruby/2.4.0/gems/workarea-package_products-3.1.0/app/models/workarea/catalog/product.decorator
|
234
|
+
./vendor/ruby/2.4.0/gems/workarea-reviews-2.1.0/app/models/workarea/catalog/product.decorator
|
235
|
+
```
|
236
|
+
|
237
|
+
To quickly demonstrate the effect of multiple decorators on the Product class, the following example (which I've annotated) lists the class's immediate ancestors.
|
238
|
+
|
239
|
+
```bash
|
240
|
+
$ bin/rails r 'puts Workarea::Catalog::Product.ancestors' | grep 'Workarea'
|
241
|
+
Workarea::Catalog::Product::ProductDecorator # application decorator
|
242
|
+
Workarea::Catalog::Product::ReviewsProductDecorator # |
|
243
|
+
Workarea::Catalog::Product::PackageProductsProductDecorator # |-- plugin decorators
|
244
|
+
Workarea::Catalog::Product::ClothingProductDecorator # |
|
245
|
+
Workarea::Catalog::Product::BrowseOptionProductDecorator # |
|
246
|
+
Workarea::Catalog::Product # original class
|
247
|
+
Workarea::FeaturedProducts
|
248
|
+
Workarea::Details
|
249
|
+
Workarea::Commentable
|
250
|
+
Workarea::Navigable
|
251
|
+
Workarea::Releasable
|
252
|
+
Workarea::ApplicationDocument
|
253
|
+
```
|
254
|
+
|
255
|
+
When looking up methods originally defined in this class, Ruby will actually look through the modules and classes as they are ordered above (top to bottom). Note the plugin decorator modules are searched before the original class, and they are searched in the opposite order the plugins are included in the Gemfile. Each plugin decorator module has a prefix that is derived from the value of the `:with` option in the decorator. The `:with` value must be unique to the ecosystem to avoid naming conflicts.
|
256
|
+
|
257
|
+
The application decorator module is searched first. Notice it does not have a prefix, because the `:with` option is omitted from the decorator, which is common practice for application decorators. Because the application decorator module is searched first, it has the responsibility of resolving any conflicts resulting from the culmination of the other decorators.
|
258
|
+
|
259
|
+
## Super
|
260
|
+
|
261
|
+
Within a decorator's method definitions, calling `super` results in calling the same method on the closest ancestor in which it is defined. An example ancestor chain is shown above. As you can see from that example, a decorator may in fact be extending another decorator. Furthermore, calling `super` has various applications that may not be immediately obvious. The following examples, taken from various plugins, demonstrate uses of `super` within decorators.
|
262
|
+
|
263
|
+
In the following examples, <dfn>command</dfn> refers to a method concerned with side effects, while <dfn>query</dfn> refers to a method concerned with a return value.
|
264
|
+
|
265
|
+
### Prepend to a Command
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
# workarea-browse_option-1.1.0/app/workers/workarea/index_product.decorator
|
269
|
+
|
270
|
+
module Workarea
|
271
|
+
decorate IndexProduct, with: :browse_option do
|
272
|
+
class_methods do
|
273
|
+
def perform(product)
|
274
|
+
clear(product)
|
275
|
+
super
|
276
|
+
end
|
277
|
+
|
278
|
+
def clear(product)
|
279
|
+
# ...
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
### Conditionally Append to a Command
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
# workarea-package_products-3.1.0/app/controllers/workarea/storefront/products_controller.decorator
|
290
|
+
|
291
|
+
module Workarea
|
292
|
+
decorate Storefront::ProductsController, with: :package_products do
|
293
|
+
def show
|
294
|
+
super
|
295
|
+
render 'package_show' if @product.package?
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
```
|
300
|
+
|
301
|
+
### Conditionally Replace a Command
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
# workarea-content_search-1.0.1/app/controllers/workarea/storefront/searches_controller.decorator
|
305
|
+
|
306
|
+
module Workarea
|
307
|
+
decorate Storefront::SearchesController, with: :content_search do
|
308
|
+
# ...
|
309
|
+
|
310
|
+
def set_search(response)
|
311
|
+
if response.template == 'content'
|
312
|
+
@search = Storefront::ContentSearchViewModel.new(response, view_model_options)
|
313
|
+
else
|
314
|
+
super
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
321
|
+
### Append to a Query
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
# workarea-reviews-2.1.0/app/models/workarea/search/storefront/product.decorator
|
325
|
+
|
326
|
+
module Workarea
|
327
|
+
decorate Search::Storefront::Product, with: :reviews do
|
328
|
+
def sorts
|
329
|
+
super.merge(
|
330
|
+
rating: Review.find_sorting_score(model.id)
|
331
|
+
)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# workarea-reviews-2.1.0/app/queries/workarea/search/product_search.decorator
|
337
|
+
|
338
|
+
module Workarea
|
339
|
+
decorate Search::ProductSearch, with: :reviews do
|
340
|
+
class_methods do
|
341
|
+
def available_sorts
|
342
|
+
super.tap { |sorts| sorts << Sort.top_rated }
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
```
|
348
|
+
|
349
|
+
### Conditionally Prepend to a Query
|
350
|
+
|
351
|
+
```ruby
|
352
|
+
# workarea-browse_option-1.1.0/app/view_models/workarea/storefront/product_view_model/cache_key.decorator
|
353
|
+
|
354
|
+
module Workarea
|
355
|
+
decorate Storefront::ProductViewModel::CacheKey, with: :browse_option do
|
356
|
+
# ...
|
357
|
+
|
358
|
+
def option_parts
|
359
|
+
option = @product.browse_option
|
360
|
+
return super unless option.present? && @options[option].present?
|
361
|
+
|
362
|
+
super.unshift(@options[option])
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
```
|
367
|
+
|
368
|
+
### Conditionally Replace a Query
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
# workarea-package_products-3.1.0/app/queries/workarea/search/product_entries.decorator
|
372
|
+
|
373
|
+
module Workarea
|
374
|
+
decorate Search::ProductEntries, with: :package_products do
|
375
|
+
def index_entries_for(product)
|
376
|
+
return Search::Storefront::PackageProduct.new(product) if product.package?
|
377
|
+
super
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
```
|
382
|
+
|
383
|
+
## Decorator Generator
|
384
|
+
|
385
|
+
Workarea provides a Rails generator that application developers can use to create a new decorator within an application. Given the path (relative to the engine root) to a file where a Workarea class is defined, the generator will create a decorator for that class within the application. The generator will also try to create decorators for applicable tests.
|
386
|
+
|
387
|
+
Run the generator with the _--help_ option for documentation and examples. The following example is from my demonstration app running Workarea 3.1.1.
|
388
|
+
|
389
|
+
```bash
|
390
|
+
$ bin/rails g workarea:decorator --help
|
391
|
+
Usage:
|
392
|
+
rails generate workarea:decorator PATH [options]
|
393
|
+
|
394
|
+
Runtime options:
|
395
|
+
-f, [--force] # Overwrite files that already exist
|
396
|
+
-p, [--pretend], [--no-pretend] # Run but do not make any changes
|
397
|
+
-q, [--quiet], [--no-quiet] # Suppress status output
|
398
|
+
-s, [--skip], [--no-skip] # Skip files that already exist
|
399
|
+
|
400
|
+
Description:
|
401
|
+
Generates a new decorator for a given PATH in a Workarea platform
|
402
|
+
component (or plugin), and a decorator for its unit test from the existing
|
403
|
+
codebase in your host app.
|
404
|
+
|
405
|
+
Example:
|
406
|
+
rails generate workarea:decorator app/models/workarea/search/storefront/product.rb
|
407
|
+
|
408
|
+
This will create:
|
409
|
+
app/models/workarea/search/storefront/product.decorator
|
410
|
+
test/models/workarea/search/storefront/product_test.decorator (if a test exists)
|
411
|
+
|
412
|
+
If no tests exist, it will also show a huge warning message stating the class you're
|
413
|
+
about to decorate has NO tests, so anything you change must be also
|
414
|
+
verified in the unit tests.
|
415
|
+
```
|