Idiots Guide To Episerver Markets

In an Episerver e-commerce website, markets are the way you can split up your PIM to different demographics.  Obviously, all companies are different and each has its own business process and its own unique sales funnels.  This means that the exact criteria that determine a company's markets can potentially be very different between projects.  Some companies might just have a single market, others can define multiple markets, each with its own product catalog, language, currency, and promotions determined by factors such as brand, location, or locale.  In this simple guide, I'm going to talk about how to create and query your own markets within Episerver commerce.  In this post, I'll hopefully go over all the code you'll need to crack on.

How To Query Existing Markets

In Episerver you can view all the existing markets in your website, via code using the IMarketService API, which you can access via.

   var marketService = ServiceLocator.Current.GetInstance<IMarketService>();
   var allMarkets = marketService.GetAllMarkets();

How To Get The Current Site Visitors Market

When a site visitor first hits your website, one of the first things you need to do within your request pipeline, is to look-up the market ID they should be using and if it doesn't exist, associate one against them in a cookie or session, otherwise they'll likely just see the default market and won't be able to see the correct products. To get the current market and set the market you can use the ICurrentMarket API :

Get Current Market

var currentMarketService = ServiceLocator.Current.GetInstance<ICurrentMarket>();
var currentMarket = currentMarketService.GetCurrentMarket();

Set Current Market

   var currentMarketService = ServiceLocator.Current.GetInstance<ICurrentMarket>();
   currentMarketService.SetCurrentMarket(marketId);

How Do  Create Custom Rules When Selecting A Market?

As I mentioned in the introduction, if you need to create multiple markets you will need to write some custom code as your market will be unique to you, e.g. some people might want to store the users current market id in a cookie, some in session. Some might need to query the language to get the market ID, some might need to run some custom code to get a brand name for example.

To do this, you'll need to create a new class that implements ICurrentMarket.  All you need to do is write a custom class that implements the ICurrentMarket interface and implements the GetCurrentMarket()and SetCurrentMarket() with their own implements.

NOTE: Don't forget to update your structure map container to use this new class, otherwise it will likely default to the out-of-the-box implementation, e.g. container.For<ICurrentMarket>().Singleton().Use<MyMarket>();

The code below is based on a requirement I had on a past project.  The logic you end up writing will likely be different than this, but, hopefully, it'll give you an idea about it.  In this example, on each page request, you'll read the cookie value to set if the market has been previously set, if it hasn't we'll query the current language API to get the culture code.  Using the current language code, we can query the current markets to get the matching market.

    public class CurrentMarket : ICurrentMarket
    {
        public IMarket GetCurrentMarket()
        {
            var marketService = ServiceLocator.Current.GetAllInstances<IMarketService>();

            var marketId = MethodToReadCookieHasMarketIdSet()
            if (!string.IsNullOrEmpty(marketId ))
            {
                var currentMarket = _marketService.GetMarket(marketId);
         	return currentMarket;
            }

            var languageBranchRepository = ServiceLocator.Current.GetInstance<ILanguageBranchRepository>();
            var currentLanguage = languageBranchRepository.Load(CultureInfo.CurrentUICulture);
            return _marketService.GetAllMarkets()
                    .FirstOrDefault(x => string.Equals(x.DefaultLanguage.Name, currentLanguage, System.StringComparison.InvariantCultureIgnoreCase));	
        }
    }

 

I Need To Store Custom Data With My Markets, Is This Possible?

Yes, like most things Episerver markets are defined by an interface, IMarket.  Out of the box, Episerver gives you the MarketImpl class.  You can use this class to define your markets and pass it into the IMarketService to create a new market within your commerce database.  If you want to add in your own custom fields, all you need to do is create your own class with your own custom properties, like so:

 

    public class Market : IMarket
    {
        public string MyCustomProperty { get; set; }

        public MarketId MarketId => throw new System.NotImplementedException();

        public bool IsEnabled => throw new System.NotImplementedException();

        public string MarketName => throw new System.NotImplementedException();

        public string MarketDescription => throw new System.NotImplementedException();

        public CultureInfo DefaultLanguage => throw new System.NotImplementedException();

        public IEnumerable<CultureInfo> Languages => throw new System.NotImplementedException();

        public Currency DefaultCurrency => throw new System.NotImplementedException();

        public IEnumerable<Currency> Currencies => throw new System.NotImplementedException();

        public IEnumerable<string> Countries => throw new System.NotImplementedException();
    }

Markets Takeaway

If you have a need to sell your products to different markets, based on countries, brands, currency etc.. then markets are the place to start. Building markets in Episerver hopefully shouldn't be too painful. All the API's and entities all are interface based, so unit testing isn't too bad.

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top