Error executing template "Designs/Swift/Paragraph/Swift_ProductListItemRepeater.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_e7fa5fc9f0954fe2aa02475818c8bcaf.<RenderProductList>b__1_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\dignet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListItemRepeater.cshtml:line 79
at CompiledRazorTemplates.Dynamic.RazorEngine_e7fa5fc9f0954fe2aa02475818c8bcaf.Execute() in D:\dynamicweb.net\Solutions\Dynamicweb\dignet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListItemRepeater.cshtml:line 40
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
@using Dynamicweb.Ecommerce.ProductCatalog
@using Dynamicweb.Core
@using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites
@using Dynamicweb.Environment
@functions
{
string liveInfoClass = "";
}
@{
bool isDetailPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID"));
string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
string productInfoFeed = "";
bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled;
if (isLazyLoadingForProductInfoEnabled)
{
if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
{
productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
if (!string.IsNullOrEmpty(productInfoFeed))
{
productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
}
}
liveInfoClass = "js-live-info";
}
}
@if (!isDetailPage) {
if (!string.IsNullOrEmpty(theme)) {
<div class="h-100@(theme) item_@Model.Item.SystemName.ToLower()" @productInfoFeed>
@RenderProductList()
</div>
} else {
<div class="item_@Model.Item.SystemName.ToLower()" @productInfoFeed>
@RenderProductList()
</div>
}
}
@helper RenderProductList () {
bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false;
ProductListViewModel productList = new ProductListViewModel();
string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID");
string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID");
var cookieOptInLevel = CookieManager.GetCookieOptInLevel();
bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical"));
ProductListViewModelSettings productListSetting = new ProductListViewModelSettings
{
LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
ShopId = Pageview.Area.EcomShopId
};
int productsCount = 0;
int maxProductsCounter = 0;
if (Dynamicweb.Context.Current.Items.Contains("ProductList"))
{
productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"];
}
else if (Pageview.Item["DummyProductGroup"] != null)
{
var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
ProductListViewModel groupList = pageViewModel.Item.GetValue("DummyProductGroup") != null ? pageViewModel.Item.GetValue("DummyProductGroup") as ProductListViewModel : new ProductListViewModel();
if (groupList?.Group?.Id != null) {
productList = ViewModelFactory.CreateView(productListSetting, groupList.Group.Id);
Dynamicweb.Context.Current.Items.Add("ProductList", productList);
} else {
productList = ViewModelFactory.CreateView(productListSetting, Dynamicweb.Ecommerce.Services.ProductGroups.GetGroups(Dynamicweb.Ecommerce.Common.Context.LanguageID).FirstOrDefault().Id);
Dynamicweb.Context.Current.Items.Add("ProductList", productList);
}
}
else if (Pageview.Item["DummyProductGroup"] == null) {
productList = ViewModelFactory.CreateView(productListSetting, Dynamicweb.Ecommerce.Services.ProductGroups.GetGroups(Dynamicweb.Ecommerce.Common.Context.LanguageID).FirstOrDefault().Id);
Dynamicweb.Context.Current.Items.Add("ProductList", productList);
}
if (Pageview.Page.Item.SystemName == "Swift_ProductListComponentEdit") {
if (productList.TotalProductsCount == 0) {
ProductViewModelSettings productSetting = new ProductViewModelSettings
{
LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
ShopId = Pageview.Area.EcomShopId
};
foreach (var product in Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(3, Dynamicweb.Ecommerce.Common.Context.LanguageID, false)) {
var productView = ViewModelFactory.CreateView(productSetting, product.Id);
productList.Products.Add(productView);
}
Dynamicweb.Context.Current.Items["ProductList"] = productList;
}
productList.TotalProductsCount = 3;
productList.PageSize = 3;
maxProductsCounter = 3;
}
string groupId = productList?.Group?.Id != null ? productList.Group.Id : "";
string url = Dynamicweb.Context.Current.Request.RawUrl;
if (productList.TotalProductsCount > 0) {
int pageSizeSetting = 30;
int pageSize = productList.PageSize;
pageSize += pageSizeSetting;
int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : productList.PageSize;
string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : "";
int listItemSourcePageId = Model.Item.GetInt32("ListComponentSource");
var page = Dynamicweb.Services.Pages.GetPage(listItemSourcePageId);
if (page != null) {
var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page);
string gridColumnSize = Model.Item.GetRawValueString("GridLayoutDesktop", "3-columns");
gridColumnSize = gridColumnSize == "2-columns" ? "g-col-lg-6" : gridColumnSize;
gridColumnSize = gridColumnSize == "3-columns" ? "g-col-lg-4" : gridColumnSize;
gridColumnSize = gridColumnSize == "4-columns" ? "g-col-lg-3" : gridColumnSize;
gridColumnSize = gridColumnSize == "6-columns" ? "g-col-lg-2" : gridColumnSize;
gridColumnSize = gridColumnSize == "list" ? "" : gridColumnSize;
string gridColumnMobileSize = Model.Item.GetRawValueString("GridLayoutMobile", "2-columns");
gridColumnMobileSize = gridColumnMobileSize == "list" ? "g-col-12" : gridColumnMobileSize;
gridColumnMobileSize = gridColumnMobileSize == "2-columns" ? "g-col-6" : gridColumnMobileSize;
string listItemTheme = " theme " + pageViewModel.Item.GetRawValueString("Theme", string.Empty).Replace(" ", "").Trim().ToLower();
string listItemPadding = pageViewModel.Item.GetRawValueString("ContentPadding", string.Empty);
string listItemPaddingClass = string.Empty;
switch(listItemPadding)
{
case "small":
listItemPaddingClass = " p-2 p-xl-3";
break;
case "large":
listItemPaddingClass = " p-3 p-xl-4";
break;
case "small-x":
listItemPaddingClass = " px-2 px-md-3";
break;
case "large-x":
listItemPaddingClass = " px-3 px-md-4";
break;
}
<div class="grid">
@if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
{
<script>
gtag("event", "view_item_list", {
item_list_id: "product_list_item_repeater",
item_list_name: "Product list (Item Repeater)",
items: [
@foreach (ProductViewModel product in productList.Products)
{
<text>{
item_id: "@product.Number",
item_name: "@product.Name",
currency: "@product.Price.CurrencyCode",
price: @product.Price.Price
},</text>
}
]
});
</script>
}
@foreach (ProductViewModel product in productList.Products)
{
if (maxProductsCounter == 0 || (productsCount < maxProductsCounter)) {
string detailsPageLink = !string.IsNullOrEmpty(GetPageIdByNavigationTag("Shop").ToString()) ? GetPageIdByNavigationTag("Shop").ToString() : string.Empty;
string selectedDetailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(product.PrimaryOrDefaultGroup.Id)?.Meta.PrimaryPage ?? string.Empty;
string detailsPageId = detailsPageLink != string.Empty ? detailsPageLink.Substring(detailsPageLink.LastIndexOf('=') + 1) : string.Empty;
string selectedDetailPageId = selectedDetailPage != string.Empty ? selectedDetailPage.Substring(selectedDetailPage.LastIndexOf('=') + 1) : string.Empty;
detailsPageId = string.IsNullOrEmpty(selectedDetailPage) ? detailsPageId : selectedDetailPageId;
string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : "";
variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink;
string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop");
link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}";
link += $"&ProductID={product.Id}";
link += variantIdForLink;
link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link);
if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
{
Dynamicweb.Context.Current.Items["ProductDetails"] = product;
}
else
{
Dynamicweb.Context.Current.Items.Add("ProductDetails", product);
}
if (Model.Item.GetString("ListComponentSource") != null) {
<article class="@gridColumnMobileSize @gridColumnSize @listItemTheme @listItemPaddingClass d-flex flex-column position-relative product js-product @liveInfoClass" data-product-id="@product.Id" itemscope itemtype="https://schema.org/Product">
@{
string clickProductLink = string.Empty;
if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
{
clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @product.Price.Price + "')\"";
}
}
<a href="@link" class="stretched-link" @clickProductLink>
<span class="visually-hidden">@product.Name</span>
</a>
@if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
{
<script>
function clickProductLink(productId, productName, productVariant, productCurrency, productPrice) {
if (typeof gtag !== "undefined") {
gtag("event", "select_item", {
item_list_id: "product_list_item_repeater",
item_list_name: "Product list (Item Repeater)",
items: [
{
item_id: productId,
item_name: productName,
currency: productCurrency,
item_list_id: "product_list_item_repeater",
item_list_name: "Product list (Item Repeater)",
item_variant: productVariant,
price: productPrice
}
]
});
}
}
</script>
}
@RenderGrid(listItemSourcePageId)
</article>
}
productsCount++;
}
}
</div>
<div class="my-3">
<div class="text-center">
<div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div>
@if (productList.PageCount != 1 && maxProductsCounter == 0) {
string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "";
sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection;
<form method="get" action="@url" data-response-target-element="content" class="w-100">
@if (productList?.FacetGroups != null) {
foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
{
foreach (FacetViewModel facetItem in facetGroup.Facets)
{
foreach (FacetOptionViewModel facetOption in facetItem.Options)
{
if (facetOption.Selected)
{
<input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]">
}
}
}
}
}
@if (productList?.Group?.Id != null) {
<input type="hidden" name="GroupId" value="@productList.Group.Id">
}
<input type="hidden" name="PageSize" value="@pageSize">
<input type="hidden" name="SortBy" value="@sortBySelection">
<input type="hidden" name="RequestType" value="UpdateList">
@{
string nextPageLink = "/Default.aspx?ID=" + Pageview.Page.ID + "&PageSize=" + pageSize + "&SortBy=" + sortBySelection;
foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
{
foreach (FacetViewModel facetItem in facetGroup.Facets)
{
foreach (FacetOptionViewModel facetOption in facetItem.Options)
{
if (facetOption.Selected)
{
nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]";
}
}
}
}
nextPageLink += productList?.Group?.Id != null ? "&GroupID=" + productList.Group.Id : "";
nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : "";
}
<a href="@nextPageLink" class="btn btn-primary" type="button" onclick="swift.ProductList.Update(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a>
</form>
}
</div>
</div>
<script>
function switchVariantProduct(id, price, imagesrc) {
var productImageElement = document.querySelector("#ProductImage_" + id);
var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price");
if (productPriceElement) {
productPriceElement.innerText = price;
}
if (productImageElement) {
productImageElement.src = imagesrc;
var imageSrcset = productImageElement.srcset;
imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&");
productImageElement.srcset = imageSrcset;
}
}
</script>
} else if (Pageview.IsVisualEditorMode) {
<div class="alert alert-dark m-0" role="alert">
<span>@Translate("The selected component does not exist anymore")</span>
</div>
}
} else {
string noProductsFoundMessage = !string.IsNullOrEmpty(Model.Item.GetString("NoProductsFoundMessage")) ? Model.Item.GetString("NoProductsFoundMessage") : Translate("We did not find anything matching your search result");
bool hasSubgroups = false;
if (productList.SubGroups != null)
{
hasSubgroups = productList.SubGroups.Any();
}
if (!Model.Item.GetBoolean("HideNoProductsFoundMessage")) {
if (!isVisualEditor)
{
<div class="alert alert-dark m-0" role="alert">
@noProductsFoundMessage
</div>
} else {
<div class="alert alert-dark m-0" role="alert">
@Translate("Product list: The list will be shown here, if any")
</div>
}
} else if (!hasSubgroups)
{
<div class="alert alert-dark m-0" role="alert">
@noProductsFoundMessage
</div>
}
}
}