Navigace

Error executing template "Designs/Swift/Paragraph/Swift_ProductListItemRepeater.cshtml"
System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Concurrent.ConcurrentDictionary`2.TryGetValue(TKey key, TValue& value)
at Dynamicweb.Caching.DictionaryCache`2.GetCacheResult(IEnumerable`1 keys)
at Dynamicweb.Caching.ServiceCache`2.GetCache(IEnumerable`1 keys)
at Dynamicweb.Caching.ServiceCache`2.GetCache(TKey key)
at Dynamicweb.Ecommerce.ProductCatalog.ViewSettingsBaseCurrencyBase`1.GetCurrency()
at Dynamicweb.Ecommerce.ProductCatalog.ViewSettingsBaseCurrencyBase`1.GetPriceContext()
at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo)
at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__49()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at CompiledRazorTemplates.Dynamic.RazorEngine_cdf1cb797309447987b383518e2f8c0a.Execute() in D:\dynamicweb.net\Solutions\Dynamicweb\hctswift.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductListItemRepeater.cshtml:line 119
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 5 @{ 6 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 7 int productsCount = 0; 8 int maxProductsCounter = 0; 9 10 string productInfoFeed = ""; 11 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 12 if (isLazyLoadingForProductInfoEnabled) 13 { 14 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 15 { 16 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 17 if (!string.IsNullOrEmpty(productInfoFeed)) 18 { 19 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 20 } 21 } 22 } 23 24 ProductListViewModel productList = null; 25 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 26 { 27 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 28 } 29 else if (Pageview.Page.Item["DummyProductGroup"] != null && Pageview.IsVisualEditorMode) 30 { 31 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 32 ProductListViewModel groupList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 33 34 if (groupList?.Products is object) 35 { 36 productList = groupList; 37 } 38 } 39 } 40 41 @if (productList is object) 42 { 43 <div class="h-100@(theme) product-list item_@Model.Item.SystemName.ToLower()" @productInfoFeed> 44 @{ 45 bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false; 46 47 string groupId = productList?.Group?.Id != null ? productList.Group.Id : ""; 48 string url = Dynamicweb.Context.Current.Request.RawUrl; 49 50 if (productList.TotalProductsCount > 0) 51 { 52 int pageSizeSetting = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("OriginalPageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("OriginalPageSize")) : productList.PageSize; 53 int pageNumber = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageNum")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageNum")) : productList.CurrentPage; 54 int pageSize = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) : productList.PageSize; 55 pageNumber = pageSize != pageSizeSetting ? (pageSize / pageSizeSetting) : pageNumber; 56 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : pageSizeSetting * pageNumber; 57 loadedProducts = loadedProducts > productList.TotalProductsCount ? productList.TotalProductsCount : loadedProducts; 58 59 pageNumber += 1; 60 61 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : string.Empty; 62 searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("q")) ? Dynamicweb.Context.Current.Request.Form.Get("q") : searchQuery; 63 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : string.Empty; 64 string isVariant = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("isVariant")) ? Dynamicweb.Context.Current.Request.QueryString.Get("isVariant") : ""; 65 66 int itemSourcePageId = Convert.ToInt32(Model.Item.GetRawValueString("ListComponentSource", "0")); 67 68 var pageService = new Dynamicweb.Content.PageService(); 69 itemSourcePageId = itemSourcePageId > 0 && pageService.GetPageOrLanguage(itemSourcePageId, Pageview.AreaID) != null ? pageService.GetPageOrLanguage(itemSourcePageId, Pageview.AreaID).ID : itemSourcePageId; 70 71 var page = Dynamicweb.Content.Services.Pages.GetPage(itemSourcePageId); 72 73 if (page != null) 74 { 75 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page); 76 77 string gridColumnSize = Model.Item.GetRawValueString("GridLayoutDesktop", "3-columns"); 78 gridColumnSize = gridColumnSize == "2-columns" ? "g-col-lg-6" : gridColumnSize; 79 gridColumnSize = gridColumnSize == "3-columns" ? "g-col-lg-4" : gridColumnSize; 80 gridColumnSize = gridColumnSize == "4-columns" ? "g-col-lg-3" : gridColumnSize; 81 gridColumnSize = gridColumnSize == "6-columns" ? "g-col-lg-2" : gridColumnSize; 82 gridColumnSize = gridColumnSize == "list" ? "g-col-lg-12" : gridColumnSize; 83 84 string gridColumnMobileSize = Model.Item.GetRawValueString("GridLayoutMobile", "2-columns"); 85 gridColumnMobileSize = gridColumnMobileSize == "list" ? "g-col-12" : gridColumnMobileSize; 86 gridColumnMobileSize = gridColumnMobileSize == "2-columns" ? "g-col-6" : gridColumnMobileSize; 87 88 string listItemTheme = " theme " + pageViewModel.Item.GetRawValueString("Theme", string.Empty).Replace(" ", "").Trim().ToLower(); 89 string listItemPadding = pageViewModel.Item.GetRawValueString("ContentPadding", string.Empty); 90 string listItemPaddingClass = string.Empty; 91 92 switch (listItemPadding) 93 { 94 case "small": 95 listItemPaddingClass = " p-2 p-xl-3"; 96 break; 97 case "large": 98 listItemPaddingClass = " p-3 p-xl-4"; 99 break; 100 case "small-x": 101 listItemPaddingClass = " px-2 px-md-3"; 102 break; 103 case "large-x": 104 listItemPaddingClass = " px-3 px-md-4"; 105 break; 106 } 107108 <div class="grid pb-3"> 109 <script> 110 gtag("event", "view_item_list", { 111 item_list_id: "product_list_item_repeater", 112 item_list_name: "Product list (Item Repeater)", 113 items: [ 114 @foreach (ProductViewModel product in productList.Products) 115 { 116 <text>{ 117 item_id: "@product.Number", 118 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name)", 119 currency: "@product.Price.CurrencyCode", 120 price: @product.Price.ToStringInvariant(), 121 discount: @product.Discount.ToStringInvariant() 122 },</text> 123 } 124 ] 125 }); 126 </script> 127128 @foreach (ProductViewModel product in productList.Products) 129 { 130 if (maxProductsCounter == 0 || (productsCount < maxProductsCounter)) 131 { 132 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 133134 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 135 { 136 Dynamicweb.Context.Current.Items["ProductDetails"] = product; 137 } 138 else 139 { 140 Dynamicweb.Context.Current.Items.Add("ProductDetails", product); 141 } 142143 if (Model.Item.GetString("ListComponentSource") != null) 144 { 145 <article class="@gridColumnMobileSize @gridColumnSize @listItemTheme @listItemPaddingClass d-flex flex-column position-relative product js-product" data-product-id="@product.Id" data-variant-id="@product.VariantId" itemscope itemtype="https://schema.org/Product"> 146 @{ 147 string clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @product.Price.ToStringInvariant() + "', '" + @product.Discount.ToStringInvariant() + "')\""; 148 } 149 <a href="@link" class="stretched-link" onmouseover="swift.Image.swapImage(event)" onmouseout="swift.Image.swapImage(event)" @clickProductLink> 150 <span class="visually-hidden">@product.Name</span> 151 </a> 152153 <script> 154 function clickProductLink(productId, productName, productVariant, productCurrency, productPrice, productDiscount) { 155 if (typeof gtag !== "undefined") { 156 gtag("event", "select_item", { 157 item_list_id: "product_list_item_repeater", 158 item_list_name: "Product list (Item Repeater)", 159 items: [ 160 { 161 item_id: productId, 162 item_name: productName, 163 currency: productCurrency, 164 item_list_id: "product_list_item_repeater", 165 item_list_name: "Product list (Item Repeater)", 166 item_variant: productVariant, 167 price: productPrice, 168 discount: productDiscount 169 } 170 ] 171 }); 172 } 173 } 174 </script> 175176 @RenderGrid(itemSourcePageId) 177 </article> 178 } 179180 productsCount++; 181 } 182 } 183 </div> 184185 <div class="my-3" id="ProductListLoadMore"> 186 <div class="text-center"> 187 <div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div> 188 @if (productList.PageCount != 1 && maxProductsCounter == 0 && loadedProducts < productList.TotalProductsCount) 189 { 190 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? ""; 191 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 192 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID") : ""; 193194 <form method="get" action="@url" data-response-target-element=".product-list" data-swap="afterend" class="w-100"> 195 @if (productList?.FacetGroups != null) 196 { 197 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 198 { 199 foreach (FacetViewModel facetItem in facetGroup.Facets) 200 { 201 foreach (FacetOptionViewModel facetOption in facetItem.Options) 202 { 203 if (facetOption.Selected) 204 { 205 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]"> 206 } 207 } 208 } 209 } 210 } 211212 @if (!string.IsNullOrEmpty(searchQuery)) 213 { 214 <input type="hidden" name="q" value="@searchQuery"> 215 <input type="hidden" name="SearchLayout" value="@searchLayout"> 216 } 217218 @if (!string.IsNullOrEmpty(mainProductId)) 219 { 220 <input type="hidden" name="MainProductID" value="@mainProductId"> 221 } 222223 @if (productList?.Group?.Id != null) 224 { 225 <input type="hidden" name="GroupId" value="@groupId"> 226 } 227228 <input type="hidden" name="OriginalPageSize" value="@pageSizeSetting"> 229 <input type="hidden" name="PageSize" value="@(loadedProducts + pageSizeSetting)"> 230 <input type="hidden" name="PageNum" value="@pageNumber"> 231 <input type="hidden" name="SortBy" value="@sortBySelection"> 232 <input type="hidden" name="RequestType" value="UpdateList"> 233 <input type="hidden" name="ParagraphID" value="@Model.ID"> 234235 @if (!string.IsNullOrEmpty(isVariant)){ 236237 <input type="hidden" name="isVariant" value="@isVariant"> 238239 } 240241 @if (productList?.FacetGroups is object) 242 { 243 string nextPageLink = $"/Default.aspx?ID={Pageview.Page.ID}&PageNum={pageNumber}&SortBy={sortBySelection}"; 244245 if (!string.IsNullOrEmpty(isVariant)){ 246 nextPageLink += "&isVariant=" + isVariant ; 247 } 248249250 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 251 { 252 foreach (FacetViewModel facetItem in facetGroup.Facets) 253 { 254 foreach (FacetOptionViewModel facetOption in facetItem.Options) 255 { 256 if (facetOption.Selected) 257 { 258 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]"; 259 } 260 } 261 } 262 } 263264 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : ""; 265 string disableLoadMore = isLazyLoadingForProductInfoEnabled ? "d-none" : ""; 266267 <a href="@nextPageLink" class="btn btn-primary swift_load_more_button @disableLoadMore" onclick="swift.ProductList.Update(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a> 268 } 269 </form> 270 } 271 </div> 272 </div> 273274 <script> 275 function switchVariantProduct(id, price, imagesrc) { 276 var productImageElement = document.querySelector("#ProductImage_" + id); 277 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price"); 278279 if (productPriceElement) { 280 productPriceElement.innerText = price; 281 } 282283 if (productImageElement) { 284 productImageElement.src = imagesrc; 285286 var imageSrcset = productImageElement.srcset; 287 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&"); 288289 productImageElement.srcset = imageSrcset; 290 } 291 } 292 </script> 293 } 294 else if (Pageview.IsVisualEditorMode) 295 { 296 <div class="alert alert-dark m-0" role="alert"> 297 <span>@Translate("The selected component does not exist anymore")</span> 298 </div> 299 } 300 } 301 else 302 { 303 string noProductsFoundMessage = !string.IsNullOrEmpty(Model.Item.GetString("NoProductsFoundMessage")) ? Model.Item.GetString("NoProductsFoundMessage") : Translate("We did not find anything matching your search result"); 304 bool hasSubgroups = false; 305306 if (productList.SubGroups != null) 307 { 308 hasSubgroups = productList.SubGroups.Any(); 309 } 310311 if (!Model.Item.GetBoolean("HideNoProductsFoundMessage")) 312 { 313 if (!isVisualEditor) 314 { 315 <div class="alert alert-dark m-0" role="alert"> 316 @noProductsFoundMessage 317 </div> 318 } 319 else 320 { 321 <div class="alert alert-dark m-0" role="alert"> 322 @Translate("Product list: The list will be shown here, if any") 323 </div> 324 } 325 } 326 else if (!hasSubgroups) 327 { 328 <div class="alert alert-dark m-0" role="alert"> 329 @noProductsFoundMessage 330 </div> 331 } 332 } 333 } 334 </div> 335 } 336 else if (Pageview.IsVisualEditorMode) 337 { 338 <div class="alert alert-dark m-0" role="alert"> 339 <span>@Translate("Product list item repeater: The repeater paragraph will be shown here, if any products are available")</span> 340 </div> 341 } 342