{"id":21431519,"url":"https://github.com/ecomclub/ecomplus-store-template","last_synced_at":"2026-02-13T12:53:13.634Z","repository":{"id":96379228,"uuid":"118822233","full_name":"ecomclub/ecomplus-store-template","owner":"ecomclub","description":"Template specifications for E-Com Plus ecommerce themes","archived":false,"fork":false,"pushed_at":"2019-02-07T16:28:25.000Z","size":285,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-14T23:39:49.521Z","etag":null,"topics":["ecommerce-framework","ecommerce-store","ecommerce-storefront","javascript-library","storefront","vuejs2"],"latest_commit_sha":null,"homepage":"https://developers.e-com.plus/docs/themes/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ecomclub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-24T21:07:29.000Z","updated_at":"2024-05-16T17:40:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"c8e7f5bc-8eb2-40bb-80f4-2757bf13604c","html_url":"https://github.com/ecomclub/ecomplus-store-template","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ecomclub/ecomplus-store-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecomclub%2Fecomplus-store-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecomclub%2Fecomplus-store-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecomclub%2Fecomplus-store-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecomclub%2Fecomplus-store-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecomclub","download_url":"https://codeload.github.com/ecomclub/ecomplus-store-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecomclub%2Fecomplus-store-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29406544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecommerce-framework","ecommerce-store","ecommerce-storefront","javascript-library","storefront","vuejs2"],"created_at":"2024-11-22T23:07:54.372Z","updated_at":"2026-02-13T12:53:13.608Z","avatar_url":"https://github.com/ecomclub.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Storefront theme\n\n## Pages\n1. [Storefront theme](./)\n2. [Template structure](./structure/)\n3. [JavaScript methods API](./methods/)\n4. [Implement a search engine](./search/)\n\n## Summary\n1. [Introduction](#introduction)\n2. [Getting started](#getting-started)\n    * [Renderization callback](#renderization-callback)\n3. [Guide](#guide)\n    * [App main element](#app-main-element)\n        * [Specifying store](#specifying-store)\n        * [Specifying language](#specifying-language)\n    * [Vue instances](#vue-instances)\n        * [Store API objects](#store-api-objects)\n            * [Object types](#object-types)\n            * [Store info sample](#store-info-sample)\n            * [Basic product sample](#basic-product-sample)\n            * [List of objects](#list-of-objects)\n            * [List of categories sample](#list-of-categories-sample)\n        * [Search API objects](#search-api-objects)\n            * [List items](#list-items)\n            * [Products list sample](#products-list-sample)\n            * [Search products by keyword](#search-products-by-keyword)\n            * [List items from category or brand](#list-items-from-category-or-brand)\n            * [List of specific products](#list-of-specific-products)\n        * [List products from collection](#list-products-from-collection)\n    * [Recommended CSS](#recommended-css)\n\n{% raw %}\n\n# Introduction\nThis document is intended to list predefined mustache tags,\nHTML classes and attributes, and\n\u003ca href=\"./methods/\"\u003eJavaScript methods\u003c/a\u003e\n(functions) for layout rendering with\n\u003ca href=\"https://github.com/ecomclub/ecomplus-store-render\" target=\"_blank\"\u003eecomplus-store-render\u003c/a\u003e.\n\n**It's possible to use any HTML template for E-Com Plus storefront.**\nAfter reading this documentation, you will be able to customize a theme\n(editing some elements only) or start a new theme from scratch.\n\nIf you want to create a new theme from scratch, be sure to follow\n\u003ca href=\"./structure/\"\u003ethis template structure\u003c/a\u003e.\n\nE-Com Plus storefront uses\n\u003ca href=\"https://vuejs.org/v2/guide/\" target=\"_blank\"\u003eVue.js 2\u003c/a\u003e framework, so\nstore template specifications follow the\n\u003ca href=\"https://vuejs.org/v2/guide/syntax.html\" target=\"_blank\"\u003eVue template syntax\u003c/a\u003e.\n\n\u003e After reading the docs,\n\u003e \u003ca href=\"https://github.com/ecomclub/ecomplus-store-template/wiki\" target=\"_blank\"\u003evisit the Wiki\u003c/a\u003e\n\u003e to make suggestions or contribute with documentation content and examples.\n\u003e If you need help, feel free to\n\u003e \u003ca href=\"https://github.com/ecomclub/ecomplus-store-template/issues\" target=\"_blank\"\u003eopen a new issue\u003c/a\u003e.\n\n# Getting started\nYour HTML file must include\n\u003ca href=\"https://vuejs.org/v2/\" target=\"_blank\"\u003eVue\u003c/a\u003e,\n\u003ca href=\"https://github.com/ecomclub/ecomplus-sdk-js\" target=\"_blank\"\u003estorefront JS SDK\u003c/a\u003e\nand the\n\u003ca href=\"https://github.com/ecomclub/ecomplus-store-render\" target=\"_blank\"\u003elayout renderer app\u003c/a\u003e.\nYou can include storefront \"all in one\" JS file **(recommended)**:\n\n```html\n\u003cscript src=\"https://ecvol.com/js/storefront@2/storefront.min.js\"\u003e\u003c/script\u003e\n```\n\nOr import the scripts one by one (not recommended):\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ecomplus-sdk@1/dist/sdk.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ecomplus-render@2/dist/render.min.js\"\u003e\u003c/script\u003e\n```\n\nThen, start the layout rendering with JS below:\n\n```javascript\nEcom.init()\n```\n\nThe scripts should be loaded after the HTML content of the page,\nso you have to put them before `\u003c/body\u003e` tag,\nwe also recommend to load them before other scripts,\nsuch as jQuery lib. Final example:\n\n```html\n\u003cbody\u003e\n  \u003c!-- HTML content --\u003e\n  \u003cscript src=\"https://ecvol.com/js/storefront@2/storefront.min.js\"\u003e\u003c/script\u003e\n  \u003cscript\u003e\n    Ecom.init()\n  \u003c/script\u003e\n  \u003c!-- Optionally, other JS --\u003e\n\u003c/body\u003e\n```\n\n## Renderization callback\nYou probably want to manipulate the rendered elements\nwith JavaScript (maybe with jQuery),\nto work properly, you must do this **after the renderization**.\n\nSend a\n\u003ca href=\"https://developer.mozilla.org/en-US/docs/Glossary/Callback_function\" target=\"_blank\"\u003ecallback function\u003c/a\u003e\nas first param of _init_ method:\n\n```javascript\nEcom.init(function () {\n  // handle events and effects with rendered elements\n})\n```\n\n# Guide\nHTML classes used by this library will be named with the prefix `_ecom-`,\ndata attributes may be used together with the classes in the elements.\n\n## App main element\nYour HTML must have an element\nwith class `_ecom-store`, it's **required**.\n\nAll Vue template must be inside this element,\nincluding all mustache tags and Vue HTML attributes,\nso probably it will be the `\u003cbody\u003e`, but it's not a rule, you can use\na `\u003cdiv\u003e`, `\u003cspan\u003e` or any other:\n\n```html\n\u003cbody class=\"_ecom-store\"\u003e\n  \u003c!-- HTML CODE --\u003e\n\u003c/body\u003e\n```\n\n### Specifying store\nBy default, store will be defined in function of the site domain,\nbut you can also use the attributes `data-store` and `data-id`\nwith your _Store ID_ and _Store Object ID_ respectively:\n\n```html\n\u003cdiv class=\"_ecom-store\" data-store=\"100\" data-id=\"5a674f224e0dcec2c3353d9d\"\u003e\n```\n\nIt's useful if the template is designed for one specific store only,\nor if you want to work with multiple stores in the same storefront.\n\n### Specifying language\nIf you don't want to use the store default language,\nyou can use the attribute `data-lang`:\n\n```html\n\u003cdiv class=\"_ecom-store\" data-lang=\"en_us\"\u003e\n```\n\nUse lowercase letters and separate lang of country (if any) by underline,\neg.: `pt_br`, `en_us`, `it`, `es`.\n\n## Vue instances\nEach HTML element with class `_ecom-el` will be an\n\u003ca href=\"https://vuejs.org/v2/guide/instance.html\" target=\"_blank\"\u003eVue instance\u003c/a\u003e.\nIt represents an object declaration, preceded of a REST API GET request.\n\nInside `._ecom-el` elements you can use mustache tags and any\n\u003ca href=\"https://vuejs.org/v2/guide/syntax.html\" target=\"_blank\"\u003eVue template\u003c/a\u003e\nattributes.\n\n### Store API objects\n\u003ca href=\"https://ecomstore.docs.apiary.io/\" target=\"_blank\"\u003eStore API\u003c/a\u003e requests\nare rendered from `._ecom-el` elements\nwith the attributes below:\n\n| Attribute   | Description |\n| :---:       | :---: |\n| `data-type` | Type of object, with one of [these values](#object-types) |\n| `data-id`   | API Object ID, the `_id` of the object you are getting from the API _(optional)_ |\n\nIn almost all cases, you will not create an HTML for each object,\nfor example, you will create only one HTML file for all products,\nnot one per product.\nIn these cases it's not possible to specify `data-id` (it's dynamic),\nlet the element without this attribute,\nID will be defined in function of page URL (slug).\n\nThe\n\u003ca href=\"https://vuejs.org/v2/guide/instance.html#Data-and-Methods\" target=\"_blank\"\u003einstance data\u003c/a\u003e\nwill be an object with `body` property, `body` is the object returned from\n\u003ca href=\"https://ecomstore.docs.apiary.io/\" target=\"_blank\"\u003eStore API\u003c/a\u003e,\nwith the same properties.\n\n#### Object types\nPossible values for `data-type`:\n\n| Type          | Object model |\n| :---:         | :---: |\n| `product`     | [Reference](https://ecomstore.docs.apiary.io/#reference/products/product-object) |\n| `brand`       | [Reference](https://ecomstore.docs.apiary.io/#reference/brands/brand-object) |\n| `category`    | [Reference](https://ecomstore.docs.apiary.io/#reference/categories/category-object) |\n| `collection`  | [Reference](https://ecomstore.docs.apiary.io/#reference/collections/collection-object) |\n| `customer`    | [Reference](https://ecomstore.docs.apiary.io/#reference/customers/customer-object) |\n| `cart`        | [Reference](https://ecomstore.docs.apiary.io/#reference/carts/cart-object) |\n| `order`       | [Reference](https://ecomstore.docs.apiary.io/#reference/orders/order-object) |\n| `application` | [Reference](https://ecomstore.docs.apiary.io/#reference/applications/application-object) |\n| `store`       | [Reference](https://ecomstore.docs.apiary.io/#reference/stores/store-object) |\n\n#### Store info sample\nThe example below shows some of the current store information:\n\n```html\n\u003cdiv class=\"footer _ecom-el\" data-type=\"store\"\u003e\n  \u003cdiv class=\"logo\" v-if=\"body.logo\"\u003e\n    \u003cimg v-bind:src=\"body.logo.url\" v-bind:alt=\"body.logo.alt\" v-bind:width=\"width(body.logo)\"\u003e\n  \u003c/div\u003e\n  \u003ch2 class=\"store-title\"\u003e {{ body.name }} \u003c/h2\u003e\n  \u003cp\u003e {{ body.description }} \u003c/p\u003e\n\u003c/div\u003e\n```\n\nIn the example above, Vue data (inside mustache tags and `v-*` attributes) have the\n\u003ca href=\"https://ecomstore.docs.apiary.io/#reference/stores/specific-store\" target=\"_blank\"\u003e\nproperties listed here\u003c/a\u003e,\nfollowing the store object model, but only with public data.\n\n#### Basic product sample\nThe example below is a simple implementation of a product page:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"product\"\u003e\n  \u003cdiv v-bind:class=\"'prod-' + body.sku\" v-if=\"body.visible\"\u003e\n    \u003cul\u003e\n      \u003cli v-for=\"picture in body.pictures\"\u003e\n        \u003cspan v-if=\"picture.big\"\u003e\n          \u003cimg v-if=\"picture.zoom\" v-bind:src=\"picture.big.url\" v-bind:alt=\"picture.big.alt\"\n            v-bind:data-zoom=\"picture.zoom.url\" /\u003e\n          \u003cimg v-else v-bind:src=\"picture.big.url\" v-bind:alt=\"picture.big.alt\" /\u003e\n        \u003c/span\u003e\n      \u003c/li\u003e\n    \u003c/ul\u003e\n    \u003ca v-bind:href=\"body.slug\"\u003e\n      \u003ch1\u003e {{ name() }} \u003c/h1\u003e\n    \u003c/a\u003e\n    \u003cp class=\"price-block\"\u003e\n      \u003cspan v-if=\"onPromotion()\"\u003e\n        {{ body.currency_symbol }}\n        \u003cstrong class=\"price\"\u003e {{ formatMoney(body.price) }} \u003c/strong\u003e\n        \u003cspan class=\"base-price\"\u003e {{ formatMoney(body.base_price) }} \u003c/span\u003e\n      \u003c/span\u003e\n      \u003cspan v-else\u003e\n        {{ body.currency_symbol }} \u003cstrong class=\"price\"\u003e {{ formatMoney(price()) }} \u003c/strong\u003e\n      \u003c/span\u003e\n    \u003c/p\u003e\n    \u003cdiv v-if=\"body.available\"\u003e\n      \u003cbutton v-if=\"inStock()\" class=\"buy\"\u003e Buy \u003c/button\u003e\n      \u003cdiv class=\"no-stock\" v-else\u003e Out of stock \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"description\"\u003e\n      {{ body.body_html }}\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nIf you are creating the HTML file for a specific product only,\nor embedding one product inside a custom page, you must set `data-id`\nwith the product ID:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"product\" data-id=\"123a5432109876543210cdef\"\u003e\n```\n\nVue data (inside mustache tags and `v-*` attributes) follows this\n\u003ca href=\"https://ecomstore.docs.apiary.io/#reference/products/product-object\" target=\"_blank\"\u003eobject reference\u003c/a\u003e.\n\nNote that you can use similar code for other types of objects (API resources).\n\n#### List of objects\nIt's possible to render a list of Store API\n\u003ca href=\"https://ecomstore.docs.apiary.io/#reference/categories/all-categories\" target=\"_blank\"\u003ecategories\u003c/a\u003e,\n\u003ca href=\"https://ecomstore.docs.apiary.io/#reference/brands/all-brands\" target=\"_blank\"\u003ebrands\u003c/a\u003e or\n\u003ca href=\"https://ecomstore.docs.apiary.io/#reference/collections/all-collections\" target=\"_blank\"\u003ecollections\u003c/a\u003e,\nto do that, you must add the attribute `data-list-all` to the `._ecom-el` element.\n\nThis is available only for elements with one of following `data-type`:\n\n| Type          | Object model |\n| :---:         | :---: |\n| `brand`       | [Reference](https://ecomstore.docs.apiary.io/#reference/brands/all-brands) |\n| `category`    | [Reference](https://ecomstore.docs.apiary.io/#reference/categories/all-categories) |\n| `collection`  | [Reference](https://ecomstore.docs.apiary.io/#reference/collections/all-collections) |\n\n#### List of categories sample\nThe example below is a simple implementation of a list of categories,\nup to 1000 objects, with random order,\nusing \u003ca href=\"https://vuejs.org/v2/guide/list.html\" target=\"_blank\"\u003eVue list\u003c/a\u003e:\n\n```html\n\u003cul class=\"_ecom-el\" data-type=\"category\" data-list-all=\"true\"\u003e\n  \u003cli v-for=\"category in body.result\"\u003e\n    \u003ca v-bind:href=\"category.slug\"\u003e\n      {{ category.name }}\n    \u003c/a\u003e\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\n\n##### Sort list alphabetically\nBy default, the objects are randomly ordered on the list,\nif you want alphabetical order, you can use the `alphabeticalSort` pre-built method:\n\n```html\n\u003cli v-for=\"category in alphabeticalSort(body.result)\"\u003e\n```\n\n### Search API objects\n\u003ca href=\"https://ecomsearch.docs.apiary.io/\" target=\"_blank\"\u003eSearch API\u003c/a\u003e requests\nare rendered from `._ecom-el` elements\nwith the `data-type` equal to `items` or `terms`,\nand other attributes depending of search case.\n\nThe\n\u003ca href=\"https://vuejs.org/v2/guide/instance.html#Data-and-Methods\" target=\"_blank\"\u003eVue instance data\u003c/a\u003e\nwill be an object with `body` property, `body` is the object returned from\n\u003ca href=\"https://ecomsearch.docs.apiary.io/\" target=\"_blank\"\u003eSearch API\u003c/a\u003e,\nwith the same properties.\n\n#### List items\nTo list products, `data-type` must be equal to `items`.\nYou can get more info and example of returned object from\n\u003ca href=\"https://ecomsearch.docs.apiary.io/#reference/items\" target=\"_blank\"\u003eAPI reference\u003c/a\u003e.\n\nThe `._ecom-el` element must also have the following attributes:\n\n| Attribute         | Description |\n| :---:             | :---: |\n| `data-type`       | Equal to `items` |\n| `data-term`       | Searched keyword _(optional)_ |\n| `data-from`       | Results offset number _(optional)_ |\n| `data-size`       | Maximum number of results _(optional)_ |\n| `data-sort`       | Results ordering, one of [these enumered values](#sort-items-search-result) _(optional)_ |\n| `data-ids`        | Filter by specific products IDs separated by `,` _(optional)_ |\n| `data-brands`     | Filter by list of brands IDs separated by `,` _(optional)_ |\n| `data-categories` | Filter by list of categories IDs separated by `,` _(optional)_ |\n| `data-price-min`  | Filter by minimum price _(optional)_ |\n| `data-price-max`  | Filter by maximum price _(optional)_ |\n| `data-spec-*`     | Filter by product specification _(optional)_ |\n\n#### Products list sample\nThe example below is a simple implementation of a list of trending products,\nusing \u003ca href=\"https://vuejs.org/v2/guide/list.html\" target=\"_blank\"\u003eVue list\u003c/a\u003e:\n\n```html\n\u003cdiv class=\"row _ecom-el\" data-type=\"items\"\u003e\n  \u003cdiv class=\"col-md-2\" v-for=\"item in body.hits.hits\"\u003e\n    \u003cdiv v-if=\"item = item._source\" class=\"item\"\u003e\n      \u003cdiv v-if=\"item.pictures \u0026\u0026 item.pictures[0] \u0026\u0026 item.pictures[0].normal\" class=\"item-img\"\u003e\n        \u003cimg v-bind:src=\"item.pictures[0].normal.url\" v-bind:alt=\"item.pictures[0].normal.alt\" /\u003e\n      \u003c/div\u003e\n      \u003ca v-bind:href=\"item.slug\"\u003e\n        \u003ch3\u003e {{ name(item) }} \u003c/h3\u003e\n      \u003c/a\u003e\n      \u003cp class=\"price-block\"\u003e\n        \u003cspan v-if=\"onPromotion(item)\"\u003e\n          {{ item.currency_symbol }}\n          \u003cstrong class=\"price\"\u003e {{ formatMoney(item.price) }} \u003c/strong\u003e\n          \u003cspan class=\"base-price\"\u003e {{ formatMoney(item.base_price) }} \u003c/span\u003e\n        \u003c/span\u003e\n        \u003cspan v-else\u003e\n          {{ item.currency_symbol }}\n          \u003cstrong class=\"price\"\u003e {{ formatMoney(price(item)) }} \u003c/strong\u003e\n        \u003c/span\u003e\n      \u003c/p\u003e\n      \u003cspan v-if=\"item.available\"\u003e\n        \u003cbutton v-if=\"inStock(item)\" class=\"buy\"\u003e Buy \u003c/button\u003e\n        \u003cspan class=\"no-stock\" v-else\u003e Out of stock \u003c/span\u003e\n      \u003c/span\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nIt's possible to specify the maximum number of listed items with `data-size`,\nthe example below will list up to 12 most popular items:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-size=\"12\"\u003e\n```\n\nFor pagination, you should use data-from (offset) together with data-size (limit).\nThe example below will list up to 12 items, starting from the 24º,\nso, from 24º to 36º:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-from=\"24\" data-size=\"12\"\u003e\n```\n\n##### Sort items search result\nBy default, items will be ordered by popularity (number of page views),\nbut you can use custom sort with `data-sort` attribute:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-sort=\"1\"\u003e\n```\n\nIt must have one of the number values below:\n\n| Enum | Description |\n| :--: | :---: |\n| `1`  | Sort by sales, products that sells more appear first |\n| `2`  | Sort by price ascending, products with lowest price appear first |\n| `3`  | Sort by price descending, products with highest price appear first |\n| `4`  | Sort by creation date, new products appear first |\n\n#### Search products by keyword\nTo find products searching by name and/or keywords, you can use `data-term`:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-term=\"tshirt\"\u003e\n```\n\n\u003ca href=\"./search/\"\u003eHere\u003c/a\u003e\nyou can check an complete example of store search engine implementation.\n\n#### Filter items by specifications\nIt's possible to filter the resultant items list by product specs,\nadding attributes of type `data-spec-*`, where the wildcard must be replaced\nby the specification (property name):\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-spec-colors=\"Blue\" data-spec-size=\"M\"\u003e\n```\n\n#### List items from category or brand\nTo list products from specific categories you should use\n`data-categories` attribute.\n\nFollowing example will list items from one category only, but you can\nspecify more than one by separating categories IDs with `,` (comma):\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-categories=\"f10000000000000000000001\"\u003e\n```\n\nSimilar to categories, you can list products from specific brands using\n`data-brands` attribute:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-brands=\"a10000000000000000000001\"\u003e\n```\n\n#### List of specific products\nYou can also list specific items using the `data-ids` attribute, where\nyou should put the IDs of respective products separated by comma:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"items\" data-ids=\"1234567890abcdef01291510,1234567890abcdef01291511\"\u003e\n```\n\nNote that you can combine the attributes from all above\nsearch and list examples to fit your needs.\n\n### List products from collection\nTo list products of a collection you have to use both\n[Store API](#store-api-objects) and [Search API](#search-api-objects).\n\nThe notation is such as the example below:\n\n```html\n\u003cdiv class=\"_ecom-el\" data-type=\"collection\" data-id=\"c92000000000000000001111\"\n  data-list=\"products\" data-size=\"12\"\u003e\n  \u003ca v-bind:href=\"body.slug\"\u003e\n    \u003ch3 class=\"coll-name\"\u003e {{ body.name }} \u003c/h3\u003e\n  \u003c/a\u003e\n  \u003cul\u003e\n    \u003cli v-for=\"item in body.hits.hits\"\u003e\n      \u003cdiv v-if=\"item = item._source\" class=\"item\"\u003e\n        \u003cdiv v-if=\"item.pictures \u0026\u0026 item.pictures[0] \u0026\u0026 item.pictures[0].normal\" class=\"item-img\"\u003e\n          \u003cimg v-bind:src=\"item.pictures[0].normal.url\" v-bind:alt=\"item.pictures[0].normal.alt\" /\u003e\n        \u003c/div\u003e\n        \u003ca v-bind:href=\"item.slug\"\u003e\n          \u003ch4\u003e {{ name(item) }} \u003c/h4\u003e\n        \u003c/a\u003e\n        \u003cp\u003e SKU: {{ item.sku }} \u003c/p\u003e\n        \u003cp class=\"price-block\"\u003e\n          \u003cspan v-if=\"onPromotion(item)\"\u003e\n            {{ item.currency_symbol }}\n            \u003cstrong class=\"price\"\u003e {{ formatMoney(item.price) }} \u003c/strong\u003e\n            \u003cspan class=\"base-price\"\u003e {{ formatMoney(item.base_price) }} \u003c/span\u003e\n          \u003c/span\u003e\n          \u003cspan v-else\u003e\n            {{ item.currency_symbol }}\n            \u003cstrong class=\"price\"\u003e {{ formatMoney(price(item)) }} \u003c/strong\u003e\n          \u003c/span\u003e\n        \u003c/p\u003e\n        \u003cbutton v-if=\"inStock(item)\" class=\"buy\"\u003e Buy \u003c/button\u003e\n        \u003cspan class=\"no-stock\" v-else\u003e Out of stock \u003c/span\u003e\n      \u003c/div\u003e\n    \u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/div\u003e\n```\n\nIn these cases you must use `data-type` and `data-id` as expected\nfor a [Store API object](#store-api-objects).\nYou also have to use the attribute `data-list` with\nvalue `products`, by doing this, you will be listing the\ncollection products by IDs such as a [Search API object](#search-api-objects).\n\nIn addition, you can use the other\n[attributes for a Search API items list](#list-items),\nsuch as the `data-size` used in the above example.\n\n## Recommended CSS\nAfter the renderization of each `._ecom-el` element,\nthe class `rendered` is automatically added, to hide the non-rendered elements\nwe recommend to use the following styles:\n\n```css\n._ecom-el {\n  opacity: 0;\n}\n._ecom-el.rendered {\n  opacity: 1;\n}\n```\n\nIf you want to use fade effect:\n\n```css\n._ecom-el {\n  opacity: 0;\n}\n._ecom-el.rendered {\n  opacity: 1;\n  animation: fadein 1s;\n  -moz-animation: fadein 1s;\n  -webkit-animation: fadein 1s;\n  -o-animation: fadein 1s;\n}\n@keyframes fadein {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n/* Firefox */\n@-moz-keyframes fadein {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n/* Safari and Chrome */\n@-webkit-keyframes fadein {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n/* Opera */\n@-o-keyframes fadein {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n```\n\nOf course you can change the animation time from 1s to what you want.\n\n{% endraw %}\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecomclub%2Fecomplus-store-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecomclub%2Fecomplus-store-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecomclub%2Fecomplus-store-template/lists"}