From 23543dadbbd2f1b740897d4eddbcf8de3a6c741d Mon Sep 17 00:00:00 2001 From: EndPositive Date: Wed, 5 Feb 2020 22:25:04 +0100 Subject: [PATCH 1/8] Add price formatting --- config/default.json | 4 +++- core/filters/price.js | 30 ++++++++++++------------------ package.json | 1 + 3 files changed, 16 insertions(+), 19 deletions(-) mode change 100755 => 100644 package.json diff --git a/config/default.json b/config/default.json index 0af74022fc..61edb4dd1e 100644 --- a/config/default.json +++ b/config/default.json @@ -484,7 +484,9 @@ "defaultLocale": "en-US", "currencyCode": "USD", "currencySign": "$", - "priceFormat": "{sign}{amount}", + "currencyDecimal": null, + "currencyGroup": null, + "currencyPattern": null, "dateFormat": "HH:mm D/M/YYYY", "fullCountryName": "United States", "fullLanguageName": "English", diff --git a/core/filters/price.js b/core/filters/price.js index 36673f495e..99cd575b16 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -1,14 +1,5 @@ import { currentStoreView } from '@vue-storefront/core/lib/multistore' - -const formatValue = (value, locale) => { - const price = Math.abs(parseFloat(value)) - const formatter = new Intl.NumberFormat(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) - return formatter.format(price) -} - -const applyCurrencySign = (formattedPrice, { currencySign, priceFormat }) => { - return priceFormat.replace('{sign}', currencySign).replace('{amount}', formattedPrice) -} +import CurrencyFormatter from 'currencyformatter.js' /** * Converts number to price string @@ -23,14 +14,17 @@ export function price (value, storeView) { return value; } - const { defaultLocale, currencySign, priceFormat } = _storeView.i18n + let { defaultLocale, currencyCode, currencySign, currencyPattern, currencyDecimal, currencyGroup } = _storeView.i18n; - const formattedValue = formatValue(value, defaultLocale) - const valueWithSign = applyCurrencySign(formattedValue, { currencySign, priceFormat }) + const separatorIndex = defaultLocale.indexOf('-'); + const languageCode = (separatorIndex > -1) ? defaultLocale.substr(0, separatorIndex) : defaultLocale; - if (value >= 0) { - return valueWithSign - } else { - return '-' + valueWithSign - } + return CurrencyFormatter.format(value, { + currencyCode: currencyCode, + symbol: currencySign, + locale: languageCode, + decimal: currencyDecimal, + group: currencyGroup, + pattern: currencyPattern + }); } diff --git a/package.json b/package.json old mode 100755 new mode 100644 index b19530b1fa..97733b7115 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "bodybuilder": "2.2.13", "config": "^1.30.0", "cross-env": "^3.1.4", + "currencyformatter.js": "^2.2.0", "dayjs": "^1.8.15", "es6-promise": "^4.2.4", "express": "^4.14.0", From 4d1967368ea628a3a14b5c8d47fcb94ea14cc426 Mon Sep 17 00:00:00 2001 From: EndPositive Date: Wed, 5 Feb 2020 22:29:53 +0100 Subject: [PATCH 2/8] Change let to const in price formatting --- core/filters/price.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/filters/price.js b/core/filters/price.js index 99cd575b16..11f1e5c3da 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -14,7 +14,7 @@ export function price (value, storeView) { return value; } - let { defaultLocale, currencyCode, currencySign, currencyPattern, currencyDecimal, currencyGroup } = _storeView.i18n; + const { defaultLocale, currencyCode, currencySign, currencyPattern, currencyDecimal, currencyGroup } = _storeView.i18n; const separatorIndex = defaultLocale.indexOf('-'); const languageCode = (separatorIndex > -1) ? defaultLocale.substr(0, separatorIndex) : defaultLocale; From 42540f19259c8f168d688ed2cf3bbdf83ff9a72e Mon Sep 17 00:00:00 2001 From: EndPositive Date: Wed, 5 Feb 2020 22:59:59 +0100 Subject: [PATCH 3/8] Update Changelog and Upgrade notes --- CHANGELOG.md | 1 + docs/guide/upgrade-notes/README.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca4e2c4a4..e6c013b39c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `Intl.NumberFormat()`/`toLocaleString()` via polyfill support in NodeJs - @cewald (#3836, #4040) - Added `saveBandwidthOverCache` parameter for skipping caching for products data - @andrzejewsky (#3706) - New zoom effect for product gallery images - @Michal-Dziedzinski (#2755) +- Add custom currency formats - @EndPositive (#3553) ### Fixed - Fixed Search product fails for category filter when categoryId is string - @adityasharma7 (#3929) diff --git a/docs/guide/upgrade-notes/README.md b/docs/guide/upgrade-notes/README.md index fb5366d527..8a88f93173 100644 --- a/docs/guide/upgrade-notes/README.md +++ b/docs/guide/upgrade-notes/README.md @@ -16,6 +16,9 @@ This new `api-search-query` adapter supports the `response_format` query paramet The `amp-renderer` module has been disabled by default to save the bundle size; If you'd like to enable it uncomment the module from the `src/modules` and uncomment the `product-amp` and `category-amp` links that are added to the `` section in the `src/themes/default/Product.vue` and `src/themes/default/Category.vue` +**Replace priceFormat by currencyPattern** + +The new `price` filter now allows much more customisation. If you were using `priceFormat` to place the currency sign behind the value, you should use `currencyPattern` and set it to a custom currency format string such as `#,##0.00!`. ## 1.10 -> 1.11 From 55f459e59d9ac7c241b422ad7557e5608c5786fa Mon Sep 17 00:00:00 2001 From: EndPositive Date: Wed, 5 Feb 2020 23:35:12 +0100 Subject: [PATCH 4/8] Add module to yarn.lock --- yarn.lock | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/yarn.lock b/yarn.lock index 87347bf2c4..6968361f88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5188,6 +5188,11 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" +currencyformatter.js@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/currencyformatter.js/-/currencyformatter.js-2.2.0.tgz#ffafd871bbc92127cadf55588e64026cab78d8b0" + integrity sha512-kfMfQBOsK9vnzqUT7pQY+I6ZTM7VWkICwiFUOLPLpOzR5Ir+AUoa1kO7I1clsiHXYe1FPyX91BRWBgHOUEH/NQ== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" From c9c04c61b3388221862a4e31ee8de5cd66803f99 Mon Sep 17 00:00:00 2001 From: EndPositive Date: Fri, 7 Feb 2020 21:08:30 +0100 Subject: [PATCH 5/8] Remove priceformatting.js, introduce fractionDigits and bring back priceFormat. --- CHANGELOG.md | 2 +- config/default.json | 3 +- core/filters/price.js | 44 ++++++++++++++++++++++-------- docs/guide/upgrade-notes/README.md | 4 --- package.json | 1 - yarn.lock | 5 ---- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c013b39c..9f4b732fdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `Intl.NumberFormat()`/`toLocaleString()` via polyfill support in NodeJs - @cewald (#3836, #4040) - Added `saveBandwidthOverCache` parameter for skipping caching for products data - @andrzejewsky (#3706) - New zoom effect for product gallery images - @Michal-Dziedzinski (#2755) -- Add custom currency formats - @EndPositive (#3553) +- Add custom currency separators and amount of fraction digits - @EndPositive (#3553) ### Fixed - Fixed Search product fails for category filter when categoryId is string - @adityasharma7 (#3929) diff --git a/config/default.json b/config/default.json index 61edb4dd1e..c409f6ac07 100644 --- a/config/default.json +++ b/config/default.json @@ -486,7 +486,8 @@ "currencySign": "$", "currencyDecimal": null, "currencyGroup": null, - "currencyPattern": null, + "fractionDigits": 2, + "priceFormat": "{sign}{amount}", "dateFormat": "HH:mm D/M/YYYY", "fullCountryName": "United States", "fullLanguageName": "English", diff --git a/core/filters/price.js b/core/filters/price.js index 11f1e5c3da..6e8720e0a6 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -1,5 +1,21 @@ import { currentStoreView } from '@vue-storefront/core/lib/multistore' -import CurrencyFormatter from 'currencyformatter.js' + +const applyCurrencySign = (formattedPrice, { currencySign, priceFormat }) => { + return priceFormat.replace('{sign}', currencySign).replace('{amount}', formattedPrice) +}; + +const getLocaleSeparators = (defaultLocale) => { + return { + decimal: (0.01).toLocaleString(defaultLocale).replace(/[0-9]/g, ''), + group: (1000).toLocaleString(defaultLocale).replace(/[0-9]/g, '') + } +}; + +const replaceSeparators = (formattedPrice, currencySeparators, separators) => { + if (currencySeparators.decimal) formattedPrice = formattedPrice.replace(separators.decimal, currencySeparators.decimal); + if (currencySeparators.group) formattedPrice = formattedPrice.replace(separators.group, currencySeparators.group); + return formattedPrice; +}; /** * Converts number to price string @@ -14,17 +30,21 @@ export function price (value, storeView) { return value; } - const { defaultLocale, currencyCode, currencySign, currencyPattern, currencyDecimal, currencyGroup } = _storeView.i18n; + const { defaultLocale, currencySign, currencyDecimal, currencyGroup, fractionDigits, priceFormat } = _storeView.i18n; - const separatorIndex = defaultLocale.indexOf('-'); - const languageCode = (separatorIndex > -1) ? defaultLocale.substr(0, separatorIndex) : defaultLocale; + const options = { minimumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits }; - return CurrencyFormatter.format(value, { - currencyCode: currencyCode, - symbol: currencySign, - locale: languageCode, - decimal: currencyDecimal, - group: currencyGroup, - pattern: currencyPattern - }); + const localePrice = value.toLocaleString(defaultLocale, options); + + let formattedPrice; + if (currencyDecimal || currencyGroup) { + formattedPrice = replaceSeparators(localePrice, { decimal: currencyDecimal, group: currencyGroup }, getLocaleSeparators(defaultLocale)); + } + const valueWithSign = applyCurrencySign(formattedPrice, { currencySign, priceFormat }); + + if (value >= 0) { + return valueWithSign + } else { + return '-' + valueWithSign + } } diff --git a/docs/guide/upgrade-notes/README.md b/docs/guide/upgrade-notes/README.md index 8a88f93173..a573fd3051 100644 --- a/docs/guide/upgrade-notes/README.md +++ b/docs/guide/upgrade-notes/README.md @@ -16,10 +16,6 @@ This new `api-search-query` adapter supports the `response_format` query paramet The `amp-renderer` module has been disabled by default to save the bundle size; If you'd like to enable it uncomment the module from the `src/modules` and uncomment the `product-amp` and `category-amp` links that are added to the `` section in the `src/themes/default/Product.vue` and `src/themes/default/Category.vue` -**Replace priceFormat by currencyPattern** - -The new `price` filter now allows much more customisation. If you were using `priceFormat` to place the currency sign behind the value, you should use `currencyPattern` and set it to a custom currency format string such as `#,##0.00!`. - ## 1.10 -> 1.11 This is the last major release of Vue Storefront 1.x before 2.0 therefore more manual updates are required to keep external packages compatible with 1.x as long as possible. diff --git a/package.json b/package.json index 97733b7115..b19530b1fa 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "bodybuilder": "2.2.13", "config": "^1.30.0", "cross-env": "^3.1.4", - "currencyformatter.js": "^2.2.0", "dayjs": "^1.8.15", "es6-promise": "^4.2.4", "express": "^4.14.0", diff --git a/yarn.lock b/yarn.lock index 6968361f88..87347bf2c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5188,11 +5188,6 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" -currencyformatter.js@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/currencyformatter.js/-/currencyformatter.js-2.2.0.tgz#ffafd871bbc92127cadf55588e64026cab78d8b0" - integrity sha512-kfMfQBOsK9vnzqUT7pQY+I6ZTM7VWkICwiFUOLPLpOzR5Ir+AUoa1kO7I1clsiHXYe1FPyX91BRWBgHOUEH/NQ== - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" From 7a5203c805931d0bbbf396b762f28f9785a4bc04 Mon Sep 17 00:00:00 2001 From: EndPositive Date: Sat, 8 Feb 2020 13:38:27 +0100 Subject: [PATCH 6/8] Update setup.md and types.ts. --- core/lib/types.ts | 3 + docs/guide/cookbook/setup.md | 371 ++++++++++++++++++----------------- 2 files changed, 190 insertions(+), 184 deletions(-) diff --git a/core/lib/types.ts b/core/lib/types.ts index 692e9add39..999db289f2 100644 --- a/core/lib/types.ts +++ b/core/lib/types.ts @@ -35,6 +35,9 @@ export interface StoreView { defaultLocale: string, currencyCode: string, currencySign: string, + currencyDecimal: string, + currencyGroup: string, + fractionDigits: number, priceFormat: string, dateFormat: string }, diff --git a/docs/guide/cookbook/setup.md b/docs/guide/cookbook/setup.md index 24c2e4fdf4..e892944387 100644 --- a/docs/guide/cookbook/setup.md +++ b/docs/guide/cookbook/setup.md @@ -5,7 +5,7 @@ } -In this chapter, we will cover : +In this chapter, we will cover : [[toc]] @@ -14,23 +14,23 @@ In this chapter, we will cover : Now you are definitely interested in **Vue Storefront**. That's why you are here. You've come across the line. You made a choice. You will have something in return, which is great. Be it developers, entrepreneurs or even marketing managers that they may want to try something new for better products in hopes of enhancing their clients or customers' experience. You chose the right path. We will explore anything you need to get you started at all with [**Vue Storefront** infrastructure](https://github.com/DivanteLtd). ## 1. Install with Docker -Docker has been arguably the most sought-after, brought to the market which took the community by storm ever since its introduction. Although it's yet controversial whether it's the best choice among its peers, I have never seen such an unanimous enthusiasm over one tech product throughout the whole developers community. +Docker has been arguably the most sought-after, brought to the market which took the community by storm ever since its introduction. Although it's yet controversial whether it's the best choice among its peers, I have never seen such an unanimous enthusiasm over one tech product throughout the whole developers community. -Then, why so? In modern computer engineering, products are so complex with an endless list of dependencies intertwined with each other. Building such dependencies in place for every occasion where it's required is one hell of a job, not to mention glitches from all the version variation. That's where Docker steps in to make you achieve **infrastructure automation**. This concept was conceived to help you focus on your business logic rather than having you stuck with hassles of lower level tinkering. +Then, why so? In modern computer engineering, products are so complex with an endless list of dependencies intertwined with each other. Building such dependencies in place for every occasion where it's required is one hell of a job, not to mention glitches from all the version variation. That's where Docker steps in to make you achieve **infrastructure automation**. This concept was conceived to help you focus on your business logic rather than having you stuck with hassles of lower level tinkering. Luckily, we already have been through all this for you, got our hands dirty. All you need is run a set of docker commands to get you up and running from scratch. Without further ado, let's get started! ### 1. Preparation -- You need [`docker`](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04) and [`docker-compose`](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04) installed. +- You need [`docker`](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04) and [`docker-compose`](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04) installed. - You need [`git`](https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-18-04) installed. :::tip NOTE We will walk you with docker on *Linux*. (Specifically *Ubuntu 18.04* if needed) -There is only one bias for Docker before using it; *Run it on Linux*. Docker is native Linux, was created using a Linux technology; LXC (linux container) in the first place. Even though there were many attempts made to make it available to other platforms as it does on Linux, and it has definitely been on a progress, however, using Docker on Linux is the solidest way to deal with the technology. +There is only one bias for Docker before using it; *Run it on Linux*. Docker is native Linux, was created using a Linux technology; LXC (linux container) in the first place. Even though there were many attempts made to make it available to other platforms as it does on Linux, and it has definitely been on a progress, however, using Docker on Linux is the solidest way to deal with the technology. -That being sad, there are tips for using other platforms for docker at [Chef's Secrets](#_4-chef-s-secret-protip) as well. +That being sad, there are tips for using other platforms for docker at [Chef's Secrets](#_4-chef-s-secret-protip) as well. ::: ### 2. Recipe @@ -44,19 +44,19 @@ cd vue-storefront-api ```bash cp config/default.json config/local.json ``` -Then edit `local.json` to your need. +Then edit `local.json` to your need. We will look into this in greater detail at [Chef's secret](#_4-chef-s-secret-protip) :::tip TIP This step can be skipped if you are OK with values of `default.json` since it follows the [files load order](https://github.com/lorenwest/node-config/wiki/Configuration-Files#file-load-order) of [node-config](https://github.com/lorenwest/node-config) ::: -3. Run the following Docker command : +3. Run the following Docker command : ```bash docker-compose -f docker-compose.yml -f docker-compose.nodejs.yml up -d ``` -Then the result would look something like this : +Then the result would look something like this : ```bash Building app Step 1/8 : FROM node:10-alpine @@ -107,10 +107,10 @@ warning eslint > file-entry-cache > flat-cache > circular-json@0.3.3: CircularJS ::: 3. In order to verify, run `docker ps` to show which containers are up ```bash -docker ps +docker ps ``` -Then, +Then, ```bash CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 53a47d5a6440 vuestorefrontapi_kibana "/bin/bash /usr/loca…" 31 seconds ago Up 29 seconds 0.0.0.0:5601->5601/tcp vuestorefrontapi_kibana_1 @@ -118,7 +118,7 @@ CONTAINER ID IMAGE COMMAND CREATED 165ae945dbe5 vuestorefrontapi_es1 "/bin/bash bin/es-do…" 8 days ago Up 30 seconds 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch 8dd144746cef redis:4-alpine "docker-entrypoint.s…" 11 days ago Up 31 seconds 0.0.0.0:6379->6379/tcp vuestorefrontapi_redis_1 ``` -The ports number will be used later in the frontend configuration. In fact, they are already set in as default values. +The ports number will be used later in the frontend configuration. In fact, they are already set in as default values. You will see 4 containers are running, which is : | Container | Port | @@ -141,13 +141,13 @@ cd vue-storefront cp config/default.json config/local.json ``` Then fix the value as you need it in the `local.json` file. -In `local.json`, you may change values for information of backend family. But if you followed this recipe verbatim, you don't have to, because it's already there with the default value. Should you study the contents, please see to [Chef's secret](#secret-1-study-in-local-json) +In `local.json`, you may change values for information of backend family. But if you followed this recipe verbatim, you don't have to, because it's already there with the default value. Should you study the contents, please see to [Chef's secret](#secret-1-study-in-local-json) -6. Finally run the following Docker command : +6. Finally run the following Docker command : ```bash -docker-compose up -d +docker-compose up -d ``` -The result should be something like this : +The result should be something like this : ```bash Building app Step 1/8 : FROM node:10-alpine @@ -200,22 +200,22 @@ de560221fdaf vuestorefrontapi_kibana "/bin/bash /usr/loca…" 8 hours d46c1e0a22af redis:4-alpine "docker-entrypoint.s…" 8 hours ago Up 24 minutes 0.0.0.0:6379->6379/tcp vuestorefrontapi_redis_1 ``` -8. Open your browser and visit [http://localhost:3000/](http://localhost:3000/) +8. Open your browser and visit [http://localhost:3000/](http://localhost:3000/) After compiling, *Voila!* ![vs_home_intro_borderline](../images/home-vuestorefront.png) -### 3. Peep into the kitchen (what happens internally) +### 3. Peep into the kitchen (what happens internally) We used `docker-compose` for setting up the entire environment of Vue Storefront. It was more than enough to launch the machines behind for running the shop. -It was possible because `docker` encapsulated the whole bunch of infrastructure into a linear set of declarative definition for the desired state. +It was possible because `docker` encapsulated the whole bunch of infrastructure into a linear set of declarative definition for the desired state. We had 2 steps of `docker-compose` one of which is for backend **Vue Storefront API**, the other for frontend **Vue Storefront**. The first `docker-compose` had two `yml` files for input. The first input file `docker-compose.yml` describe its base requirement all but **Vue Storefront API** itself; that is, **Elasticsearch** as data store, **Redis** for cache and **Kibana** for helping you grab your data visually (a pair of Elasticsearch). ```yaml -# docker-compose.yml +# docker-compose.yml version: '3.0' services: es1: @@ -247,10 +247,10 @@ services: volumes: esdat1: ``` -:::tip NOTE +:::tip NOTE Once a term explained, it will be ignored thereafter for consecutive occurrence. ::: -`version` denotes which version of `docker-compose` this file uses. +`version` denotes which version of `docker-compose` this file uses. `services` describe containers. It codifies how they should run. In other words, it codifies option flags used with `docker run ...` @@ -258,21 +258,21 @@ Once a term explained, it will be ignored thereafter for consecutive occurrence. - `build` denotes build path of container. - `volumes` contains the mount path of volumes shared between host and container as *host:container* - `ports` connect ports between host and container as in *host:container* -- `environment` allows you to add environment variables. `Xmx512m` means JVM will take up to maximum 512MB memory. `Xms512m` means minimum memory. Combining them, there will be no memory resize, it will just stick to 512MB from start to end throughout its life cycle. +- `environment` allows you to add environment variables. `Xmx512m` means JVM will take up to maximum 512MB memory. `Xms512m` means minimum memory. Combining them, there will be no memory resize, it will just stick to 512MB from start to end throughout its life cycle. `kibana` contains information of *Kibana* application container. -- `depends_on` creates dependency for a container of other containers. So, this container is dependent on `es1` that's just described above. -- `volumes` mean volumes shared, `:ro` creates the volume in `read-only` mode for the container. +- `depends_on` creates dependency for a container of other containers. So, this container is dependent on `es1` that's just described above. +- `volumes` mean volumes shared, `:ro` creates the volume in `read-only` mode for the container. -`redis` contains information of *Redis* cache application container. +`redis` contains information of *Redis* cache application container. -- `image` node contains the name of image this container is based on. +- `image` node contains the name of image this container is based on. -`volumes` in top level can be used as a reference to be used across multiple services(containers). +`volumes` in top level can be used as a reference to be used across multiple services(containers).

-The second input file `docker-compose.nodejs.yml` deals with **Vue Storefront API** node application. +The second input file `docker-compose.nodejs.yml` deals with **Vue Storefront API** node application. ```yaml version: '3.0' services: @@ -301,17 +301,17 @@ services: ports: - '8080:8080' ``` -`app` contains information of *Vue Storefront API* application. +`app` contains information of *Vue Storefront API* application. - `build` is path for build information. If the value is string, it's a plain path. When it's object, you may have a few options to add. `context` is relative path or git repo url where `Dockerfile` is located. `dockerfile` node may change the path/name of `Dockerfile`. [more info](https://docs.docker.com/compose/compose-file/#build) -- `depends_on` tells us this container is based on `es1` and `redis` containers we created above. -- `env_file` helps you add environment values from files. It's relative path from the `docker-compose` file that is in the process, in this case, it's `docker-compose.nodejs.yml` -- `environment` is to set `VS_ENV` as `dev` so that environment will be setup for developer mode. +- `depends_on` tells us this container is based on `es1` and `redis` containers we created above. +- `env_file` helps you add environment values from files. It's relative path from the `docker-compose` file that is in the process, in this case, it's `docker-compose.nodejs.yml` +- `environment` is to set `VS_ENV` as `dev` so that environment will be setup for developer mode. - `tmpfs` denotes temporary volumes that are only available to host memory. Unlike `volumes`, this `tmpfs` will be gone once the container stops. This option is only available to *Linux*.

-The second `docker-compose` step handles **Vue Storefront** frontend. +The second `docker-compose` step handles **Vue Storefront** frontend. ``` yaml version: '2.0' services: @@ -343,32 +343,32 @@ services: ports: - '3000:3000' ``` -This looks like by and large the same with *Vue Storefront API* with a few changes. +This looks like by and large the same with *Vue Storefront API* with a few changes. `app` service describes options for *Vue Storefront* frontend application. - `network_mode` allows you to modify values for `--network` option of docker client. `host` option allows your designated container to open to host network. For example, if you bind your container in host's `80` port, then the container will be accessible at host's `:80` from the internet. In other words, the container is not isolated. [more info](https://docs.docker.com/network/host/) -If you take a closer look inside `Dockerfile`s, you will notice they install all the dependencies of the project from `package.json` not to mention required OS features including `git`, `wget` and certificates. You don't have to worry what to do because we made it do for you. +If you take a closer look inside `Dockerfile`s, you will notice they install all the dependencies of the project from `package.json` not to mention required OS features including `git`, `wget` and certificates. You don't have to worry what to do because we made it do for you. -Next, you might want to import your goods data. Please jump to [Data imports](./data-import.md) if you don't want to stop. +Next, you might want to import your goods data. Please jump to [Data imports](./data-import.md) if you don't want to stop. ### 4. Chef's secret (protip) #### Secret 1. Study in `local.json` for *Vue Storefront API* -Starting point of customization is `default.json` or its copy `local.json` where the platform seeks configuration values. +Starting point of customization is `default.json` or its copy `local.json` where the platform seeks configuration values. :::tip NOTE If you want to modify `default.json`, don't edit it directly but copy the whole file into `local.json` and start editing it in that file. Why it should be done that way is explained later at [Secret 3. Why use node-config?](#secret-3-why-use-node-config) ::: -We have 2 `local.json` files, one of which is for backend here, and we will look at [Secret 2](#secret-2-study-in-local-json-for-vue-storefront), the other for frontend . +We have 2 `local.json` files, one of which is for backend here, and we will look at [Secret 2](#secret-2-study-in-local-json-for-vue-storefront), the other for frontend . -At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue-storefront-api/blob/master/config/default.json) for **backend** : +At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue-storefront-api/blob/master/config/default.json) for **backend** : ```json "server": { "host": "localhost", "port": 8080, "searchEngine": "elasticsearch" - }, + }, ``` -- This is where your API backend is defined. The server will listen `server.host`:`server.port` unless it's defined otherwise in environment variables. +- This is where your API backend is defined. The server will listen `server.host`:`server.port` unless it's defined otherwise in environment variables. - `server.searchEngine` is used in the integration with `graphql` so please don't change it. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/graphql/resolvers.js#L6) ```json @@ -381,7 +381,7 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- ``` - `orders.useServerQueue` allows you to use queue process when `order` API is used to create an order. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/order.js#L65) -- `catalog.excludeDisabledProducts` allows you to skip disabled products when importing products using `mage2vs`. +- `catalog.excludeDisabledProducts` allows you to skip disabled products when importing products using `mage2vs`. [jump to code](https://github.com/DivanteLtd/mage2vuestorefront/blob/master/src/adapters/magento/product.js#L166) ```json @@ -408,21 +408,21 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- "apiVersion": "5.6" }, ``` -- `elasticsearch` element is used widely across the whole platform. Considering `elasticsearch` works as a data store (database), it's natural. +- `elasticsearch` element is used widely across the whole platform. Considering `elasticsearch` works as a data store (database), it's natural. - - `host`, `port`, `protocol` defines `elasticsearch` connect information. + - `host`, `port`, `protocol` defines `elasticsearch` connect information. - `user`, `password` is default credentials of `elasticsearch`. If you changed the credentials of `elasticsearch`, please change this accordingly. [more info](https://www.elastic.co/guide/en/x-pack/current/security-getting-started.html) - `min_score` sets a `min_score` when building a query for `elasticsearch`. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/graphql/elasticsearch/queryBuilder.js#L172) :::tip TIP - `min_score` helps you exclude documents with `_score` less than `min_score` value. + `min_score` helps you exclude documents with `_score` less than `min_score` value. ::: - - `indices` may contain one or multiple indexes. Each index acts as a data store for a storefront. You may add entries to the array with arbitrary names or remove entries from it. + - `indices` may contain one or multiple indexes. Each index acts as a data store for a storefront. You may add entries to the array with arbitrary names or remove entries from it. :::warning CAUTION ! - However, the index name should match the one you will use for [data pump](data-import.md#_2-2-recipe-b-using-on-premise). + However, the index name should match the one you will use for [data pump](data-import.md#_2-2-recipe-b-using-on-premise). ::: - The default values for `indices` assume you have 2 additional stores(`de`, `it`) plus the default store. + The default values for `indices` assume you have 2 additional stores(`de`, `it`) plus the default store. - `indexTypes` contains values for mapping. You can consider it as `table` if you take `indices` as database. - - `apiVersion` defines the `elasticsearch` version it uses. + - `apiVersion` defines the `elasticsearch` version it uses. ```json "redis": { @@ -441,7 +441,7 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- "it" ], ``` -- `availableStores` contains additional stores code name. If this value is an empty array, it means you only have one default store. +- `availableStores` contains additional stores code name. If this value is an empty array, it means you only have one default store. ```json "storeViews": { @@ -506,38 +506,38 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- ``` - `storeViews` element contains the whole information of ***additional*** stores. The default store information doesn't exist here, it exists on top level. -- `multistore` is supposed to tell the platform if it has multiple stores to consider. For example, it is used to configure `tax` values of additional store. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/platform/magento2/tax.js#L14) +- `multistore` is supposed to tell the platform if it has multiple stores to consider. For example, it is used to configure `tax` values of additional store. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/platform/magento2/tax.js#L14) - `mapStoreUrlsFor` is used for building url routes in frontend. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/lib/multistore.ts#L85) -- `de` element contains detailed information of `de` store. You need to have this kind of element for all the additional stores you added to `availableStores` with `storeCode` as the key. `de` and `it` in the `default.json` exhibits an example you can copy & paste for other stores you need to add. - - `storeCode` denotes store code for the store. +- `de` element contains detailed information of `de` store. You need to have this kind of element for all the additional stores you added to `availableStores` with `storeCode` as the key. `de` and `it` in the `default.json` exhibits an example you can copy & paste for other stores you need to add. + - `storeCode` denotes store code for the store. - `storeId` denotes store ID of the store. - `name` denotes the store name. - `url` denotes URL for the store. - - `elasticsearch` contains information for the store. This information may override the default one defined above. + - `elasticsearch` contains information for the store. This information may override the default one defined above. - `host` is where your *Elasticsearch* listens on. - `index` is the name of the index for the store. - `tax` contains tax information of the store. - - `defaultCountry` is the code name of the country on which tax is calculated for the store. + - `defaultCountry` is the code name of the country on which tax is calculated for the store. - `defaultRegion` is default region. - `calculateServerSide` determines if price is fetched with(`true`)/without(`false`) tax calculated. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/product.js#L48) - `sourcePriceIncludesTax` determines whether price is stored with tax applied (`true`) or tax calculated on runtime (`false`). [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/platform/magento2/tax.js#L12) - - `i18n` connotes *internationalization*. [more info](https://en.wikipedia.org/wiki/Internationalization_and_localization) + - `i18n` connotes *internationalization*. [more info](https://en.wikipedia.org/wiki/Internationalization_and_localization) - `fullCountryName` is the full name of the country this `i18n` is applied to. - `fullLanguageName` is the full name of the language this `i18n` is applied to. - `defaultCountry` is the abbreviated name of the country this `i18n` is applied to by default. - `defaultLanguage` is the abbreviated name of the language this `i18n` is applied to by default. - - `defaultLocale` is the default locale this `i18n` uses. - - `currencyCode` is the currency code this store uses. - - `currencySign` is the currency sign this store uses. - - `dateFormat` is the date format this store uses. - - + - `defaultLocale` is the default locale this `i18n` uses. + - `currencyCode` is the currency code this store uses. + - `currencySign` is the currency sign this store uses. + - `dateFormat` is the date format this store uses. + + ```json "authHashSecret": "__SECRET_CHANGE_ME__", "objHashSecret": "__SECRET_CHANGE_ME__", ``` -- `authHashSecret` is used to encode & decode JWT for API use. -- `objHashSecret` is 1) fallback secret hash for `authHashSecret`, 2) used for hashing in tax calculation. +- `authHashSecret` is used to encode & decode JWT for API use. +- `objHashSecret` is 1) fallback secret hash for `authHashSecret`, 2) used for hashing in tax calculation. ```json "cart": { @@ -553,20 +553,20 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- "sourcePriceIncludesTax": false }, ``` -- `cart` +- `cart` - `setConfigurableProductOptions` flag determines to show either the parent item or the child item (aka selected option item) in the cart context. `true` shows parent item instead of the option item selected. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/platform/magento2/o2m.js#L94) - `tax` - `alwaysSyncPlatformPricesOver` [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/order.js#L49) - - `usePlatformTotals` - These two options are used to determine whether to fetch prices from data source on the fly or not. If you set `alwaysSyncPlatformPricesOver` true, then it skips checking the checksum for cart items based on price. - + - `usePlatformTotals` + These two options are used to determine whether to fetch prices from data source on the fly or not. If you set `alwaysSyncPlatformPricesOver` true, then it skips checking the checksum for cart items based on price. + ```json "bodyLimit": "100kb", "corsHeaders": [ "Link" ], ``` -- `bodyLimit` limits how big a request can be for your application. +- `bodyLimit` limits how big a request can be for your application. - `corsHeaders` allows you to add entries to `Access-Control-Expose-Headers` ```json @@ -606,26 +606,26 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- - `mailchimp` provides `POST`, `DELETE` APIs for *Mailchimp* `subscribe` method. - `listId` is the ID of list you are publishing. - `apiKey` is API key you are assigned. - - `apiUrl` is API base url for *Mailchimp* service. + - `apiUrl` is API base url for *Mailchimp* service. - `mailService` is used to send emails from Vue Storefront via *Gmail*. - `transport` contains basic information for *Gmail* service. - `host` is where your mail is sent en route. - `port` is the port number used for the service. - - `secure` determines to use SSL connection. + - `secure` determines to use SSL connection. - `user` is `username` for the service. - `pass` is `password` for the service. - - `targetAddressWhitelist` checks if an user confirmed his/her email address *and* source email is white-listed. - - `secretString` is used for hashing. + - `targetAddressWhitelist` checks if an user confirmed his/her email address *and* source email is white-listed. + - `secretString` is used for hashing. ```json "magento2": { - "url": "http://demo-magento2.vuestorefront.io/", - "imgUrl": "http://demo-magento2.vuestorefront.io/media/catalog/product", - "assetPath": "/../var/magento2-sample-data/pub/media", - "magentoUserName": "", - "magentoUserPassword": "", - "httpUserName": "", - "httpUserPassword": "", + "url": "http://demo-magento2.vuestorefront.io/", + "imgUrl": "http://demo-magento2.vuestorefront.io/media/catalog/product", + "assetPath": "/../var/magento2-sample-data/pub/media", + "magentoUserName": "", + "magentoUserPassword": "", + "httpUserName": "", + "httpUserPassword": "", "api": { "url": "http://demo-magento2.vuestorefront.io/rest", "consumerKey": "byv3730rhoulpopcq64don8ukb8lf2gq", @@ -650,26 +650,26 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- } }, ``` -- `magento2` is used to integrate with Magento 2 as a data source. - +- `magento2` is used to integrate with Magento 2 as a data source. + - `imgUrl` is base image url. [jump to code](https://github.com/kkdg/vue-storefront-api/blob/master/src/api/img.js#L38) - + - `assetPath` is used for the `media` path. [jump to code](https://github.com/kkdg/vue-storefront-api/blob/master/src/index.js#L22) - + - `api` contains API credentials for integration. - + - `url` is base url for Magento 2 instance. - `consumerKey` See **TIP** - `consumerSecret` - `accessToken` - `accessTokenSecret` - - - + + + :::tip TIP - + These 4 nodes above is the required credentials for integration with Magento 2. [how to get them](data-import.html#_2-2-recipe-b-using-on-premise) - + ::: `magento1` has just the same structure with `magento2`. @@ -678,7 +678,7 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- ```json "imageable": { - "namespace": "", + "namespace": "", "maxListeners": 512, "imageSizeLimit": 1024, "whitelist": { @@ -698,44 +698,44 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- "process": 4 }, "simd": true, - "keepDownloads": true + "keepDownloads": true }, ``` -- `imageable` deals with everything you need to configure when it comes to your storefront images, especially product images. - +- `imageable` deals with everything you need to configure when it comes to your storefront images, especially product images. + - `maxListeners` limits maximum listeners to request's socket. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/img.js#L21) - `imageSizeLimit` limits maximum image size. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/img.js#L56) - `whitelist` contains a white-list of image source domains - + - `allowedHosts` contains the array of white-list - + :::warning DON'T FORGET - + You should include your source domain in `allowedHosts` or your request for product images will fail. [more info](data-import.html#secret-1-product-image-is-not-synced) - + ::: - + :::tip NOTE - - From `cache` to `simd` they are used to configure [Sharp](https://github.com/lovell/sharp) library. *Sharp* is a popular library for image processing in *Node.js*. [jump to option docs](https://sharp.dimens.io/en/stable/api-utility/#cache) - + + From `cache` to `simd` they are used to configure [Sharp](https://github.com/lovell/sharp) library. *Sharp* is a popular library for image processing in *Node.js*. [jump to option docs](https://sharp.dimens.io/en/stable/api-utility/#cache) + ::: - - - `cache` limits `libvips` operation cache from *Sharp*. Values hereunder are default values. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/lib/image.js#L5) - - - `memory` is the maximum memory in MB to use for the cache. - - `files` is the maximum number of files to hold open. - - `items` is the maximum number of operations to cache. - - - `concurrency` is the number of threads for processing each image. - - - `counters` provides access to internal task counters. - - - `queue` is the number of tasks in queue for *libuv* to provide a worker thread. - - `process` limits the number of resize tasks concurrently processed. - - - `simd` to use SIMD vector unit of the CPU in order to enhance the performance. - + + - `cache` limits `libvips` operation cache from *Sharp*. Values hereunder are default values. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/lib/image.js#L5) + + - `memory` is the maximum memory in MB to use for the cache. + - `files` is the maximum number of files to hold open. + - `items` is the maximum number of operations to cache. + + - `concurrency` is the number of threads for processing each image. + + - `counters` provides access to internal task counters. + + - `queue` is the number of tasks in queue for *libuv* to provide a worker thread. + - `process` limits the number of resize tasks concurrently processed. + + - `simd` to use SIMD vector unit of the CPU in order to enhance the performance. + ```json @@ -764,13 +764,13 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- } }, ``` -- `entities` is used to integrate with *GraphQL* in **Vue Storefront API**. +- `entities` is used to integrate with *GraphQL* in **Vue Storefront API**. - `category` - `includeFields` contains an array of fields to be added as `sourceInclude` [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/graphql/elasticsearch/category/resolver.js#L10) - `product` - `filterFieldMapping` adds a field mapping to apply a filter in a query [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/graphql/elasticsearch/mapping.js#L19) - - `category.name` - + - `category.name` + ```json "usePriceTiers": false, "boost": { @@ -783,17 +783,17 @@ At [`vue-storefront-api/config/default.json`](https://github.com/DivanteLtd/vue- } ``` - `usePriceTiers` determines whether to use price tiers for customers in groups -- `boost` is used to give weighted values to fields for a query to *Elasticsearch*, the bigger, the heavier. +- `boost` is used to give weighted values to fields for a query to *Elasticsearch*, the bigger, the heavier. - `name` field has the value *3* so that matching query with the `name` has the highest priority. - - `category.name` ,`short_description`, `description`, `sku`, `configurable_children.sku ` the rest of fields have the default value; 1. - + - `category.name` ,`short_description`, `description`, `sku`, `configurable_children.sku ` the rest of fields have the default value; 1. +

#### Secret 2. Study in `local.json` for *Vue Storefront* -At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-storefront/blob/master/config/default.json) for **frontend** : +At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-storefront/blob/master/config/default.json) for **frontend** : ```json "server": { @@ -816,43 +816,43 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor ``` - `server` contains information of various features related to *frontend* server. - - - `host` is the host address in which your *Vue Storefront* instance starts at. - - - `port` is the port number in which your *Vue Storefront* instance listens to. - + + - `host` is the host address in which your *Vue Storefront* instance starts at. + + - `port` is the port number in which your *Vue Storefront* instance listens to. + - `protocol` is used for *GraphQL* integration. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/lib/search/adapter/graphql/searchAdapter.ts#L48) - + - `api` determines API mode between `api` and `graphql`. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/resolvers/resolveGraphQL.js#L7) - + :::tip TIP - - You may take a look at [*GraphQL Action Plan*](/guide/basics/graphql.html) guide to help yourself make a decision which mode you should take. + + You may take a look at [*GraphQL Action Plan*](/guide/basics/graphql.html) guide to help yourself make a decision which mode you should take. ::: - + - `devServiceWorker` enables *service worker* in `develop` mode. The *service worker* is normally enabled by default for `production` mode, but not for `develop` mode. Setting this flag *true* forces to use *service worker* in `develop` mode too. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/service-worker/registration.js#L5) :::tip TIP - - You may take a look at [Working with Service Workers](/guide/core-themes/service-workers.html) for better understanding. - ::: - + + You may take a look at [Working with Service Workers](/guide/core-themes/service-workers.html) for better understanding. + ::: + - `useOutputCacheTagging` determines to allow *Output Cache Tags*. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/server.js#L168) - + - `useOutputCache` determines to allow *Output Cache*. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/server.js#L64) - + - `outputCacheDefaultTtl` defines the default timeout for *Redis Tag Cache*. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/utils/cache-instance.js#L16) - + - `availableCacheTags` contains a list of available cache tags. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/cache.js#L7) - + - `invalidateCacheKey` is the key used for checking validity of invalidation. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/server.js#L66) :::tip TIP - + You may take a look at [SSR Cache](/guide/basics/ssr-cache.html) in order to grab the idea of *Output Cache* in *Vue Storefront* ::: - + - `dynamicConfigReload` enables to reload `config.json` on the fly with each server request. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/server.js#L232) - `dynamicConfigContinueOnError` allows to skip errors during configuration merge on the fly. [jump to code](https://github.com/DivanteLtd/vue-storefront/blob/master/core/scripts/server.js#L240) - - `dynamicConfigExclude` + - `dynamicConfigExclude` - `dynamicConfigInclude` - `elasticCacheQuota` @@ -860,7 +860,7 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor ```json "seo": { "useUrlDispatcher": true -}, +}, "console": { "showErrorOnProduction" : true, "verbosityLevel": "display-everything" @@ -905,9 +905,9 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor "cutoff_frequency": 0.01, "max_expansions": 3, "minimum_should_match": "75%", - "prefix_length": 2, + "prefix_length": 2, "boost_mode": "multiply", - "score_mode": "multiply", + "score_mode": "multiply", "max_boost": 100, "function_min_score": 1 }, @@ -939,7 +939,7 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor "useInitialStateFilter": true }, ``` -- `ssr` +- `ssr` - `templates` - `default` @@ -1229,7 +1229,7 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor }, ``` - `tax`: ... - - `defaultCountry` is the code name of the country on which tax is calculated for the store. + - `defaultCountry` is the code name of the country on which tax is calculated for the store. - `defaultRegion` is default region. - `sourcePriceIncludesTax` determines whether price is stored with tax applied (`true`) or tax calculated on runtime (`false`). [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/platform/magento2/tax.js#L12) - `calculateServerSide` determines if price is fetched with(`true`)/without(`false`) tax calculated. [jump to code](https://github.com/DivanteLtd/vue-storefront-api/blob/master/src/api/product.js#L48) @@ -1258,6 +1258,9 @@ At [`vue-storefront/config/default.json`](https://github.com/DivanteLtd/vue-stor "defaultLocale": "en-US", "currencyCode": "USD", "currencySign": "$", + "currencyDecimal": null, + "currencyGroup": null, + "fractionDigits": 2, "priceFormat": "{sign}{amount}", "dateFormat": "HH:mm D/M/YYYY", "fullCountryName": "United States", @@ -1356,58 +1359,58 @@ Sometimes we need to know the inside of the perfect machine so that we can prepa

-## 4. Storefront CLI at your service -Upon the release of 1.10, we also present a new way of setup and all its sorts from `CLI` which is the all-time most favorite tool of developers worldwide if I must say. There are lots of benefits when `CLI` methods are available such as automation in scripts in cooperation with other automation tools out there. +## 4. Storefront CLI at your service +Upon the release of 1.10, we also present a new way of setup and all its sorts from `CLI` which is the all-time most favorite tool of developers worldwide if I must say. There are lots of benefits when `CLI` methods are available such as automation in scripts in cooperation with other automation tools out there. -We will continuously add new features to [`CLI`](https://www.npmjs.com/package/@vue-storefront/cli) as the version goes up. +We will continuously add new features to [`CLI`](https://www.npmjs.com/package/@vue-storefront/cli) as the version goes up. ### 1. Preparation - You need to have installed [`npm`](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) on your machine. (or [`yarn`](https://yarnpkg.com/lang/en/docs/install/#debian-stable) if you chose it) ### 2. Recipe -1. Install _Vue Storefront CLI_ package on your machine with `-g` flag as follows : +1. Install _Vue Storefront CLI_ package on your machine with `-g` flag as follows : ```bash npm install -g @vue-storefront/cli@0.0.15 ``` :vhs: You may also watch it in [bash playback :movie_camera:](https://asciinema.org/a/ZK0BVF7cQ8OaHHRcsaZgcOCfN) -2. Now go to any random folder you want to install a _Vue Storefront_ app under, and run the following : +2. Now go to any random folder you want to install a _Vue Storefront_ app under, and run the following : ```bash vsf init ``` -3. You will encounter a series of questions to install the app, first of which is as follows : +3. You will encounter a series of questions to install the app, first of which is as follows : ```bash ✔ Check avalilable versions -? Which version of Vue Storefront you'd like to install? -❯ Stable versions (recommended for production) - Release Candidates +? Which version of Vue Storefront you'd like to install? +❯ Stable versions (recommended for production) + Release Candidates In development branches (could be unstable!) ``` Select an option based on which you are to install. -4. Next question is about specific version to be installed as follows : +4. Next question is about specific version to be installed as follows : ```bash -? Select specific version - v1.8.0 -❯ v1.10.0 - v1.9.2 - v1.9.1 - v1.9.0 - v1.8.5 - v1.8.4 +? Select specific version + v1.8.0 +❯ v1.10.0 + v1.9.2 + v1.9.1 + v1.9.0 + v1.8.5 + v1.8.4 ``` Choose a version of your target. -5. Next question is about how you install it between `installer`/`manual` like below : +5. Next question is about how you install it between `installer`/`manual` like below : ```bash -? Would you like to use friendly installer or install Vue Storefront manually? -❯ Installer (MacOS/Linux only) +? Would you like to use friendly installer or install Vue Storefront manually? +❯ Installer (MacOS/Linux only) Manual installation ``` -Let's pick the `Installer` option for now. +Let's pick the `Installer` option for now. -Then you will see the machine start working on installation : +Then you will see the machine start working on installation : ```bash ? Would you like to use friendly installer or install Vue Storefront manually? Installer (MacOS/Linux only) ✔ Copying Vue Storefront files @@ -1415,7 +1418,7 @@ Then you will see the machine start working on installation : Running installer ``` -6. Once the preparation is finished then another series of questions pops up as `installer` is associated with as follows : +6. Once the preparation is finished then another series of questions pops up as `installer` is associated with as follows : ```bash yarn run v1.17.3 $ node ./core/scripts/installer @@ -1427,20 +1430,20 @@ $ node ./core/scripts/installer ? Would you like to use https://demo.vuestorefront.io as the backend? (Y/n) ``` -From this on, the questions would be the same as installation through `installer`. +From this on, the questions would be the same as installation through `installer`. You can follow it further at [Install using installer](#_2-using-installer) 7. Once the questions have been answered then the remaining process is taken to action. You will see a screen as follows when they finished : ```bash ? Please provide path for images endpoint https://demo.vuestorefront.io/img/ - Trying to create log files... + Trying to create log files... - Creating storefront config 'config/local.json'... + Creating storefront config 'config/local.json'... - Build storefront npm... + Build storefront npm... - Starting storefront server... + Starting storefront server... ┌────────────────────────────────────────────────────┐ │ Congratulations! │ @@ -1463,10 +1466,10 @@ You can follow it further at [Install using installer](#_2-using-installer) ![home_borderline](../images/home-vuestorefront.png) -Congratulation! +Congratulation! ### 3. Peep into the kitchen (what happens internally) -_Vue Storefront_ people prepared the `CLI` way of installing the whole infrastructure for your _Vue Storefront_ app provided as an `npm` package. It's now as easy as to install an `npm` package on any machine. Installed then run a command with a few options would be more than enough for the app to be up and running. Believe me your next _Vue Storefront_ app will be with you instantly with a breeze as long as `CLI` is accessible. +_Vue Storefront_ people prepared the `CLI` way of installing the whole infrastructure for your _Vue Storefront_ app provided as an `npm` package. It's now as easy as to install an `npm` package on any machine. Installed then run a command with a few options would be more than enough for the app to be up and running. Believe me your next _Vue Storefront_ app will be with you instantly with a breeze as long as `CLI` is accessible. ### 4. Chef's secret (protip) #### Secret 1. Install with _manual_ path @@ -1480,7 +1483,7 @@ _Vue Storefront_ people prepared the `CLI` way of installing the whole infrastru
## 5. How to debug *Anything* -When it comes to developing a software, there is one thing you really need to know. Knowing the blocker. Fixing a problem means you already know what's going on before what went wrong, and most of the time your pains are from yourself failing at that, which is, you don't know the problem and that is the problem. +When it comes to developing a software, there is one thing you really need to know. Knowing the blocker. Fixing a problem means you already know what's going on before what went wrong, and most of the time your pains are from yourself failing at that, which is, you don't know the problem and that is the problem. ### 1. Preparation ### 2. Recipe ### 3. Peep into the kitchen (what happens internally) From b1765a1b57f3543cb4dba1e354a889615d9c9720 Mon Sep 17 00:00:00 2001 From: EndPositive Date: Sat, 8 Feb 2020 14:15:57 +0100 Subject: [PATCH 7/8] Fix undefined value when not using currencyDecimal/Group. --- core/filters/price.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/filters/price.js b/core/filters/price.js index 6e8720e0a6..e7886664b0 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -36,7 +36,7 @@ export function price (value, storeView) { const localePrice = value.toLocaleString(defaultLocale, options); - let formattedPrice; + let formattedPrice = localePrice; if (currencyDecimal || currencyGroup) { formattedPrice = replaceSeparators(localePrice, { decimal: currencyDecimal, group: currencyGroup }, getLocaleSeparators(defaultLocale)); } From bafa1ae74722ddbdb7cbe41f341bf38aa02b800e Mon Sep 17 00:00:00 2001 From: EndPositive Date: Thu, 13 Feb 2020 23:11:34 +0100 Subject: [PATCH 8/8] Replace null by empty string. --- config/default.json | 4 ++-- core/filters/price.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/default.json b/config/default.json index c409f6ac07..3e604024f1 100644 --- a/config/default.json +++ b/config/default.json @@ -484,8 +484,8 @@ "defaultLocale": "en-US", "currencyCode": "USD", "currencySign": "$", - "currencyDecimal": null, - "currencyGroup": null, + "currencyDecimal": "", + "currencyGroup": "", "fractionDigits": 2, "priceFormat": "{sign}{amount}", "dateFormat": "HH:mm D/M/YYYY", diff --git a/core/filters/price.js b/core/filters/price.js index e7886664b0..6cbab190d6 100644 --- a/core/filters/price.js +++ b/core/filters/price.js @@ -37,7 +37,7 @@ export function price (value, storeView) { const localePrice = value.toLocaleString(defaultLocale, options); let formattedPrice = localePrice; - if (currencyDecimal || currencyGroup) { + if (currencyDecimal !== '' || currencyGroup !== '') { formattedPrice = replaceSeparators(localePrice, { decimal: currencyDecimal, group: currencyGroup }, getLocaleSeparators(defaultLocale)); } const valueWithSign = applyCurrencySign(formattedPrice, { currencySign, priceFormat });