Here's the screenshot of our Merchello implementation:
Umbraco version is 7.5.11,
Merchello is 2.6.0(dev),
current user in umbraco has language English (United Kingdom),
Merchello Setting Currency is British Pound,
Default Extended Content Culture is English (United Kingdom),
then products Ajour, Element, Evolution, Flea and Paranormal have extended content set in both nb-NO and en-US cultures, the last product Test11 has extended content saved in en-GB only.
1) First are rendered the three products at the bottom since they do not have variants, and the rendered decimal prices (i.e £842 712,00) follow somehow the gdp currency format position
Since this is inside the WebApi, there is no Culture carried from the page, so the rendered decimal prices (i.e £2,049.00) seem to follow now the gdp currency format position and pattern
Merchello by default only supports a single currency which is set in the back office AND it is not tied to the localization. That's only the textual content (the Umbraco properties).
If you want to allow for different currencies there are a bunch of other things to consider, like making sure that an order is all done in the same currency, price conversions, etc.
There have been a number of people who have done it - Simon Brownlie for one ...
In our case here I am merely pointing to the mixed formatting of a single value of a price (£842 712,00).
Since Merchello is not tied to localization, then in our case I found a solution to just use the default extended content culture setting as a global localization setting for Merchello:
Helpers.cs:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Web;
using Merchello.Core;
using Merchello.Web;
using MerchelloConstants = Merchello.Core.Constants;
using Umbraco.Core;
using Umbraco.Core.Services;
using Umbraco.Web;
namespace AjourCms.Ajour
{
public static class Helpers
{
public static string DecryptLicence(string licenceKey)
{
var licence = new AjourLicence(licenceKey);
if (!licence.IsValid) return "Licence invalid" + (licence.Exception != null ? ": " + licence.Exception.Message : "");
return "Users:" + (licence.Users != null ? licence.Users.Value.ToString() : "") + ", " +
(licence.IsTrial ? "Trial" : "Expires:" + (licence.ExpirationDate != null ? licence.ExpirationDate.Value.ToLongDateString() : ""));
}
public static CultureInfo MerchelloStoreCulture
{
get { return CultureInfo.GetCultureInfo(MerchelloContext.Current.Services.StoreSettingService.GetByKey(MerchelloConstants.StoreSetting.DefaultExtendedContentCulture).Value); }
}
public static string AjourCultureSuffix(CultureInfo culture)
{
return culture.Name.ToLowerInvariant().Replace("-", "_");
}
public static string Localize(string area, string key, ILocalizedTextService localizedTextService = null, CultureInfo cultureInfo = null)
{
if (string.IsNullOrWhiteSpace(area))
{
if (string.IsNullOrWhiteSpace(key))
{
return "[!]";
}
return "[!/" + key + "]";
}
if (string.IsNullOrWhiteSpace(key))
{
return "[!" + area + "/]";
}
if (cultureInfo == null) cultureInfo = MerchelloStoreCulture;
if (cultureInfo == null)
{
return "[!" + key + "]";
}
if (localizedTextService == null) localizedTextService = ApplicationContext.Current.Services.TextService;
if (localizedTextService == null)
{
return "[!" + key + "]";
}
return localizedTextService.Localize(area + "/" + key, cultureInfo);
}
public static string LocalizeProductEstablishingOptionChoice(string optionChoice, string localizedEstablishingFee, string localizedNoEstablishingFee)
{
string localizedOptionChoice;
var genericName = optionChoice;
string translatedName = null;
if (genericName.Contains(":") && genericName.Split(':').Length > 0)
{
decimal decimalFee;
var genericNameDecimalFee = genericName.Split(':')[1].Trim().Split(' ')[0];
genericNameDecimalFee = Regex.Replace(genericNameDecimalFee, "[^0-9.,]", "");
var serverCultureDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
if (serverCultureDecimalSeparator == "." && genericNameDecimalFee.Contains(","))
{
genericNameDecimalFee = genericNameDecimalFee.Replace(",", ".");
}
if (serverCultureDecimalSeparator == "," && genericNameDecimalFee.Contains("."))
{
genericNameDecimalFee = genericNameDecimalFee.Replace(".", ",");
}
if (decimal.TryParse(genericNameDecimalFee, out decimalFee))
{
var parsedFee = decimalFee.AsFormattedCurrency();
translatedName = localizedEstablishingFee + ": " + parsedFee;
}
}
else
{
translatedName = localizedNoEstablishingFee;
}
if (translatedName != null)
{
localizedOptionChoice = translatedName;
}
else
{
localizedOptionChoice = "!" + optionChoice;
}
return localizedOptionChoice;
}
public static string GetCurrentPaymentLogs()
{
var result = string.Empty;
var currentCustomer = new CustomerContext(UmbracoContext.Current).CurrentCustomer;
var logCacheKey = "" + currentCustomer.Key + "_Payment";
if (HttpContext.Current.Cache[logCacheKey] != null)
{
var storedLogs = HttpContext.Current.Cache[logCacheKey] as string;
if (!string.IsNullOrWhiteSpace(storedLogs))
{
var storedLogsLines = storedLogs.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
foreach (var storedLogsLine in storedLogsLines)
{
result += "<p>" + storedLogsLine + "</p>" + Environment.NewLine;
}
//result = storedLogs.Replace(Environment.NewLine, "<br/>");
// result = storedLogs;
}
HttpContext.Current.Cache.Remove(logCacheKey);
}
return result;
}
}
}
And then in pages:
...
@using AjourHelpers = AjourCms.Ajour.Helpers;
@{
var product = Merchello.TypedProductContent(Model.ProductKey);
// Local variable for partial view conditionals
var hasVariants = product.ProductVariants.Any();
var merchelloStoreCulture = AjourHelpers.MerchelloStoreCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = merchelloStoreCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = merchelloStoreCulture;
...
}
With this, depending on our currencyCode formats defined in merchello.config:
I've been looking at a library named NodaMoney (https://github.com/remyvd/NodaMoney) to handle this sort of thing in the future. I've actually replaced all decimal prices in Merchello in a private branch with the Money type and done a bit of testing ... works pretty slick.
Prices Culture
Hi Rusty,
Here's the screenshot of our Merchello implementation:
Umbraco version is 7.5.11, Merchello is 2.6.0(dev), current user in umbraco has language English (United Kingdom), Merchello Setting Currency is British Pound, Default Extended Content Culture is English (United Kingdom),
then products Ajour, Element, Evolution, Flea and Paranormal have extended content set in both nb-NO and en-US cultures, the last product Test11 has extended content saved in en-GB only.
In merchello.config I have:
Now the prices on the page:
1) First are rendered the three products at the bottom since they do not have variants, and the rendered decimal prices (i.e £842 712,00) follow somehow the gdp currency format position
but with the value defined by the nok currency format pattern:
The formatted currency is called directly from the AddToBasketForm.cshtml page from line around 217:
When debugging the .AsFormattedCurrency() calls, breaking inside Merchello.Core\CurrencyContext.cs at line 121:
and inspecting in the ImmediateWindow:
I get the
2) Secondly are renderred the upper row products, since they have variants, so the endpoint
productTableApi: '/umbraco/Merchello/ProductDataTableApi/'
is called with the WebApi method
that calls in the ProductDataTableFactory.cs method:
that contains the AsFormattedCurrency() calls again:
Since this is inside the WebApi, there is no Culture carried from the page, so the rendered decimal prices (i.e £2,049.00) seem to follow now the gdp currency format position and pattern
but when debugging again the .AsFormattedCurrency() calls, breaking inside Merchello.Core\CurrencyContext.cs at line 121:
and inspecting again in the ImmediateWindow:
I now get the
I hope i got the behavior, do I interpret things correctly Rusty ?
Why do I see this combination of gdp/nok formats in the rendered decimals ?
Is there anything I'm missing, please ?
Hey Claudiu
Merchello by default only supports a single currency which is set in the back office AND it is not tied to the localization. That's only the textual content (the Umbraco properties).
If you want to allow for different currencies there are a bunch of other things to consider, like making sure that an order is all done in the same currency, price conversions, etc.
There have been a number of people who have done it - Simon Brownlie for one ...
Thanks for your answer Rusty.
In our case here I am merely pointing to the mixed formatting of a single value of a price (£842 712,00).
Since Merchello is not tied to localization, then in our case I found a solution to just use the default extended content culture setting as a global localization setting for Merchello:
Helpers.cs:
And then in pages:
With this, depending on our currencyCode formats defined in merchello.config:
we can have all prices displayed correctly for English (United Kingdom):
£842,712.00
and for Norwegian, Bokmål (Norway):
842 712,00 kr
Hey Claudiu - Thanks for posting your solution.
I've been looking at a library named NodaMoney (https://github.com/remyvd/NodaMoney) to handle this sort of thing in the future. I've actually replaced all decimal prices in Merchello in a private branch with the Money type and done a bit of testing ... works pretty slick.
is working on a reply...