Dæk

1 produkter
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_9007eb53378b4c6fadb1c53951b14cf2.Execute() in D:\dynamicweb.net\Solutions\Novicell\awintherbikes.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListItemRepeater.cshtml:line 285
   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> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Core 4 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 5 @using Dynamicweb.Environment 6 7 @functions 8 { 9 string liveInfoClass = ""; 10 } 11 12 @{ 13 bool isDetailPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")); 14 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 15 16 string productInfoFeed = ""; 17 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 18 if (isLazyLoadingForProductInfoEnabled) 19 { 20 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 21 { 22 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 23 if (!string.IsNullOrEmpty(productInfoFeed)) 24 { 25 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 26 } 27 } 28 liveInfoClass = "js-live-info"; 29 } 30 31 } 32 33 @if (!isDetailPage) { 34 <div class="h-100@(theme) item_@Model.Item.SystemName.ToLower()" @productInfoFeed> 35 @{ 36 bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false; 37 38 ProductListViewModel productList = new ProductListViewModel(); 39 40 string googleTagManagerID = Pageview.AreaSettings.GetString("GoogleTagManagerID"); 41 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 42 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 43 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 44 45 ProductListViewModelSettings productListSetting = new ProductListViewModelSettings 46 { 47 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 48 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 49 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 50 ShopId = Pageview.Area.EcomShopId 51 }; 52 53 int productsCount = 0; 54 int maxProductsCounter = 0; 55 56 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 57 { 58 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 59 } 60 else if (Pageview.Item["DummyProductGroup"] != null) 61 { 62 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 63 ProductListViewModel groupList = pageViewModel.Item.GetValue("DummyProductGroup") != null ? pageViewModel.Item.GetValue("DummyProductGroup") as ProductListViewModel : new ProductListViewModel(); 64 65 if (groupList?.Group?.Id != null) 66 { 67 productList = ViewModelFactory.CreateView(productListSetting, groupList.Group.Id); 68 Dynamicweb.Context.Current.Items.Add("ProductList", productList); 69 } 70 else 71 { 72 productList = ViewModelFactory.CreateView(productListSetting, Dynamicweb.Ecommerce.Services.ProductGroups.GetGroups(Dynamicweb.Ecommerce.Common.Context.LanguageID).FirstOrDefault().Id); 73 74 Dynamicweb.Context.Current.Items.Add("ProductList", productList); 75 } 76 } 77 else if (Pageview.Item["DummyProductGroup"] == null) 78 { 79 productList = ViewModelFactory.CreateView(productListSetting, Dynamicweb.Ecommerce.Services.ProductGroups.GetGroups(Dynamicweb.Ecommerce.Common.Context.LanguageID).FirstOrDefault().Id); 80 Dynamicweb.Context.Current.Items.Add("ProductList", productList); 81 } 82 83 if (Pageview.Page.Item.SystemName == "Swift_ProductListComponentEdit") 84 { 85 if (productList.TotalProductsCount == 0) 86 { 87 ProductViewModelSettings productSetting = new ProductViewModelSettings 88 { 89 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 90 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 91 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 92 ShopId = Pageview.Area.EcomShopId 93 }; 94 95 foreach (var product in Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(3, Dynamicweb.Ecommerce.Common.Context.LanguageID, false)) 96 { 97 var productView = ViewModelFactory.CreateView(productSetting, product.Id); 98 productList.Products.Add(productView); 99 } 100 101 Dynamicweb.Context.Current.Items["ProductList"] = productList; 102 } 103 104 productList.TotalProductsCount = 3; 105 productList.PageSize = 3; 106 maxProductsCounter = 3; 107 } 108 109 string groupId = productList?.Group?.Id != null ? productList.Group.Id : ""; 110 string url = Dynamicweb.Context.Current.Request.RawUrl; 111 112 if (productList.TotalProductsCount > 0) 113 { 114 int pageSizeSetting = 30; 115 int pageSize = productList.PageSize; 116 pageSize += pageSizeSetting; 117 118 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : productList.PageSize; 119 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : ""; 120 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : ""; 121 122 int listItemSourcePageId = Model.Item.GetInt32("ListComponentSource"); 123 var page = Dynamicweb.Content.Services.Pages.GetPage(listItemSourcePageId); 124 125 if (page != null) 126 { 127 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page); 128 129 string gridColumnSize = Model.Item.GetRawValueString("GridLayoutDesktop", "3-columns"); 130 gridColumnSize = gridColumnSize == "2-columns" ? "g-col-lg-6" : gridColumnSize; 131 gridColumnSize = gridColumnSize == "3-columns" ? "g-col-lg-4" : gridColumnSize; 132 gridColumnSize = gridColumnSize == "4-columns" ? "g-col-lg-3" : gridColumnSize; 133 gridColumnSize = gridColumnSize == "6-columns" ? "g-col-lg-2" : gridColumnSize; 134 gridColumnSize = gridColumnSize == "list" ? "" : gridColumnSize; 135 136 string gridColumnMobileSize = Model.Item.GetRawValueString("GridLayoutMobile", "2-columns"); 137 gridColumnMobileSize = gridColumnMobileSize == "list" ? "g-col-12" : gridColumnMobileSize; 138 gridColumnMobileSize = gridColumnMobileSize == "2-columns" ? "g-col-6" : gridColumnMobileSize; 139 140 string listItemTheme = " theme " + pageViewModel.Item.GetRawValueString("Theme", string.Empty).Replace(" ", "").Trim().ToLower(); 141 string listItemPadding = pageViewModel.Item.GetRawValueString("ContentPadding", string.Empty); 142 string listItemPaddingClass = string.Empty; 143 144 switch (listItemPadding) 145 { 146 case "small": 147 listItemPaddingClass = " p-2 p-xl-3"; 148 break; 149 case "large": 150 listItemPaddingClass = " p-3 p-xl-4"; 151 break; 152 case "small-x": 153 listItemPaddingClass = " px-2 px-md-3"; 154 break; 155 case "large-x": 156 listItemPaddingClass = " px-3 px-md-4"; 157 break; 158 } 159 160 <div class="grid"> 161 @if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 162 { 163 <script> 164 gtag("event", "view_item_list", { 165 item_list_id: "product_list_item_repeater", 166 item_list_name: "Product list (Item Repeater)", 167 items: [ 168 @foreach (ProductViewModel product in productList.Products) 169 { 170 <text>{ 171 item_id: "@product.Number", 172 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name)", 173 currency: "@product.Price.CurrencyCode", 174 price: @product.Price.Price 175 },</text> 176 } 177 ] 178 }); 179 </script> 180 } 181 182 @foreach (ProductViewModel product in productList.Products) 183 { 184 if (maxProductsCounter == 0 || (productsCount < maxProductsCounter)) { 185 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 186 187 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 188 { 189 Dynamicweb.Context.Current.Items["ProductDetails"] = product; 190 } 191 else 192 { 193 Dynamicweb.Context.Current.Items.Add("ProductDetails", product); 194 } 195 196 if (Model.Item.GetString("ListComponentSource") != null) { 197 <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"> 198 @{ 199 string clickProductLink = string.Empty; 200 if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 201 { 202 clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @product.Price.Price + "')\""; 203 } 204 } 205 <a href="@link" class="stretched-link" onmouseover="swift.Image.swapImage(event)" onmouseout="swift.Image.swapImage(event)" @clickProductLink> 206 <span class="visually-hidden">@product.Name</span> 207 </a> 208 @if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 209 { 210 <script> 211 function clickProductLink(productId, productName, productVariant, productCurrency, productPrice) { 212 if (typeof gtag !== "undefined") { 213 gtag("event", "select_item", { 214 item_list_id: "product_list_item_repeater", 215 item_list_name: "Product list (Item Repeater)", 216 items: [ 217 { 218 item_id: productId, 219 item_name: productName, 220 currency: productCurrency, 221 item_list_id: "product_list_item_repeater", 222 item_list_name: "Product list (Item Repeater)", 223 item_variant: productVariant, 224 price: productPrice 225 } 226 ] 227 }); 228 } 229 } 230 </script> 231 } 232 @RenderGrid(listItemSourcePageId) 233 </article> 234 } 235 236 productsCount++; 237 } 238 } 239 </div> 240 241 <div class="my-3"> 242 <div class="text-center"> 243 <div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div> 244 @if (productList.PageCount != 1 && maxProductsCounter == 0) 245 { 246 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? ""; 247 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 248 249 <form method="get" action="@url" data-response-target-element="content" class="w-100"> 250 @if (productList?.FacetGroups != null) 251 { 252 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 253 { 254 foreach (FacetViewModel facetItem in facetGroup.Facets) 255 { 256 foreach (FacetOptionViewModel facetOption in facetItem.Options) 257 { 258 if (facetOption.Selected) 259 { 260 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]"> 261 } 262 } 263 } 264 } 265 } 266 267 @if (!string.IsNullOrEmpty(searchQuery)) 268 { 269 <input type="hidden" name="q" value="@searchQuery"> 270 <input type="hidden" name="SearchLayout" value="@searchLayout"> 271 } 272 273 @if (productList?.Group?.Id != null) 274 { 275 <input type="hidden" name="GroupId" value="@productList.Group.Id"> 276 } 277 278 <input type="hidden" name="PageSize" value="@pageSize"> 279 <input type="hidden" name="SortBy" value="@sortBySelection"> 280 <input type="hidden" name="RequestType" value="UpdateList"> 281 282 @{ 283 string nextPageLink = "/Default.aspx?ID=" + Pageview.Page.ID + "&PageSize=" + pageSize + "&SortBy=" + sortBySelection; 284 285 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 286 { 287 foreach (FacetViewModel facetItem in facetGroup.Facets) 288 { 289 foreach (FacetOptionViewModel facetOption in facetItem.Options) 290 { 291 if (facetOption.Selected) 292 { 293 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]"; 294 } 295 } 296 } 297 } 298 299 nextPageLink += productList?.Group?.Id != null ? "&GroupID=" + productList.Group.Id : ""; 300 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : ""; 301 } 302 303 <a href="@nextPageLink" class="btn btn-primary" type="button" onclick="swift.ProductList.Update(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a> 304 </form> 305 } 306 </div> 307 </div> 308 309 <script> 310 function switchVariantProduct(id, price, imagesrc) { 311 var productImageElement = document.querySelector("#ProductImage_" + id); 312 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price"); 313 314 if (productPriceElement) { 315 productPriceElement.innerText = price; 316 } 317 318 if (productImageElement) { 319 productImageElement.src = imagesrc; 320 321 var imageSrcset = productImageElement.srcset; 322 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&"); 323 324 productImageElement.srcset = imageSrcset; 325 } 326 } 327 </script> 328 } 329 else if (Pageview.IsVisualEditorMode) 330 { 331 <div class="alert alert-dark m-0" role="alert"> 332 <span>@Translate("The selected component does not exist anymore")</span> 333 </div> 334 } 335 } 336 else 337 { 338 string noProductsFoundMessage = !string.IsNullOrEmpty(Model.Item.GetString("NoProductsFoundMessage")) ? Model.Item.GetString("NoProductsFoundMessage") : Translate("We did not find anything matching your search result"); 339 bool hasSubgroups = false; 340 341 if (productList.SubGroups != null) 342 { 343 hasSubgroups = productList.SubGroups.Any(); 344 } 345 346 if (!Model.Item.GetBoolean("HideNoProductsFoundMessage")) 347 { 348 if (!isVisualEditor) 349 { 350 <div class="alert alert-dark m-0" role="alert"> 351 @noProductsFoundMessage 352 </div> 353 } 354 else 355 { 356 <div class="alert alert-dark m-0" role="alert"> 357 @Translate("Product list: The list will be shown here, if any") 358 </div> 359 } 360 } 361 else if (!hasSubgroups) 362 { 363 <div class="alert alert-dark m-0" role="alert"> 364 @noProductsFoundMessage 365 </div> 366 } 367 } 368 } 369 </div> 370 } 371

Godt håndværk gennem generationer

Winther A/S har siden 1932 produceret cykler. Cykler bygget på en vision om at skabe sikker transport for børn. Cykler du kan stole på.