You may have noticed that the new promotion system within EPiServer Commerce is finally out of beta.
Besides all the obvious advantages there is a little treasure in there as well.
In the old days we used to create custom blocks for displaying a banner for a promotion. Or we used some other way. This required a lot of custom logic, or work for the editor, to show or hide a banner when appropriate.
On a promotion you now have a Banner property. Just a simple ContentReference.
Now you can get a list of all banners for all active promotions, if you want of course, and display them, like this for example.
public List<PromotionalBanner> GetAllPromotionalBannersForMarket() { List<PromotionalBanner> promotionBanners = new List<PromotionalBanner>(); try { ICurrentMarket currentMarket = ServiceLocator.Current.GetInstance<ICurrentMarket>(); PromotionEngineContentLoader promotionEngineContentLoader = ServiceLocator.Current.GetInstance<PromotionEngineContentLoader>(); IContentLoader contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); PromotionFilters promotionFilters = ServiceLocator.Current.GetInstance<PromotionFilters>(); IList<PromotionData> promotions = promotionEngineContentLoader.GetEvaluablePromotionsInPriorityOrder(currentMarket.GetCurrentMarket()); PromotionFilterContext promotionFilterContext = promotionFilters.Filter(promotions, new List<string>(), RequestFulfillmentStatus.None); foreach (PromotionData promotionData in promotionFilterContext.IncludedPromotions.Where(pd => !ContentReference.IsNullOrEmpty(pd.Banner))) { string imageUrl = UrlResolver.Current.GetUrl( promotionData.Banner, null, new VirtualPathArguments { ContextMode = ContextMode.Default }); if (string.IsNullOrWhiteSpace(imageUrl)) { continue; } string campaignName = null; string campaignDescription = null; SalesCampaign campaign = contentLoader.Get<SalesCampaign>(promotionData.ParentLink); if (campaign != null) { campaignName = campaign.Name; campaignDescription = campaign.Description; } PromotionalBanner promotionalBanner = new PromotionalBanner { BannerUrl = imageUrl, PromotionDescription = promotionData.Description ?? string.Empty, PromotionName = promotionData.Name ?? string.Empty, CampaignDescription = campaignDescription ?? string.Empty, CampaignName = campaignName ?? string.Empty }; promotionBanners.Add(promotionalBanner); } } catch (ActivationException) { } catch (ArgumentNullException) { } catch (TypeMismatchException) { } catch (ContentNotFoundException) { } return promotionBanners; }
public class PromotionalBanner { public string BannerUrl { get; set; } public string PromotionDescription { get; set; } public string PromotionName { get; set; } public string CampaignDescription { get; set; } public string CampaignName { get; set; } }
The code is also on Gist.
Yes should be really easy for editors using rendering templates as well. You can then just drag a promotion on to content areas and have the partial view render the banner. There is campaign widget on the right now for being able to to drag campaigns and promotions on to content areas
LikeLike
Yes, that is certainly an option, and for displaying one promotion it might be OK. Though the editor still would have to remove it manually from your content area when the promotion is finished.
For displaying all promotions in a carousel, or pick a random one, from a campaign you would have to create the logic in your rendering template, which I try to avoid.
And you would have to register the rendering template in a IViewTemplateModelRegistrator implementation.
With this piece of code, or a variation on it, I would only need one block. Non active promotions will not show up and I would not have to remove it from a content area manually. You could build in randomization, a selector. Single display, or a carousel.
LikeLike
In this Gist: https://gist.github.com/jstemerdink/0cadf41e1c62abb34ae83f5a1b93590d I have added a sample showing the use of rendering templates discussed above
LikeLike