Error executing template "Designs/Swift/eCom/ProductCatalog/ProductViewDetail.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_64c40966a23c4374b822c52188fc8466.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits ViewModelTemplate<ProductViewModel> 2 @using Dynamicweb.Rendering 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Core 5 6 @{ 7 string metaDescription = string.IsNullOrEmpty(Model.MetaDescription) ? Model.Name : Model.MetaDescription; 8 9 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Model.DefaultImage.Value}\">"); 10 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{Model.Name}\">"); 11 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{metaDescription}\">"); 12 13 Pageview.Meta.AddTag("twitter:image", Model.DefaultImage.Value); 14 Pageview.Meta.AddTag("twitter:image:alt", Model.Name); 15 Pageview.Meta.AddTag("twitter:description", metaDescription); 16 } 17 18 @{ 19 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 20 { 21 Dynamicweb.Context.Current.Items["ProductDetails"] = Model; 22 } 23 else 24 { 25 Dynamicweb.Context.Current.Items.Add("ProductDetails", Model); 26 } 27 28 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 29 if (isLazyLoadingForProductInfoEnabled) 30 { 31 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 32 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 33 bool hasVariantId = !string.IsNullOrEmpty(Model.VariantId); 34 string variantIdParam = hasVariantId ? $"/{Model.VariantId}" : ""; 35 string priceFilledProperties = $"Price,PriceFormatted{(showPricesWithVat == "false" && !neverShowVat ? ",PriceWithVat,PriceWithVatFormatted" : "")}"; 36 string productInfoFeed = $@"/dwapi/ecommerce/products/{Model.Id}{variantIdParam} 37 ?UserId={Converter.ToString(Pageview.User?.ID)} 38 &LanguageId={Pageview.Area.EcomLanguageId}&CurrencyCode={Pageview.Area.EcomCurrencyId}&CountryCode={Pageview.Area.EcomCountryCode}&ShopId={Pageview.Area.EcomShopId} 39 &FilledProperties=Id,Price,PriceBeforeDiscount,StockLevel,VariantInfo,NeverOutOfstock,Prices 40 &PriceSettings.ShowPricesWithVat={Pageview.Area.EcomPricesWithVat} 41 &PriceSettings.FilledProperties={priceFilledProperties} 42 &getproductinfo=true"; 43 Dynamicweb.Context.Current.Items["ProductInfoFeed"] = productInfoFeed; 44 45 <script type="module"> 46 swift.LiveProductInfo.init(); 47 </script> 48 } 49 } 50 51 <script> 52 gtag("event", "view_item", { 53 currency: "@Model.Price.CurrencyCode", 54 value: @PriceViewModelExtensions.ToStringInvariant(Model.Price), 55 items: [ 56 { 57 item_id: "@Model.Number", 58 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", 59 currency: "@Model.Price.CurrencyCode", 60 price: @PriceViewModelExtensions.ToStringInvariant(Model.Price) 61 } 62 ] 63 }); 64 </script> 65 66 <script> 67 window.addEventListener('load', function (event) { 68 swift.Video.init(); 69 }); 70 </script> 71
Error executing template "/Designs/Swift/Paragraph/Swift_ProductDetailsImage_Custom.cshtml" System.ArgumentNullException: Value cannot be null. (Parameter 'source') at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate) at CompiledRazorTemplates.Dynamic.RazorEngine_66c33de136704350b5f7079e0debebea.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) 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.Frontend 4 @using System.IO 5 @using System.Text.RegularExpressions @using Dynamicweb.Data 6 7 @functions { 8 public ProductViewModel product { get; set; } = new ProductViewModel(); 9 public string galleryLayout { get; set; } 10 public string[] supportedImageFormats { get; set; } 11 public string[] supportedVideoFormats { get; set; } 12 public string[] supportedDocumentFormats { get; set; } 13 public string[] allSupportedFormats { get; set; } 14 15 public class RatioSettings 16 { 17 public string Ratio { get; set; } 18 public string CssClass { get; set; } 19 public string CssVariable { get; set; } 20 public string Fill { get; set; } 21 } 22 23 public RatioSettings GetRatioSettings(string size = "desktop") 24 { 25 var ratioSettings = new RatioSettings(); 26 27 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 28 ratio = ratio != "0" ? ratio : ""; 29 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 30 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 31 cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; 32 cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; 33 34 ratioSettings.Ratio = ratio; 35 ratioSettings.CssClass = cssClass; 36 ratioSettings.CssVariable = cssVariable; 37 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 38 39 return ratioSettings; 40 } 41 42 public string GetArrowsColor() 43 { 44 var invertColor = Model.Item.GetBoolean("InvertModalArrowsColor"); 45 var arrowsColor = invertColor ? " carousel-dark" : string.Empty; 46 return arrowsColor; 47 } 48 49 public string GetThumbnailPlacement() 50 { 51 return Model.Item.GetRawValueString("ThumbnailPlacement", "bottom"); 52 } 53 54 public string GetThumbnailRowSettingCss() 55 { 56 switch (GetThumbnailPlacement()) 57 { 58 case "bottom": 59 return "d-flex flex-wrap"; 60 case "left": 61 return "d-flex flex-column order-first"; 62 case "right": 63 return "d-flex flex-column order-last"; 64 default: 65 return "d-flex flex-wrap"; 66 } 67 } 68 69 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) 70 { 71 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 72 string type = GetVideoType(asset.Value); 73 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; 74 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 75 76 var videoParams = new Dictionary<string, object>(); 77 videoParams.Add("AssetName", asset.Name); 78 videoParams.Add("AssetVideoType", type); 79 videoParams.Add("AssetDisplayName", asset.DisplayName); 80 videoParams.Add("OpenVideoInModal", openInModal); 81 videoParams.Add("VideoAutoPlay", autoPlay); 82 videoParams.Add("Size", size); 83 videoParams.Add("Id", Model.ID); 84 return videoParams; 85 86 } 87 88 public string GetVideoType(string assetValue) 89 { 90 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; 91 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 92 type = string.IsNullOrEmpty(type) ? "selfhosted" : type; 93 94 return type; 95 } 96 97 public string GetYoutubeScreenDump(string assetValue, string quality) 98 { 99 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?"); 100 Match match = regex.Match(assetValue); 101 string videoId = match.Success ? match.Groups[1].Value : string.Empty; 102 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/{quality}.jpg"; 103 return youtubeThumbnail; 104 } 105 106 private bool DefaultImageBelongsToVariant(ProductViewModel product) 107 { 108 string search = "/Files/"; string input = product.DefaultImage.Value; 109 int index = input.IndexOf(search); string detailValue = input.Substring(index + search.Length); string query = $"SELECT COUNT(*) AS RelationExists FROM EcomDetails" + 110 $" WHERE DetailProductId = '{product.Id}'" + 111 $" AND DetailVariantId = '{product.VariantId}'" + 112 $" AND DetailLanguageId = '{product.LanguageId}'" + 113 $" AND DetailValue = '{detailValue}'"; 114 using (var reader = Database.CreateDataReader(query)) 115 { 116 while (reader.Read()) 117 { 118 return reader["RelationExists"].ToString() != "0"; 119 } 120 } 121 return false; 122 } 123 } 124 125 @{ 126 ProductViewModel product = null; 127 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 128 { 129 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 130 } 131 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 132 { 133 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 134 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 135 136 if (productList?.Products is object) 137 { 138 product = productList.Products[0]; 139 } 140 } 141 } 142 143 @if (product is object) 144 { 145 @* Supported formats *@ 146 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 147 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 148 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx" }; 149 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 150 151 @* Collect the assets *@ 152 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 153 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 154 155 @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ 156 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 157 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 158 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 159 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 160 assetsList = assetsList.Union(assetsImages); 161 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 162 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 163 164 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 165 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 166 167 int totalAssets = 0; 168 if (showOnlyPrimaryImage == false) 169 { 170 foreach (MediaViewModel asset in assetsList) 171 { 172 var assetValue = asset.Value; 173 foreach (string format in allSupportedFormats) 174 { 175 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 176 { 177 totalAssets++; 178 } 179 } 180 } 181 } 182 183 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null) || totalAssets == 0 && defaultImageFallback) 184 { 185 assetsList = new List<MediaViewModel>() { product.DefaultImage }; 186 totalAssets = 1; 187 } 188 @* Remove default product image from variant if its not the only image and not actually assigned to it *@ 189 if (assetsImages.Count() > 1 && !string.IsNullOrEmpty(product.VariantId) && product.DefaultImage != null && !DefaultImageBelongsToVariant(product)) 190 { 191 List<MediaViewModel> assetsListList = assetsList.ToList(); 192 assetsListList.Remove(assetsListList.First(x => x.Value.Equals(defaultImage))); 193 totalAssets--; 194 assetsList = assetsListList; 195 } 196 197 @* Theme settings *@ 198 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 199 200 var badgeParms = new Dictionary<string, object>(); 201 badgeParms.Add("size", "h5"); 202 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 203 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 204 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 205 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 206 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 207 208 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 209 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 210 DateTime createdDate = product.Created.Value; 211 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 212 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 213 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; 214 215 @* Get assets from selected categories or get all assets *@ 216 if (totalAssets != 0) 217 { 218 int assetNumber = 0; 219 int thumbnailNumber = 0; 220 int modalAssetNumber = 0; 221 string thumbnailAxisCss = GetThumbnailPlacement() == "bottom" ? "flex-column" : string.Empty; 222 223 <div class="d-flex gap-3 h-100 @(thumbnailAxisCss) @(theme) item_@Model.Item.SystemName.ToLower()"> 224 <div id="SmallScreenImages_@Model.ID" class="carousel@(GetArrowsColor()) col position-relative" data-bs-ride="carousel"> 225 <div class="carousel-inner h-100"> 226 @foreach (MediaViewModel asset in assetsList) 227 { 228 var assetValue = asset.Value; 229 foreach (string format in allSupportedFormats) 230 { 231 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 232 { 233 string activeSlide = assetNumber == 0 ? "active" : ""; 234 235 <div class="carousel-item @activeSlide" data-bs-interval="99999"> 236 @{ 237 string size = "mobile"; 238 239 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 240 241 242 <div class="h-100 @(imageTheme)"> 243 @foreach (string imageFormat in supportedImageFormats) 244 { //Images 245 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 246 { 247 if (product is object) 248 { 249 string productName = product.Name; 250 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 251 string imageLinkPath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 252 253 RatioSettings ratioSettings = GetRatioSettings(size); 254 255 var parms = new Dictionary<string, object>(); 256 parms.Add("alt", productName + asset.Keywords); 257 parms.Add("itemprop", "image"); 258 parms.Add("columns", Model.GridRowColumnCount); 259 parms.Add("eagerLoadNewImages", Model.Item.GetBoolean("DisableLazyLoading")); 260 parms.Add("doNotUseGetimage", Model.Item.GetBoolean("DisableGetImage")); 261 if (!string.IsNullOrEmpty(asset.DisplayName)) 262 { 263 parms.Add("title", asset.DisplayName); 264 } 265 266 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") 267 { 268 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 269 } 270 else 271 { 272 parms.Add("cssClass", "mw-100 mh-100"); 273 } 274 275 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 276 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 277 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 278 </div> 279 </a> 280 } 281 } 282 } 283 @foreach (string videoFormat in supportedVideoFormats) 284 { //Videos 285 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 286 { 287 if (Model.Item.GetString("OpenVideoInModal") == "true") 288 { 289 if (product is object) 290 { 291 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 292 293 string productName = product.Name; 294 productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 295 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 296 297 RatioSettings ratioSettings = GetRatioSettings(size); 298 299 string type = GetVideoType(asset.Value); 300 301 string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "maxresdefault") : string.Empty; 302 videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; 303 string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : ""; 304 305 306 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 307 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 308 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 309 @if (type != "selfhosted") 310 { 311 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> 312 } 313 else 314 { 315 string videoType = Path.GetExtension(asset.Value).ToLower(); 316 317 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 318 <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> 319 </video> 320 } 321 </div> 322 </div> 323 324 } 325 } 326 else 327 { 328 if (product is object) 329 { 330 var videoParams = GetVideoParams(asset, size); 331 @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value}, videoParams); 332 333 } 334 } 335 } 336 } 337 @foreach (string documentFormat in supportedDocumentFormats) 338 { //Documents 339 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) 340 { 341 if (product is object) 342 { 343 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 344 345 string productName = product.Name; 346 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 347 string imageLinkPath = imagePath; 348 349 RatioSettings ratioSettings = GetRatioSettings(size); 350 351 var parms = new Dictionary<string, object>(); 352 parms.Add("alt", productName + asset.Keywords); 353 parms.Add("itemprop", "image"); 354 parms.Add("fullwidth", true); 355 parms.Add("columns", Model.GridRowColumnCount); 356 if (!string.IsNullOrEmpty(asset.DisplayName)) 357 { 358 parms.Add("title", asset.DisplayName); 359 } 360 361 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") 362 { 363 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 364 } 365 else 366 { 367 parms.Add("cssClass", "mw-100 mh-100"); 368 } 369 370 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@Translate("Download")"> 371 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 372 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 373 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 374 { 375 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 376 } 377 </div> 378 </a> 379 } 380 381 } 382 } 383 </div> 384 } 385 386 387 </div> 388 assetNumber++; 389 } 390 } 391 } 392 </div> 393 @if (showBadges) 394 { 395 <div class="position-absolute top-0 left-0 p-2 p-lg-3"> 396 @{@RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms)} 397 </div> 398 } 399 400 </div> 401 402 @if (totalAssets > 1) 403 { 404 <div class="@(GetThumbnailRowSettingCss()) gap-3" id="SmallScreenImagesThumbnails_@Model.ID"> 405 @foreach (MediaViewModel asset in assetsList) 406 { 407 var assetValue = asset.Value; 408 string assetName = asset.Name; 409 assetName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 410 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : null; 411 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 412 413 string imagePath = Dynamicweb.Context.Current.Server.UrlEncode(assetValue); 414 imagePath = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + assetValue.Substring(assetValue.LastIndexOf('/') + 1) + "/mqdefault.jpg" : imagePath; 415 string imagePathThumb = assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=webp" : imagePath : assetValue; 416 417 RatioSettings ratioSettings = GetRatioSettings("desktop"); 418 419 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer; min-width: 7rem; max-width: 8rem;" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to="@thumbnailNumber"> 420 @foreach (string imageFormat in supportedImageFormats) 421 { //Images 422 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 423 { 424 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain;"> 425 426 thumbnailNumber++; 427 } 428 } 429 430 @foreach (string videoFormat in supportedVideoFormats) 431 { //Videos 432 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 433 { 434 435 string type = GetVideoType(asset.Value); 436 437 string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "mqdefault") : ""; 438 videoScreendumpPath = type == "vimeo" ? string.Empty : videoScreendumpPath; 439 videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; 440 string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; 441 442 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 443 444 if (type != "selfhosted") 445 { 446 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@assetTitle" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;" /> 447 } 448 else 449 { 450 string videoType = Path.GetExtension(asset.Value).ToLower(); 451 452 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 453 <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> 454 </video> 455 } 456 457 thumbnailNumber++; 458 } 459 } 460 461 @foreach (string documentFormat in supportedDocumentFormats) 462 { //Documents 463 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) 464 { 465 <a href="@assetValue" class="ratio ratio-4x3 border outline-none" style="cursor: pointer; min-width: 7rem; max-width: 8rem;" download title="@asset.Value"> 466 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 467 { 468 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 469 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 470 </div> 471 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 mw-100 mh-100" style="object-fit: cover;"> 472 } 473 else 474 { 475 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 476 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 477 </div> 478 } 479 </a> 480 481 thumbnailNumber++; 482 } 483 } 484 </div> 485 } 486 </div> 487 } 488 </div> 489 490 @* Modal with slides *@ 491 <div class="modal fade swift_products-details-images-modal" id="modal_@Model.ID" tabindex="-1" aria-labelledby="productDetailsGalleryModalTitle_@Model.ID" aria-hidden="true"> 492 <div class="modal-dialog modal-dialog-centered modal-xl"> 493 <div class="modal-content"> 494 <div class="modal-header visually-hidden"> 495 <h5 class="modal-title" id="productDetailsGalleryModalTitle_@Model.ID">@product.Title</h5> 496 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 497 </div> 498 <div class="modal-body p-2 p-lg-3 h-100"> 499 <div id="ModalCarousel_@Model.ID" class="carousel@(GetArrowsColor()) h-100" data-bs-ride="carousel"> 500 <div class="carousel-inner h-100 @theme"> 501 @foreach (MediaViewModel asset in assetsList) 502 { 503 var assetValue = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 504 foreach (string supportedFormat in supportedImageFormats.Concat(supportedVideoFormats).ToArray()) 505 { 506 if (assetValue.IndexOf(supportedFormat, StringComparison.OrdinalIgnoreCase) >= 0) 507 { 508 string imagePath = assetValue; 509 string activeSlide = modalAssetNumber == 0 ? "active" : ""; 510 511 var parms = new Dictionary<string, object>(); 512 parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); 513 parms.Add("fullwidth", true); 514 parms.Add("columns", Model.GridRowColumnCount); 515 516 <div class="carousel-item @activeSlide h-100" data-bs-interval="99999"> 517 @foreach (string imageFormat in supportedImageFormats) 518 { //Images 519 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 520 { 521 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 522 } 523 } 524 525 @foreach (string videoFormat in supportedVideoFormats) 526 { //Videos 527 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 528 { 529 var videoParams = GetVideoParams(asset, "modal"); 530 @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value }, videoParams) 531 } 532 } 533 </div> 534 modalAssetNumber++; 535 } 536 } 537 } 538 <button class="carousel-control-prev carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="prev"> 539 <span class="carousel-control-prev-icon" aria-hidden="true"></span> 540 <span class="visually-hidden">@Translate("Previous")</span> 541 </button> 542 <button class="carousel-control-next carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="next"> 543 <span class="carousel-control-next-icon" aria-hidden="true"></span> 544 <span class="visually-hidden">@Translate("Next")</span> 545 </button> 546 </div> 547 </div> 548 </div> 549 </div> 550 </div> 551 </div> 552 } 553 else if (Pageview.IsVisualEditorMode) 554 { 555 RatioSettings ratioSettings = GetRatioSettings("desktop"); 556 557 <div class="h-100 @theme"> 558 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> 559 <img src="/Files/Images/missing_image.jpg" loading="lazy" decoding="async" class="mh-100 mw-100" style="object-fit: cover;"> 560 </div> 561 </div> 562 } 563 } 564 else if (Pageview.IsVisualEditorMode) 565 { 566 <div class="alert alert-dark m-0">@Translate("No products available")</div> 567 } 568 569 570 571
Product information
Error executing template "Designs/Swift/Paragraph/Swift_ProductDetailsSafetySymbols.cshtml" System.ArgumentNullException: Value cannot be null. (Parameter 'source') at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate) at CompiledRazorTemplates.Dynamic.RazorEngine_8d53c520731c419d859794fe10b5b935.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) 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.Frontend 4 @using System.IO 5 6 @functions { 7 public ProductViewModel product { get; set; } = new ProductViewModel(); 8 } 9 10 @{ 11 @* Handle the product *@ 12 ProductViewModel product = null; 13 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 14 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 15 { 16 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 17 } 18 else if (Pageview.Item["DummyProduct"] != null) 19 { 20 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 21 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 22 23 if (productList?.Products is object) 24 { 25 product = productList.Products[0]; 26 } 27 } 28 } 29 30 @if (product is object) 31 { 32 33 @* Collect the assets *@ 34 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 35 36 @* Collect Image Assets *@ 37 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 38 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 39 assetsList = assetsList.Union(assetsImages); 40 41 int totalAssets = 0; 42 foreach (MediaViewModel asset in assetsList) 43 { 44 totalAssets++; 45 } 46 47 @* Get assets from selected categories or get all assets *@ 48 if (totalAssets != 0) 49 { 50 <div class="h-100@(theme) position-relative item_@Model.Item.SystemName.ToLower()"> 51 <div id="SafetySymbols_@Model.ID" class="grid grid-12 gap-2 overflow-x-auto my-3 align-items-center"> 52 @foreach (MediaViewModel asset in assetsList) 53 { 54 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 55 string imageLinkPath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 56 57 var parms = new Dictionary<string, object>(); 58 parms.Add("title", asset.DisplayName); 59 parms.Add("cssClass", "p-0 p-lg-1 w-100"); 60 parms.Add("style", "object-fit: contain"); 61 62 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 63 } 64 </div> 65 </div> 66 } 67 else if (Pageview.IsVisualEditorMode) 68 { 69 <div class="h-100 @theme"> 70 <div class="alert alert-dark m-0"> 71 @Translate("Safety symbols: The symbols will be shown here, if any") 72 </div> 73 </div> 74 } 75 } 76 else if (Pageview.IsVisualEditorMode) 77 { 78 <div class="h-100 @theme"> 79 <div class="alert alert-dark m-0"> 80 @Translate("Safety symbols: The symbols will be shown here, if any") 81 </div> 82 </div> 83 } 84
Error executing template "Designs/Swift/Paragraph/Swift_ProductDetailsMediaTableCustom.cshtml" System.ArgumentNullException: Value cannot be null. (Parameter 'source') at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate) at CompiledRazorTemplates.Dynamic.RazorEngine_f869d2080ebc4c4e9c6e63625c0fbe52.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) 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.Frontend 4 @using System.IO 5 6 @functions { 7 public ProductViewModel product { get; set; } = new ProductViewModel(); 8 public string[] allSupportedFormats { get; set; } 9 10 public class RatioSettings 11 { 12 public string Ratio { get; set; } 13 public string CssClass { get; set; } 14 public string CssVariable { get; set; } 15 public string Fill { get; set; } 16 } 17 18 public RatioSettings GetRatioSettings() 19 { 20 var ratioSettings = new RatioSettings(); 21 22 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 23 ratio = ratio != "0" ? ratio : ""; 24 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 25 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 26 27 ratioSettings.Ratio = ratio; 28 ratioSettings.CssClass = cssClass; 29 ratioSettings.CssVariable = cssVariable; 30 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 31 32 return ratioSettings; 33 } 34 } 35 36 @{ 37 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 38 39 @* Get the product data *@ 40 ProductViewModel product = null; 41 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 42 { 43 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 44 } 45 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 46 { 47 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 48 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 49 50 if (productList?.Products is object) 51 { 52 product = productList.Products[0]; 53 } 54 } 55 } 56 57 @if (product is object) 58 { 59 @* Supported formats *@ 60 allSupportedFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx", "http" }; 61 62 @* Collect the assets *@ 63 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 64 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 65 66 @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ 67 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 68 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 69 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 70 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 71 72 assetsList = assetsList.Union(assetsImages); 73 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 74 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 75 76 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 77 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 78 79 int totalAssets = 0; 80 if (showOnlyPrimaryImage == false) 81 { 82 foreach (MediaViewModel asset in assetsList) 83 { 84 var assetValue = asset.Value; 85 foreach (string format in allSupportedFormats) 86 { 87 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 88 { 89 totalAssets++; 90 } 91 } 92 } 93 } 94 95 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null)) 96 { 97 assetsList = new List<MediaViewModel>() { product.DefaultImage }; 98 totalAssets = 1; 99 } 100 101 @* Layout settings *@ 102 string spacing = Model.Item.GetRawValueString("Spacing", "p-0"); 103 spacing = spacing == "none" ? "p-0" : spacing; 104 spacing = spacing == "small" ? "p-3" : spacing; 105 spacing = spacing == "large" ? "p-5" : spacing; 106 107 bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails"); 108 109 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 110 111 @* Get assets from selected categories or get all assets *@ 112 113 if (totalAssets != 0 && assetsList.Any()) 114 { 115 string assetCategoryName = string.Empty; 116 <div class="@spacing@(theme) item_@Model.Item.SystemName.ToLower()"> 117 @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 118 { 119 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 120 121 <h3 class="@titleFontSize mb-3"> 122 @Model.Item.GetString("Title") 123 </h3> 124 } 125 126 <div class="table-responsive"> 127 <table class="table table-hover align-middle mb-0" style="table-layout: fixed;"> 128 @foreach (MediaViewModel asset in assetsList.OrderBy(a => a.Keywords)) 129 { 130 var assetValue = asset.Value; 131 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); 132 string assetCategoryNameCurrent = asset.Keywords; 133 if (assetCategoryNameCurrent != assetCategoryName) 134 { 135 <thead class="border-top-0"> 136 <tr> 137 @if (!hideThumbnails) 138 { 139 <th style="width:60px"> </th> 140 } 141 <th>@asset.Keywords</th> 142 </tr> 143 </thead> 144 } 145 <tbody class="border-top-0"> 146 <tr> 147 @if (!hideThumbnails) 148 { 149 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 150 <td class="@(imageTheme) px-0"> 151 @foreach (string format in allSupportedFormats) 152 { //All 153 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 154 { 155 string productName = product.Name; 156 productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 157 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 158 string imageLinkPath = imagePath; 159 imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; 160 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 161 162 RatioSettings ratioSettings = GetRatioSettings(); 163 164 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName"> 165 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 166 { 167 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 168 <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle /> 169 </div> 170 } 171 else 172 { 173 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 174 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 175 </div> 176 } 177 </a> 178 } 179 } 180 </td> 181 } 182 <td> 183 <a href="@assetValue" class="text-decoration-none text-break" title="@assetName" target="_blank" style="display:flex"> 184 <div class="icon-2" style="z-index: 1; margin-right: 0.2em">@ReadFile(iconPath + "download.svg")</div> @assetName 185 </a> 186 </td> 187 </tr> 188 </tbody> 189 assetCategoryName = asset.Keywords; 190 } 191 </table> 192 </div> 193 </div> 194 } 195 else if (Pageview.IsVisualEditorMode) 196 { 197 <div class="h-100 @theme"> 198 <div class="alert alert-dark m-0"> 199 @Translate("No assets are available") 200 </div> 201 </div> 202 } 203 } 204 else if (Pageview.IsVisualEditorMode) 205 { 206 <div class="h-100 @theme"> 207 <div class="alert alert-dark m-0"> 208 @Translate("No assets are available") 209 </div> 210 </div> 211 } 212
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProductsList_Custom.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_dcdb384c88394fc283f14c784ddfb8f5.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) 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.Frontend 4 5 @{ 6 ProductViewModel product = new ProductViewModel(); 7 8 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 9 { 10 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 11 } 12 13 string servicePageId = Model.Item.GetLink("ServicePage") != null ? Model.Item.GetLink("ServicePage").PageId.ToString() : ""; 14 servicePageId = servicePageId == "" && GetPageIdByNavigationTag("RelatedProductsListService") != 0 ? GetPageIdByNavigationTag("RelatedProductsListService").ToString() : servicePageId; 15 string pageSize = Model.Item.GetInt32("PageSize") != 0 ? Model.Item.GetString("PageSize") : "10"; 16 17 IEnumerable<string> selectedDisplayGroups = Model.Item.GetList("Fields")?.GetRawValue().OfType<string>().ToList(); 18 string selectedDisplayGroupsString = selectedDisplayGroups.Count() > 0 ? (string.Join(",", selectedDisplayGroups.Select(x => x.ToString()).ToArray())) : ""; 19 20 string title = !string.IsNullOrEmpty(Model.Item.GetString("Title")) ? Model.Item.GetString("Title") : ""; 21 string hideTitle = Model.Item.GetBoolean("HideTitle").ToString(); 22 string hideImage = Model.Item.GetBoolean("HideImage").ToString(); 23 string hideProductNumber = Model.Item.GetBoolean("HideProductNumber").ToString(); 24 string hideProductName = Model.Item.GetBoolean("HideProductName").ToString(); 25 string hideStock = (Model.Item.GetBoolean("HideStock") || Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"])).ToString(); 26 string quantitySelector = Model.Item.GetBoolean("QuantitySelector").ToString(); 27 string hideProductPackagingInformation = Model.Item.GetBoolean("HideProductPackagingInformation").ToString(); 28 29 string relationGroupId = !string.IsNullOrEmpty(Model.Item.GetString("RelationGroup")) ? Model.Item.GetString("RelationGroup") : ""; 30 31 string campaignValues = string.Join(",", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 32 33 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 34 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : ""; 35 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-6"); 36 37 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 38 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 39 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 40 41 //Source type 42 string sourceType = Model.Item.GetRawValueString("SourceType", "variants"); 43 IList<string> relateFromProductIds = new List<string> { }; 44 45 //--- RELATED PRODUCTS --- 46 if (sourceType == "related-products" && product?.RelatedGroups != null) { 47 foreach (var group in product.RelatedGroups) 48 { 49 if (group.Id != relationGroupId) continue; 50 foreach (var relatedProduct in group.Products) 51 { 52 if (string.IsNullOrEmpty(relatedProduct.VariantId)) 53 { 54 relateFromProductIds.Add($"{relatedProduct.ProductId}"); 55 } 56 else 57 { 58 relateFromProductIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}"); 59 } 60 } 61 } 62 } 63 64 //Create group id collection and products id collection strings 65 string groupId = product.PrimaryOrDefaultGroup.Id; 66 string productIds = sourceType == "related-products" ? string.Join(",", relateFromProductIds) : product.Id; 67 bool doNotRenderParagraph = sourceType == "related-products" && !relateFromProductIds.Any(); 68 69 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 70 } 71 72 @if (!Pageview.IsVisualEditorMode && !doNotRenderParagraph) 73 { 74 <div id="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID" class="item_@Model.Item.SystemName.ToLower()"> 75 @* Initial form for first load (We pass all the settings to the actual template) *@ 76 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@Pageview.CurrentParagraph.ID" data-response-target-element="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID"> 77 <input type="hidden" name="SortOrder" value="DESC"> 78 <input type="hidden" name="ID" value="@servicePageId"> 79 <input type="hidden" name="SourceType" value="@sourceType"> 80 <input type="hidden" name="ParagraphID" value="@Pageview.CurrentParagraph.ID"> 81 <input type="hidden" name="PageSize" value="@pageSize" id="RelatedProductsListPageSize_@Pageview.CurrentParagraph.ID"> 82 <input type="hidden" name="PageSizeSetting" value="@pageSize"> 83 <input type="hidden" name="Title" value="@title"> 84 <input type="hidden" name="HideTitle" value="@hideTitle"> 85 <input type="hidden" name="SelectedDisplayGroups" value="@selectedDisplayGroupsString"> 86 <input type="hidden" name="HideImage" value="@hideImage"> 87 <input type="hidden" name="HideProductNumber" value="@hideProductNumber"> 88 <input type="hidden" name="HideProductName" value="@hideProductName"> 89 <input type="hidden" name="HideStock" value="@hideStock"> 90 <input type="hidden" name="QuantitySelector" value="@quantitySelector"> 91 <input type="hidden" name="Theme" value="@theme"> 92 <input type="hidden" name="ModalTheme" value="@modalTheme"> 93 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 94 <input type="hidden" name="ContentPadding" value="@contentPadding"> 95 <input type="hidden" name="HideProductPackagingInformation" value="@hideProductPackagingInformation"> 96 @if (isLazyLoadingForProductInfoEnabled) 97 { 98 <input type="hidden" name="getproductinfo" value="true"> 99 } 100 101 @*--- VARIANTS ---*@ 102 @if (sourceType == "variants") 103 { 104 <input type="hidden" name="MainProductID" value="@productIds"> 105 } 106 107 @*--- MOST SOLD ---*@ 108 @if (sourceType == "most-sold") 109 { 110 <input type="hidden" name="SortBy" value="OrderCount"> 111 <input type="hidden" name="GroupId" value="@groupId"> 112 <input type="hidden" name="isVariant" value="false"> 113 } 114 115 @*--- TRENDING ---*@ 116 @if (sourceType == "trending") 117 { 118 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 119 <input type="hidden" name="GroupId" value="@groupId"> 120 <input type="hidden" name="isVariant" value="false"> 121 } 122 123 @*--- LATEST ---*@ 124 @if (sourceType == "latest") 125 { 126 <input type="hidden" name="SortBy" value="Created"> 127 <input type="hidden" name="GroupId" value="@groupId"> 128 <input type="hidden" name="isVariant" value="false"> 129 } 130 131 @*--- FREQUENTLY BOUGHT ---*@ 132 @if (sourceType == "frequently") 133 { 134 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 135 <input type="hidden" name="isVariant" value="false"> 136 } 137 138 @*--- RELATED PRODUCTS ---*@ 139 @if (sourceType == "related-products") 140 { 141 <input type="hidden" name="ProductvariantId" value="@productIds"> 142 } 143 144 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 145 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 146 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 147 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 148 149 @if (campaignValues != "") 150 { 151 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 152 } 153 </form> 154 </div> 155 156 <script type="module"> 157 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_@Pageview.CurrentParagraph.ID")); 158 </script> 159 160 <script> 161 var UpdateRelatedProductsList = function(event, type, id) { 162 var targetElement = "RelatedProductsListContainer_" + id; 163 164 if (type == "UpdateFacets") { 165 targetElement = "RelatedProductsListFacets_" + id; 166 } 167 168 document.querySelector('#RelatedProductsListRequestType_' + id).value = type; 169 document.querySelector('#RelatedProductsListForm_' + id).setAttribute("data-response-target-element", targetElement); 170 171 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_" + id)); 172 }; 173 </script> 174 } 175 else if (!Pageview.IsVisualEditorMode && doNotRenderParagraph) 176 { 177 178 } 179 else 180 { 181 <div class="alert alert-info" role="alert"> 182 <span>@Translate("Related products list")</span> 183 </div> 184 } 185
Error executing template "Designs/Swift/Paragraph/Swift_ProductVariantList_Custom.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_e7f5b81e3ec34f5998012828865c49b3.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @*Base for this template is: Swift_RelatedProductsList.cshtml*@ 2 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Frontend 5 6 @{ 7 ProductViewModel product = new ProductViewModel(); 8 9 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 10 { 11 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 12 } 13 14 string servicePageId = Model.Item.GetLink("ServicePage") != null ? Model.Item.GetLink("ServicePage").PageId.ToString() : ""; 15 servicePageId = servicePageId == "" && GetPageIdByNavigationTag("ProductVariantListService") != 0 ? GetPageIdByNavigationTag("ProductVariantListService").ToString() : servicePageId; 16 string pageSize = Model.Item.GetInt32("PageSize") != 0 ? Model.Item.GetString("PageSize") : "10"; 17 18 IEnumerable<string> selectedDisplayGroups = Model.Item.GetList("Fields")?.GetRawValue().OfType<string>().ToList(); 19 string selectedDisplayGroupsString = selectedDisplayGroups.Count() > 0 ? (string.Join(",", selectedDisplayGroups.Select(x => x.ToString()).ToArray())) : ""; 20 21 string title = !string.IsNullOrEmpty(Model.Item.GetString("Title")) ? Model.Item.GetString("Title") : ""; 22 string hideTitle = Model.Item.GetBoolean("HideTitle").ToString(); 23 string hideImage = Model.Item.GetBoolean("HideImage").ToString(); 24 string hideProductNumber = Model.Item.GetBoolean("HideProductNumber").ToString(); 25 string hideProductName = Model.Item.GetBoolean("HideProductName").ToString(); 26 string hideStock = (Model.Item.GetBoolean("HideStock") || Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"])).ToString(); 27 string quantitySelector = Model.Item.GetBoolean("QuantitySelector").ToString(); 28 string hideProductPackagingInformation = Model.Item.GetBoolean("HideProductPackagingInformation").ToString(); 29 30 string campaignValues = string.Join(",", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 31 32 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 33 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : ""; 34 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-6"); 35 36 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 37 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 38 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 39 40 //Source type 41 string sourceType = Model.Item.GetRawValueString("SourceType", "variants"); 42 IList<string> relateFromProductIds = new List<string> { }; 43 44 //--- RELATED PRODUCTS --- 45 if (sourceType == "related-products" && product?.RelatedGroups != null) 46 { 47 foreach (var group in product.RelatedGroups) 48 { 49 foreach (var relatedProduct in group.Products) 50 { 51 if (string.IsNullOrEmpty(relatedProduct.VariantId)) 52 { 53 relateFromProductIds.Add($"{relatedProduct.ProductId}"); 54 } 55 else 56 { 57 relateFromProductIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}"); 58 } 59 } 60 } 61 } 62 63 //Create group id collection and products id collection strings 64 string groupId = product.PrimaryOrDefaultGroup.Id; 65 string productIds = sourceType == "related-products" ? string.Join(",", relateFromProductIds) : product.Id; 66 67 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 68 } 69 70 @if (!Pageview.IsVisualEditorMode) 71 { 72 <div id="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID" class="item_@Model.Item.SystemName.ToLower()"> 73 @* Initial form for first load (We pass all the settings to the actual template) *@ 74 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@Pageview.CurrentParagraph.ID" data-response-target-element="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID"> 75 <input type="hidden" name="SortOrder" value="DESC"> 76 <input type="hidden" name="ID" value="@servicePageId"> 77 <input type="hidden" name="SourceType" value="@sourceType"> 78 <input type="hidden" name="ParagraphID" value="@Pageview.CurrentParagraph.ID"> 79 <input type="hidden" name="PageSize" value="@pageSize" id="RelatedProductsListPageSize_@Pageview.CurrentParagraph.ID"> 80 <input type="hidden" name="PageSizeSetting" value="@pageSize"> 81 <input type="hidden" name="Title" value="@title"> 82 <input type="hidden" name="HideTitle" value="@hideTitle"> 83 <input type="hidden" name="SelectedDisplayGroups" value="@selectedDisplayGroupsString"> 84 <input type="hidden" name="HideImage" value="@hideImage"> 85 <input type="hidden" name="HideProductNumber" value="@hideProductNumber"> 86 <input type="hidden" name="HideProductName" value="@hideProductName"> 87 <input type="hidden" name="HideStock" value="@hideStock"> 88 <input type="hidden" name="QuantitySelector" value="@quantitySelector"> 89 <input type="hidden" name="Theme" value="@theme"> 90 <input type="hidden" name="ModalTheme" value="@modalTheme"> 91 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 92 <input type="hidden" name="ContentPadding" value="@contentPadding"> 93 <input type="hidden" name="HideProductPackagingInformation" value="@hideProductPackagingInformation"> 94 @if (isLazyLoadingForProductInfoEnabled) 95 { 96 <input type="hidden" name="getproductinfo" value="true"> 97 } 98 99 @*--- VARIANTS ---*@ 100 @if (sourceType == "variants") 101 { 102 <input type="hidden" name="MainProductID" value="@productIds"> 103 } 104 105 @*--- MOST SOLD ---*@ 106 @if (sourceType == "most-sold") 107 { 108 <input type="hidden" name="SortBy" value="OrderCount"> 109 <input type="hidden" name="GroupId" value="@groupId"> 110 <input type="hidden" name="isVariant" value="false"> 111 } 112 113 @*--- TRENDING ---*@ 114 @if (sourceType == "trending") 115 { 116 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 117 <input type="hidden" name="GroupId" value="@groupId"> 118 <input type="hidden" name="isVariant" value="false"> 119 } 120 121 @*--- LATEST ---*@ 122 @if (sourceType == "latest") 123 { 124 <input type="hidden" name="SortBy" value="Created"> 125 <input type="hidden" name="GroupId" value="@groupId"> 126 <input type="hidden" name="isVariant" value="false"> 127 } 128 129 @*--- FREQUENTLY BOUGHT ---*@ 130 @if (sourceType == "frequently") 131 { 132 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 133 <input type="hidden" name="isVariant" value="false"> 134 } 135 136 @*--- RELATED PRODUCTS ---*@ 137 @if (sourceType == "related-products") 138 { 139 <input type="hidden" name="ProductvariantId" value="@productIds"> 140 } 141 142 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 143 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 144 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 145 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 146 147 @if (campaignValues != "") 148 { 149 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 150 } 151 </form> 152 </div> 153 154 <script type="module"> 155 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_@Pageview.CurrentParagraph.ID")); 156 </script> 157 158 <script> 159 var UpdateRelatedProductsList = function (event, type, id) { 160 var targetElement = "RelatedProductsListContainer_" + id; 161 162 if (type == "UpdateFacets") { 163 targetElement = "RelatedProductsListFacets_" + id; 164 } 165 166 document.querySelector('#RelatedProductsListRequestType_' + id).value = type; 167 document.querySelector('#RelatedProductsListForm_' + id).setAttribute("data-response-target-element", targetElement); 168 169 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_" + id)); 170 }; 171 </script> 172 } 173 else 174 { 175 <div class="alert alert-info" role="alert"> 176 <span>@Translate("Product variant list")</span> 177 </div> 178 } 179
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProductsList_Custom.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_dcdb384c88394fc283f14c784ddfb8f5.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) 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.Frontend 4 5 @{ 6 ProductViewModel product = new ProductViewModel(); 7 8 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 9 { 10 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 11 } 12 13 string servicePageId = Model.Item.GetLink("ServicePage") != null ? Model.Item.GetLink("ServicePage").PageId.ToString() : ""; 14 servicePageId = servicePageId == "" && GetPageIdByNavigationTag("RelatedProductsListService") != 0 ? GetPageIdByNavigationTag("RelatedProductsListService").ToString() : servicePageId; 15 string pageSize = Model.Item.GetInt32("PageSize") != 0 ? Model.Item.GetString("PageSize") : "10"; 16 17 IEnumerable<string> selectedDisplayGroups = Model.Item.GetList("Fields")?.GetRawValue().OfType<string>().ToList(); 18 string selectedDisplayGroupsString = selectedDisplayGroups.Count() > 0 ? (string.Join(",", selectedDisplayGroups.Select(x => x.ToString()).ToArray())) : ""; 19 20 string title = !string.IsNullOrEmpty(Model.Item.GetString("Title")) ? Model.Item.GetString("Title") : ""; 21 string hideTitle = Model.Item.GetBoolean("HideTitle").ToString(); 22 string hideImage = Model.Item.GetBoolean("HideImage").ToString(); 23 string hideProductNumber = Model.Item.GetBoolean("HideProductNumber").ToString(); 24 string hideProductName = Model.Item.GetBoolean("HideProductName").ToString(); 25 string hideStock = (Model.Item.GetBoolean("HideStock") || Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"])).ToString(); 26 string quantitySelector = Model.Item.GetBoolean("QuantitySelector").ToString(); 27 string hideProductPackagingInformation = Model.Item.GetBoolean("HideProductPackagingInformation").ToString(); 28 29 string relationGroupId = !string.IsNullOrEmpty(Model.Item.GetString("RelationGroup")) ? Model.Item.GetString("RelationGroup") : ""; 30 31 string campaignValues = string.Join(",", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 32 33 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 34 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : ""; 35 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-6"); 36 37 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 38 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 39 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 40 41 //Source type 42 string sourceType = Model.Item.GetRawValueString("SourceType", "variants"); 43 IList<string> relateFromProductIds = new List<string> { }; 44 45 //--- RELATED PRODUCTS --- 46 if (sourceType == "related-products" && product?.RelatedGroups != null) { 47 foreach (var group in product.RelatedGroups) 48 { 49 if (group.Id != relationGroupId) continue; 50 foreach (var relatedProduct in group.Products) 51 { 52 if (string.IsNullOrEmpty(relatedProduct.VariantId)) 53 { 54 relateFromProductIds.Add($"{relatedProduct.ProductId}"); 55 } 56 else 57 { 58 relateFromProductIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}"); 59 } 60 } 61 } 62 } 63 64 //Create group id collection and products id collection strings 65 string groupId = product.PrimaryOrDefaultGroup.Id; 66 string productIds = sourceType == "related-products" ? string.Join(",", relateFromProductIds) : product.Id; 67 bool doNotRenderParagraph = sourceType == "related-products" && !relateFromProductIds.Any(); 68 69 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 70 } 71 72 @if (!Pageview.IsVisualEditorMode && !doNotRenderParagraph) 73 { 74 <div id="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID" class="item_@Model.Item.SystemName.ToLower()"> 75 @* Initial form for first load (We pass all the settings to the actual template) *@ 76 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@Pageview.CurrentParagraph.ID" data-response-target-element="RelatedProductsListContainer_@Pageview.CurrentParagraph.ID"> 77 <input type="hidden" name="SortOrder" value="DESC"> 78 <input type="hidden" name="ID" value="@servicePageId"> 79 <input type="hidden" name="SourceType" value="@sourceType"> 80 <input type="hidden" name="ParagraphID" value="@Pageview.CurrentParagraph.ID"> 81 <input type="hidden" name="PageSize" value="@pageSize" id="RelatedProductsListPageSize_@Pageview.CurrentParagraph.ID"> 82 <input type="hidden" name="PageSizeSetting" value="@pageSize"> 83 <input type="hidden" name="Title" value="@title"> 84 <input type="hidden" name="HideTitle" value="@hideTitle"> 85 <input type="hidden" name="SelectedDisplayGroups" value="@selectedDisplayGroupsString"> 86 <input type="hidden" name="HideImage" value="@hideImage"> 87 <input type="hidden" name="HideProductNumber" value="@hideProductNumber"> 88 <input type="hidden" name="HideProductName" value="@hideProductName"> 89 <input type="hidden" name="HideStock" value="@hideStock"> 90 <input type="hidden" name="QuantitySelector" value="@quantitySelector"> 91 <input type="hidden" name="Theme" value="@theme"> 92 <input type="hidden" name="ModalTheme" value="@modalTheme"> 93 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 94 <input type="hidden" name="ContentPadding" value="@contentPadding"> 95 <input type="hidden" name="HideProductPackagingInformation" value="@hideProductPackagingInformation"> 96 @if (isLazyLoadingForProductInfoEnabled) 97 { 98 <input type="hidden" name="getproductinfo" value="true"> 99 } 100 101 @*--- VARIANTS ---*@ 102 @if (sourceType == "variants") 103 { 104 <input type="hidden" name="MainProductID" value="@productIds"> 105 } 106 107 @*--- MOST SOLD ---*@ 108 @if (sourceType == "most-sold") 109 { 110 <input type="hidden" name="SortBy" value="OrderCount"> 111 <input type="hidden" name="GroupId" value="@groupId"> 112 <input type="hidden" name="isVariant" value="false"> 113 } 114 115 @*--- TRENDING ---*@ 116 @if (sourceType == "trending") 117 { 118 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 119 <input type="hidden" name="GroupId" value="@groupId"> 120 <input type="hidden" name="isVariant" value="false"> 121 } 122 123 @*--- LATEST ---*@ 124 @if (sourceType == "latest") 125 { 126 <input type="hidden" name="SortBy" value="Created"> 127 <input type="hidden" name="GroupId" value="@groupId"> 128 <input type="hidden" name="isVariant" value="false"> 129 } 130 131 @*--- FREQUENTLY BOUGHT ---*@ 132 @if (sourceType == "frequently") 133 { 134 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 135 <input type="hidden" name="isVariant" value="false"> 136 } 137 138 @*--- RELATED PRODUCTS ---*@ 139 @if (sourceType == "related-products") 140 { 141 <input type="hidden" name="ProductvariantId" value="@productIds"> 142 } 143 144 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 145 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 146 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 147 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 148 149 @if (campaignValues != "") 150 { 151 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 152 } 153 </form> 154 </div> 155 156 <script type="module"> 157 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_@Pageview.CurrentParagraph.ID")); 158 </script> 159 160 <script> 161 var UpdateRelatedProductsList = function(event, type, id) { 162 var targetElement = "RelatedProductsListContainer_" + id; 163 164 if (type == "UpdateFacets") { 165 targetElement = "RelatedProductsListFacets_" + id; 166 } 167 168 document.querySelector('#RelatedProductsListRequestType_' + id).value = type; 169 document.querySelector('#RelatedProductsListForm_' + id).setAttribute("data-response-target-element", targetElement); 170 171 swift.PageUpdater.Update(document.querySelector("#RelatedProductsListForm_" + id)); 172 }; 173 </script> 174 } 175 else if (!Pageview.IsVisualEditorMode && doNotRenderParagraph) 176 { 177 178 } 179 else 180 { 181 <div class="alert alert-info" role="alert"> 182 <span>@Translate("Related products list")</span> 183 </div> 184 } 185
Sorry. There is nothing to view here