diff --git a/docs/tags.md b/docs/tags.md
index d3947a9..a800a93 100644
--- a/docs/tags.md
+++ b/docs/tags.md
@@ -1,19 +1,6 @@
# Tags
-
-
-- [currency](#currency)
-- [customer:orders](#customer-orders)
-- [customer:order](#customer-order)
-- [id](#id)
-- [product:single](#product-single)
-- [product:configurable](#product-configurable)
-- [product:price](#product-price)
-- [product:options](#product-options)
-- [store:countries](#store-countries)
-- [wishlist:contains](#test)
-
-
+[TOC]
## Introduction
@@ -55,6 +42,13 @@ Attach it to a variable to make it reusable:
```
+## siteCurrency
+Returns the current currency that is being used by the site. This will either be the `default_currency` defined in `gaia.php` or the `currency` attribute set on the site if you're on a multisite setup.
+
+```twig
+{{ gaia:site_currency }}
+```
+
## product:single
Returns `true` if the current product is a single product that has no variants, or `false` if it does.
diff --git a/js/dist/gaia.js b/js/dist/gaia.js
index fa8d1d1..a34b791 100644
--- a/js/dist/gaia.js
+++ b/js/dist/gaia.js
@@ -30,8 +30,12 @@ window.gaia = {
});
},
- formatPrice: (price, currency) => {
- return price.toLocaleString("en-GB", { style: "currency", currency: "GBP" });
+ formatPrice: (price, locale, currency) => {
+ // Since the code comes from Statamic it should be in POSIX format, we
+ // will attempt to convert to a valid BCP 47 locale.
+ locale = locale.replace('_', '-');
+
+ return price.toLocaleString(locale, { style: "currency", currency: currency });
},
getCSRF: () => {
diff --git a/src/Tags/Gaia.php b/src/Tags/Gaia.php
index 0456c94..3710a9e 100644
--- a/src/Tags/Gaia.php
+++ b/src/Tags/Gaia.php
@@ -58,6 +58,17 @@ public function id()
return Str::lower(Str::random(10));
}
+ /**
+ * Retrieves the current site's currency.
+ *
+ * @return string The currency code for the current site.
+ * If not set, returns the default currency from configuration.
+ */
+ public function siteCurrency(): string
+ {
+ return Site::current()->attribute('currency') ?? config('gaia.default_currency');
+ }
+
public function livewireStart(): string
{
return <<<'JS'
diff --git a/stubs/resources/views/shop/product/default/_price.antlers.html b/stubs/resources/views/shop/product/default/_price.antlers.html
index 6f71575..e365d3d 100644
--- a/stubs/resources/views/shop/product/default/_price.antlers.html
+++ b/stubs/resources/views/shop/product/default/_price.antlers.html
@@ -1,23 +1,61 @@
-
- {{ gaia:product:price }}
- {{ if {gaia:product:single} }}
- {{ if is_discounted }}
-
Now {{ gaia:currency :price="min_discounted_price" }}
-
- Was {{ gaia:currency :price="min_regular_price" }}
- {{ if (discount_percentage <= '5') }}
- (-{{ gaia:currency :price="discount_amount" }})
- {{ else }}
- (-{{ discount_percentage | floor }}%)
- {{ /if }}
-
- {{ /else }}
-
{{ gaia:currency :price="min_price" }}
+
+
+ {{ gaia:product:price }}
+ {{ if {gaia:product:single} }}
+ {{ if is_discounted }}
+ Now {{ gaia:currency :price="min_discounted_price" }}
+
+ Was {{ gaia:currency :price="min_regular_price" }}
+ {{ if (discount_percentage <= '5') }}
+ (-{{ gaia:currency :price="discount_amount" }})
+ {{ else }}
+ (-{{ discount_percentage | floor }}%)
+ {{ /if }}
+
+ {{ /else }}
+ {{ gaia:currency :price="min_price" }}
+ {{ /if }}
+ {{ /if }}
+
+ {{ if {gaia:product:configurable} }}
+ From {{ gaia:currency :price="min_price" }}
{{ /if }}
- {{ /if }}
+ {{ /gaia:product:price }}
+
- {{ if {gaia:product:configurable} }}
-
From {{ gaia:currency :price="min_price" }}
- {{ /if }}
- {{ /gaia:product:price }}
+ {{ if {gaia:product:configurable} }}
+
+
+
+
Now
+
+ Was
+
+ (-%)
+
+
+
+
+
+
+
+
+
+ From
+
+ {{ /if }}
+
+
diff --git a/stubs/resources/views/shop/product/default/index.antlers.html b/stubs/resources/views/shop/product/default/index.antlers.html
index c942252..68d57e2 100644
--- a/stubs/resources/views/shop/product/default/index.antlers.html
+++ b/stubs/resources/views/shop/product/default/index.antlers.html
@@ -48,9 +48,9 @@
Alpine.store('product', {
title: '{{ title }}',
- price: '{{ gaia:product:price }}{{min_price}}{{ /gaia:product:price}}',
- variants: JSON.parse(` {{ { collection:variants :product_slug:is="slug" :site="site" } | pluck_with_keys('option1', 'option2', 'option3', 'inventory_quantity', 'slug', 'price', 'image') | to_json }} `),
- currentVariants: JSON.parse(` {{ { collection:variants :product_slug:is="slug" :site="site" } | pluck_with_keys('option1', 'option2', 'option3', 'inventory_quantity', 'slug', 'price', 'image') | to_json }} `),
+ priceTable: {},
+ variants: JSON.parse(` {{ { collection:variants :product_slug:is="slug" :site="site" } | pluck_with_keys('option1', 'option2', 'option3', 'inventory_quantity', 'slug', 'price', 'compare_at_price', 'image') | to_json }} `),
+ currentVariants: JSON.parse(` {{ { collection:variants :product_slug:is="slug" :site="site" } | pluck_with_keys('option1', 'option2', 'option3', 'inventory_quantity', 'slug', 'price', 'compare_at_price', 'image') | to_json }} `),
currentProduct: null,
selectedOptions: null,
stockStatus: 'inStock',
@@ -91,39 +91,95 @@ 0,
inStock: variant.inventory_quantity > 0,
- formattedPrice: gaia.formatPrice(variant.price),
productId: '{{ product_id }}'
}
},
+
updateDisplayedPrice() {
- if (this.variants.length === 1) {
- this.price = this.currentProduct.formattedPrice;
- return;
+ const formatPrice = (price) => {
+ if (price === null || price === undefined) {
+ return false;
+ }
+
+ return gaia.formatPrice(parseFloat(price), '{{ site:locale }}', '{{ gaia:site_currency }}');
}
- function calculateMinMaxPrices(variants) {
- return variants.reduce((acc, variant) => {
+ const calculateMinMaxPrices = () => {
+ return this.currentVariants.reduce((acc, variant) => {
return {
- smallestPrice: Math.min(acc.smallestPrice, variant.price),
- largestPrice: Math.max(acc.largestPrice, variant.price)
+ smallestPrice: Math.min(acc.smallestPrice, variant.price),
+ largestPrice: Math.max(acc.largestPrice, variant.price)
};
}, { smallestPrice: Infinity, largestPrice: -Infinity });
}
- const { smallestPrice, largestPrice } = calculateMinMaxPrices(this.currentVariants);
+ const minPrice = () => {
+ if (this.areAllOptionsSelected) {
+ return this.currentProduct.compare_at_price || this.currentProduct.price;
+ }
- if (smallestPrice === Infinity || largestPrice === Infinity) {
- let { smallestPrice, largestPrice } = calculateMinMaxPrices(this.variants);
- this.price = `${gaia.formatPrice(smallestPrice)} - ${gaia.formatPrice(largestPrice)}`;
- return;
+ const { smallestPrice, largestPrice } = calculateMinMaxPrices();
+
+ return smallestPrice;
}
- if (smallestPrice === largestPrice) {
- this.price = gaia.formatPrice(largestPrice);
- return;
+ const maxPrice = () => {
+ if (this.areAllOptionsSelected) {
+ return this.currentProduct.price;
+ }
+
+ const { smallestPrice, largestPrice } = calculateMinMaxPrices();
+
+ return largestPrice;
}
- this.price = `${gaia.formatPrice(smallestPrice)} - ${gaia.formatPrice(largestPrice)}`;
+ const compareAtPrice = () => {
+ // If the product doesn't exist yet, return false
+ if (! this.currentProduct) {
+ return false;
+ }
+
+ return this.currentProduct.compare_at_price
+ }
+
+ const discountAmount = () => {
+ // If the product doesn't exist yet, return false
+ if (! this.currentProduct) {
+ return false;
+ }
+
+ if (! this.currentProduct.compare_at_price) {
+ return false;
+ }
+
+ return this.currentProduct.price - this.currentProduct.compare_at_price;
+ }
+
+ const discountPercentage = () => {
+ // If the product doesn't exist yet, return false
+ if (! this.currentProduct) {
+ return false;
+ }
+
+ // If the product doesn't have a compare at price, it's
+ // not discounted so return false
+ if (! this.currentProduct.compare_at_price) {
+ return false;
+ }
+
+ return Math.floor((discountAmount() / this.currentProduct.price) * 100);
+ }
+
+ this.priceTable = {
+ minPrice: minPrice(),
+ formattedMinPrice: formatPrice(minPrice()),
+ maxPrice: maxPrice(),
+ formattedMaxPrice: formatPrice(maxPrice()),
+ isDiscounted: discountAmount() ? true : false,
+ discountPercentage: discountPercentage(),
+ discountAmount: discountAmount(),
+ formattedDiscountAmount: formatPrice(discountAmount()),
+ }
},
updateCurrentVariants() {
if (!this.selectedOptions) {
@@ -197,6 +253,10 @@