Error executing template "Designs/Swift/Paragraph/Swift_ProductCatalogDetailsApp.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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 4 @{ 5 //Set default product data for use in Visual Editor 6 if (Pageview.IsVisualEditorMode) 7 { 8 ProductViewModelSettings productSetting = new ProductViewModelSettings 9 { 10 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 11 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 12 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 13 ShopId = Pageview.Area.EcomShopId 14 }; 15 16 string selectedDummyProduct = "PROD1"; 17 var list = new ProductListViewModel(); 18 if (Model.Item.GetValue("DummyProduct") != null) 19 { 20 list = Model.Item.GetValue("DummyProduct") as ProductListViewModel; 21 22 foreach (var product in list.Products) 23 { 24 selectedDummyProduct = product.Id; 25 } 26 27 ProductViewModel dummyProduct = ViewModelFactory.CreateView(productSetting, selectedDummyProduct); 28 29 if (!Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 30 { 31 Dynamicweb.Context.Current.Items.Add("ProductDetails", dummyProduct); 32 } 33 } 34 else 35 { 36 <div class="alert alert-danger" role="alert"> 37 <span>@Translate("Please select a Dummy product on this paragraph")</span> 38 </div> 39 } 40 } 41 else if (!Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 42 { 43 ProductViewModel dummyProduct = new ProductViewModel(); 44 Dynamicweb.Context.Current.Items.Add("ProductDetails", dummyProduct); 45 } 46 } 47 48 @if (Pageview.IsVisualEditorMode) 49 { 50 <div class="alert alert-info" role="alert"> 51 <span>@Translate("Product catalog App: Edit this column to configure. (Product catalog app must be attached this paragraph)")</span> 52 </div> 53 } 54 55 <div class="item_@Model.Item.SystemName.ToLower()"> 56 @Model.GetModuleOutput() 57 </div> 58
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/2Columns.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.GridRowViewModel> 2 3 @{ 4 string sectionClass = "py-3"; 5 string spaceBetweenRows = Model.Item.GetRawValueString("SpaceBetweenRows", "spacing"); 6 string spaceBetweenRowsMobile = Model.Item.GetRawValueString("SpaceBetweenRowsMobile", "auto"); 7 8 //Row spacing mobile auto 9 if (spaceBetweenRowsMobile == "auto") { 10 spaceBetweenRowsMobile = spaceBetweenRows; 11 } 12 13 //Row spacing mobile 14 switch (spaceBetweenRowsMobile) { 15 case "none": //No spacing 16 sectionClass = "py-0"; 17 break; 18 case "spacing": //Small spacing top and bottom 19 sectionClass = "py-3"; 20 break; 21 case "spacing-small-top": //Small spacing top 22 sectionClass = "pt-3"; 23 break; 24 case "spacing-small-bottom": //Small spacing bottom 25 sectionClass = "pb-3"; 26 break; 27 case "spacing-medium": //Medium spacing top and bottom 28 sectionClass = "py-4"; 29 break; 30 case "spacing-medium-top": //Medium spacing top 31 sectionClass = "pt-4"; 32 break; 33 case "spacing-medium-bottom": //Medium spacing bottom 34 sectionClass = "pb-4"; 35 break; 36 case "spacing-large": //Large spacing top and bottom 37 sectionClass = "py-5"; 38 break; 39 case "spacing-top": //Large spacing top 40 sectionClass = "pt-5"; 41 break; 42 case "spacing-bottom": //Large spacing bottom 43 sectionClass = "pb-5"; 44 break; 45 } 46 47 //Row spacing dekstop 48 switch (spaceBetweenRows) { 49 case "none": //No spacing 50 sectionClass += " py-lg-0"; 51 break; 52 case "spacing": //Small spacing top and bottom 53 sectionClass += " py-lg-3"; 54 break; 55 case "spacing-small-top": //Small spacing top 56 sectionClass += " pt-lg-3 pb-lg-0"; 57 break; 58 case "spacing-small-bottom": //Small spacing bottom 59 sectionClass += " pb-lg-3 pt-lg-0"; 60 break; 61 case "spacing-medium": //Medium spacing top and bottom 62 sectionClass += " py-lg-5"; 63 break; 64 case "spacing-medium-top": //Medium spacing top 65 sectionClass += " pt-lg-5 pb-lg-0"; 66 break; 67 case "spacing-medium-bottom": //Medium spacing bottom 68 sectionClass += " pb-lg-5 pt-lg-0"; 69 break; 70 case "spacing-large": //Large spacing top and bottom 71 sectionClass += " py-lg-6"; 72 break; 73 case "spacing-top": //Large spacing top 74 sectionClass += " pt-lg-6 pb-lg-0"; 75 break; 76 case "spacing-bottom": //Large spacing bottom 77 sectionClass += " pb-lg-6 pt-lg-0"; 78 break; 79 } 80 81 string containerClass = "container-xl"; 82 string width = Model.Item.GetRawValueString("Width", "container-xl"); 83 if (width == "none") 84 { 85 containerClass = "container-fluid px-0"; 86 } 87 if (width == "stretch") { 88 containerClass = "container-fluid"; 89 } 90 if (width == "compressed") { 91 containerClass = " container-compressed"; 92 } 93 94 string rowClass = string.Empty; 95 string spaceBetweenColumns = Model.Item.GetRawValueString("SpaceBetweenColumns", string.Empty).ToLower(); 96 string spaceBetweenColumnsMobile = Model.Item.GetRawValueString("SpaceBetweenColumnsMobile", string.Empty).ToLower(); 97 //Mobile 98 if (spaceBetweenColumnsMobile == "auto") 99 { 100 spaceBetweenColumnsMobile = spaceBetweenColumns; 101 } 102 if (spaceBetweenColumnsMobile == "stick") { 103 rowClass = " gap-0"; 104 } 105 if (spaceBetweenColumnsMobile == "spacing-medium") 106 { 107 rowClass = " gap-4"; 108 } 109 if (spaceBetweenColumnsMobile == "spacing-large") { 110 rowClass = " gap-5"; 111 } 112 //Desktop 113 if (spaceBetweenColumns == "stick") { 114 rowClass += " gap-lg-0"; 115 } 116 if (spaceBetweenColumns == "spacing-medium") 117 { 118 rowClass += " gap-lg-4"; 119 } 120 if (spaceBetweenColumns == "spacing-large") { 121 rowClass += " gap-lg-5"; 122 } 123124 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 125126 string animationOnScrollCol1 = Model.Item.GetRawValueString("AnimationOnScrollCol1", "no-animation"); 127 animationOnScrollCol1 = animationOnScrollCol1 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol1 + "'" : ""; 128 string animationOnScrollCol2 = Model.Item.GetRawValueString("AnimationOnScrollCol2", "no-animation"); 129 animationOnScrollCol2 = animationOnScrollCol2 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol2 + "'" : ""; 130131 string hideOverflow = " overflow-hidden"; 132 hideOverflow = 133 animationOnScrollCol1 != "" || 134 animationOnScrollCol2 != "" 135 ? hideOverflow : ""; 136137 Dynamicweb.Frontend.FileViewModel backgroundImage = Model.Item.GetFile("BackgroundImage"); 138 string backgroundImagePath = backgroundImage?.Path ?? string.Empty; 139 backgroundImagePath = !string.IsNullOrEmpty(backgroundImagePath) ? $"/Admin/Public/GetImage.ashx?image={backgroundImagePath}&width=2600&format=webp&compression=75&quality=90" : string.Empty; 140 backgroundImagePath = Dynamicweb.Core.Encoders.HtmlEncoder.UrlPathEncode(backgroundImagePath); 141 string backgroundRepeat = Model.Item.GetRawValueString("BackgroundImageRepeat", "no-repeat"); 142 string backgroundImageSize = Model.Item.GetRawValueString("BackgroundImageSize", "initial"); 143 int xPos = backgroundImage?.FocalPositionFromLeft ?? 50; 144 int yPos = backgroundImage?.FocalPositionFromTop ?? 50; 145 string cssPosition = $"{xPos}% {yPos}%"; 146 string gradient = Model.Item.GetRawValueString("Gradient", string.Empty); 147 string gradientOpacity = Model.Item.GetRawValueString("GradientOpacity", "0.00"); 148 string gradientString = "linear-gradient(" + gradient + "deg," + "rgba(var(--swift-foreground-color-rgb)," + gradientOpacity + "), rgba(var(--swift-background-color-rgb)," + gradientOpacity + "))"; 149 string backgroundImageString = "url(" + backgroundImagePath + ")"; 150 string backgroundImagePositionString = "background-position:" + cssPosition + ";"; 151 string backgroundRepeatString = "background-repeat:" + backgroundRepeat + ";"; 152 string backgroundImageSizeString = "background-size:" + backgroundImageSize + ";"; 153 string styleString = string.Empty; 154155 var decorations = Model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 156 var css = string.Empty; 157 var cssClasses = new List<string> { }; 158159 foreach (var itemId in decorations) 160 { 161 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 162 item.TryGetValue("Class", out object classes); 163 if (classes is null) 164 { 165 continue; 166 } 167168 var cssString = (string)classes; 169 if (cssString.StartsWith("[")) 170 { 171 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 172 cssClasses.AddRange(cssArray); 173 } 174 else 175 { 176 cssClasses.Add(cssString.Replace(",", " ")); 177 } 178 } 179 css = string.Join(" ", cssClasses).Trim(); 180181 @* Only gradient *@ 182183 if (!string.IsNullOrEmpty(gradient) && string.IsNullOrEmpty(backgroundImagePath) && gradientOpacity != ("0.00")) 184 { 185 styleString += "style=\"background-image:" + gradientString + ";\""; 186 } 187188 @* Only background image *@ 189190 else if (string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 191 { 192 styleString += "style=\"background-image:" + backgroundImageString + "; " + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 193 } 194195 @* Gradient and background image *@ 196197 else if (!string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 198 { 199 styleString += "style=\"background-image:" + gradientString + "," + backgroundImageString + ";" + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 200 } 201202 int mobileColumnSize = Dynamicweb.Core.Converter.ToInt32(Model.Item.GetRawValueString("MobileColumnBehaviour", "1")); 203 int mobileOrderFirst = Dynamicweb.Core.Converter.ToInt32(Model.Item.GetRawValueString("MobileOrderFirst", "1")); 204205 if (Pageview.IsVisualEditorMode || !string.IsNullOrWhiteSpace(Model.Column(1).Output()) || !string.IsNullOrWhiteSpace(Model.Column(2).Output())) 206 { 207 <div class="@(sectionClass)@(theme) @(css) item_@Model.Item.SystemName.ToLower()" @styleString data-swift-gridrow> 208 <div class="@containerClass@(hideOverflow)"> 209 <div class="grid grid-@(mobileColumnSize) grid-lg-@Model.Columns.Count()@(rowClass)"> 210 <div class="g-col @(Model.Column(1).ColumnNumber == mobileOrderFirst ? "order-first order-lg-0" : string.Empty)" data-col-size="6" @animationOnScrollCol1 style="--bs-columns:12"> 211 @Model.Column(1).Output() 212 </div> 213 <div class="g-col @(Model.Column(2).ColumnNumber == mobileOrderFirst ? "order-first order-lg-0" : string.Empty)" data-col-size="6" @animationOnScrollCol2 style="--bs-columns:12"> 214 @Model.Column(2).Output() 215 </div> 216 </div> 217 </div> 218 </div> 219 } 220 } 221
Error executing template "/Designs/Swift/Paragraph/Related_ProductList_Custom.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.Core.Encoders 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Frontend 6 7 @{ 8 ProductViewModel dwProduct = new ProductViewModel(); 9 10 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 11 { 12 dwProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 13 } 14 List<RelatedGroupViewModel> dwProductRelGroups = dwProduct.RelatedGroups; 15 16 if (!dwProductRelGroups.Any()) 17 { 18 return; 19 } 20 21 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 22 bool anonymousUser = Pageview.User == null; 23 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 24 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 25 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 26 27 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 28 if (!url.Contains("LayoutTemplate")) 29 { 30 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 31 } 32 33 string iconPath = "/Files/icons/"; 34 35 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 36 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 37 38 IEnumerable<string> selectedDisplayGroupsList = Model.Item.GetRawValueString("Fields").Split(',').ToList(); 39 //Collect the titles for all available fields 40 List<string> fieldsHeaders = new List<string>(); 41 Dictionary<string, List<ProductViewModel>> productLists = new Dictionary<string, List<ProductViewModel>>(); 42 List<string> selectedRelGroups = Model.Item.GetRawValueString("VisibleRelatedGroups").Split(',').ToList(); 43 44 45 foreach (RelatedGroupViewModel dwProductGroup in dwProductRelGroups) 46 { 47 if (!selectedRelGroups.Contains(dwProductGroup.Id)) 48 { 49 continue; 50 } 51 52 productLists[dwProductGroup.Name] = new List<ProductViewModel>(); 53 foreach (ProductInfoViewModel dwProductViewModelInfo in dwProductGroup.Products) 54 { 55 ProductViewModelSettings productSetting = new ProductViewModelSettings 56 { 57 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 58 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 59 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 60 ShopId = Pageview.Area.EcomShopId 61 }; 62 63 ProductViewModel productViewModel = dwProductViewModelInfo.ProductId != "" ? ViewModelFactory.CreateView(productSetting, dwProductViewModelInfo.ProductId) : new ProductViewModel(); 64 productLists[dwProductGroup.Name].Add(productViewModel); 65 } 66 } 67 68 foreach (var product in productLists.SelectMany(v => v.Value)) 69 { 70 foreach (var selection in selectedDisplayGroupsList) 71 { 72 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 73 { 74 if (selection.ToString() == group.Id) 75 { 76 foreach (var field in group.Fields) 77 { 78 if (!fieldsHeaders.Contains(field.Value.Name)) 79 { 80 bool noValues = false; 81 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) { 82 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 83 noValues = values.Count > 0 ? false : true; 84 } else if (string.IsNullOrEmpty(field.Value.Value.ToString())) { 85 noValues = true; 86 } 87 88 if (!noValues) 89 { 90 fieldsHeaders.Add(field.Value.Name); 91 } 92 } 93 } 94 } 95 } 96 } 97 } 98 99100101 int pageSizeSetting = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"]) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"].ToString()) : 10; 102 string sourceType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["SourceType"]) ? Dynamicweb.Context.Current.Request.Form["SourceType"].ToString() : "variants"; 103 string requestType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["RequestType"]) ? Dynamicweb.Context.Current.Request.Form["RequestType"].ToString() : ""; 104 string title = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Title"]) ? Dynamicweb.Context.Current.Request.Form["Title"].ToString() : ""; 105 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 106 string paragraphID = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ParagraphID"]) ? Dynamicweb.Context.Current.Request.Form["ParagraphID"].ToString() : ""; 107 string servicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ID"]) ? Dynamicweb.Context.Current.Request.Form["ID"].ToString() : ""; 108 bool hideTitle = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideTitle"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideTitle"].ToString()) : false; 109 bool hideImage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideImage"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideImage"].ToString()) : false; 110 bool hideProductNumber = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductNumber"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductNumber"].ToString()) : false; 111 bool hideProductName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductName"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductName"].ToString()) : false; 112 bool hideStock = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideStock"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideStock"].ToString()) : false; 113 bool quantitySelector = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["QuantitySelector"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["QuantitySelector"].ToString()) : false; 114 string addToCartColWidth = quantitySelector ? "160" : "60"; 115 bool hideFilters = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideFilters"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideFilters"].ToString()) : false; 116117 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 118 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 119 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 120 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 121 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 122123 var badgeParms = new Dictionary<string, object>(); 124 badgeParms.Add("saleBadgeType", saleBadgeType); 125 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 126 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 127 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 128 badgeParms.Add("newPublicationDays", newPublicationDays); 129130 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 131 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 132133 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Theme"]) ? Dynamicweb.Context.Current.Request.Form["Theme"].ToString() : ""; 134 string modalTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ModalTheme"]) ? Dynamicweb.Context.Current.Request.Form["ModalTheme"].ToString() : "theme light"; 135 string titleFontSize = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["TitleFontSize"]) ? Dynamicweb.Context.Current.Request.Form["TitleFontSize"].ToString() : ""; 136 string contentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ContentPadding"]) ? Dynamicweb.Context.Current.Request.Form["ContentPadding"].ToString() : ""; 137138 //Create group id collection and products id collection strings 139 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["GroupId"]) ? Dynamicweb.Context.Current.Request.Form["GroupId"].ToString() : ""; 140 string productIds = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 141 string contextCart = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["OrderContext"]) ? Dynamicweb.Context.Current.Request.Form["OrderContext"].ToString() : ""; 142143 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 144145 string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID"); 146 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 147 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 148 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 149150 if (Model.Item != null) 151 { 152 theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 153 contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 154 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 155 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 156 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 157 contentPadding = contentPadding == "small-x" ? "px-2 px-md-3" : contentPadding; 158 contentPadding = contentPadding == "large-x" ? "px-4 px-md-5" : contentPadding; 159 } 160 } 161162 @if (productLists.Any()) { 163164 //The form that defines what should be rendered 165 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@paragraphID" data-response-target-element="RelatedProductsListFacets_@paragraphID"> 166 <input type="hidden" name="SortOrder" value="DESC" /> 167 <input type="hidden" name="ID" value="@servicePageId" /> 168 <input type="hidden" name="SourceType" value="@sourceType" /> 169 <input type="hidden" name="ParagraphID" value="@paragraphID" /> 170 <input type="hidden" name="RequestType" value="UpdateFacets" id="RelatedProductsListRequestType_@paragraphID" /> 171 <input type="hidden" name="PageSize" value="@pageSizeSetting" id="RelatedProductsListPageSize_@paragraphID" /> 172 <input type="hidden" name="PageSizeSetting" value="@pageSizeSetting" /> 173 <input type="hidden" name="Title" value="@title" /> 174 <input type="hidden" name="HideTitle" value="@hideTitle.ToString()" /> 175 <input type="hidden" name="SelectedDisplayGroups" value="@(string.Join(",", selectedDisplayGroupsList))" /> 176 <input type="hidden" name="HideImage" value="@hideImage.ToString()" /> 177 <input type="hidden" name="HideProductNumber" value="@hideProductNumber.ToString()" /> 178 <input type="hidden" name="HideProductName" value="@hideProductName.ToString()" /> 179 <input type="hidden" name="HideStock" value="@hideStock.ToString()" /> 180 <input type="hidden" name="HideFilters" value="@hideFilters.ToString()" /> 181 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()" /> 182 <input type="hidden" name="Theme" value="@theme" /> 183 <input type="hidden" name="TitleFontSize" value="@titleFontSize" /> 184 <input type="hidden" name="ContentPadding" value="@contentPadding" /> 185186 @if (!string.IsNullOrEmpty(contextCart)) 187 { 188 <input type="hidden" name="OrderContext" value="@contextCart" /> 189 <input type="hidden" name="minicartid" value="@contextCart" /> 190 } 191192 @if (isLazyLoadingForProductInfoEnabled) 193 { 194 <input type="hidden" name="getproductinfo" value="true" /> 195 } 196197 @*--- VARIANTS ---*@ 198 @if (sourceType == "variants") 199 { 200 <input type="hidden" name="MainProductID" value="@productIds" /> 201 } 202203 @*--- MOST SOLD ---*@ 204 @if (sourceType == "most-sold") 205 { 206 <input type="hidden" name="SortBy" value="OrderCount" /> 207 <input type="hidden" name="GroupId" value="@groupId" /> 208 } 209210 @*--- TRENDING ---*@ 211 @if (sourceType == "trending") 212 { 213 <input type="hidden" name="SortBy" value="OrderCountGrowth" /> 214 <input type="hidden" name="GroupId" value="@groupId" /> 215 } 216217 @*--- LATEST ---*@ 218 @if (sourceType == "latest") 219 { 220 <input type="hidden" name="SortBy" value="Created" /> 221 <input type="hidden" name="GroupId" value="@groupId" /> 222 } 223224 @*--- FREQUENTLY BOUGHT ---*@ 225 @if (sourceType == "frequently") 226 { 227 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]" /> 228 } 229230 @*--- RELATED PRODUCTS ---*@ 231 @if (sourceType == "related-products") 232 { 233 <input type="hidden" name="MainProductID" value="@productIds" /> 234 } 235236 @if (sourceType != "variants") 237 { 238 <input type="hidden" name="isVariant" value="false" /> 239 } 240 else 241 { 242 <input type="hidden" name="isVariant" value="true" /> 243 } 244245 <input type="hidden" name="SaleBadgeType" value="@saleBadgeType" /> 246 <input type="hidden" name="SaleBadgeCssClassName" value="@saleBadgeCssClassName" /> 247 <input type="hidden" name="NewBadgeCssClassName" value="@newBadgeCssClassName" /> 248 <input type="hidden" name="NewPublicationDays" value="@newPublicationDays" /> 249250 @if (campaignBadgesValues != "") 251 { 252 <input type="hidden" name="CampaignBadgesValues" value="@campaignBadgesValues" /> 253 } 254 </form> 255256 if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID)) 257 { 258 string itemVariant = string.Empty; 259260 <script> 261 gtag("event", "view_item_list", { 262 item_list_id: "related_product_list", 263 item_list_name: "Related products list", 264 items: [ 265 @foreach (ProductViewModel product in productLists.SelectMany(v => v.Value)) 266 { 267 if (!string.IsNullOrEmpty(product.VariantName)) 268 { 269 itemVariant = $"item_variant:'{product.VariantName}',"; 270 } 271 <text>{ 272 item_id: '@product.Number', 273 item_name: '@product.Name', 274 @itemVariant 275 currency: '@product.Price.CurrencyCode', 276 price: @product.Price.Price 277 },</text> 278 } 279 ] 280 }); 281 </script> 282 } 283 //The products list table 284 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "list") 285 { 286287 <div class="table-responsive w-100"> 288289290291 @foreach (KeyValuePair<string, List<ProductViewModel>> productListDict in productLists) 292 { 293 <div class="h-100 mb-4 @(contentPadding) @theme"> 294 <h3>@productListDict.Key</h3> 295296 <table class="table table-sm table-striped align-middle text-nowrap mobile-responsive-table"> 297 <thead> 298 <tr class="fw-bold"> 299 @if (!hideImage) 300 { 301 <td scope="col">&nbsp;</td> 302 } 303 @if (!hideProductNumber) 304 { 305 <td scope="col" title="#">#</td> 306 } 307 @if (!hideProductName) 308 { 309 <td scope="col" title="@Translate("Product")">@Translate("Product")</td> 310 } 311 @foreach (var header in fieldsHeaders) 312 { 313 <td scope="col" title="@header">@header</td> 314 } 315 @if (!hideStock) 316 { 317 <td scope="col" title="@Translate("Stock")">@Translate("Stock")</td> 318 } 319 @if (!hidePrice) 320 { 321 <td scope="col" align="right" class="pe-2" title="@Translate("Price")">@Translate("Price")</td> 322 } 323 @if (!hideAddToCart) 324 { 325 <td scope="col" title="@Translate("Qty")">@Translate("Qty")</td> 326 } 327 </tr> 328 </thead> 329330 <tbody> 331 @foreach (var product in productListDict.Value) 332 { 333 string image = product.DefaultImage.Value; 334 string popoverImage = product.DefaultImage.Value; 335 image = $"/Admin/Public/GetImage.ashx?image={image}&width=30&format=webp"; 336 popoverImage = $"/Admin/Public/GetImage.ashx?image={popoverImage}&width=350&Format=WebP&Quality=70"; 337338 DateTime createdDate = product.Created.Value; 339 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 340 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 341 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 342343 List<CategoryFieldViewModel> categories = new List<CategoryFieldViewModel>(); 344 foreach (var selection in selectedDisplayGroupsList) 345 { 346 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 347 { 348 if (selection.ToString() == group.Id) 349 { 350 categories.Add(group); 351 } 352 } 353 } 354355 string salesType = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductERPSalesType") ? product.ProductFields["ProductERPSalesType"]?.ToString().ToLower() : null; 356357 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 358 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 359360 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 361 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 362 link += $"&ProductID={product.Id}"; 363 link += variantIdForLink; 364 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 365366 <tr> 367 @if (!hideImage) 368 { 369 <td width="30" scope="row" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="<img src='@popoverImage' style='max-width:100%;' />" data-bs-html="true" data-bs-trigger="hover focus"> 370 <img src="@image"/> 371 </td> 372 } 373 @if (!hideProductNumber) 374 { 375 <td scope="row" title="#"> 376 <a href="@link"> 377 @product.Number 378 </a> 379 </td> 380 } 381 @if (!hideProductName) 382 { 383 <td scope="row" title="@Translate("Product")"> 384 @if (!string.IsNullOrEmpty(product.VariantName)) 385 { 386 <div>@product.Name - @product.VariantName</div> 387 } 388 else 389 { 390 @product.Name 391 } 392393 @if (showBadges) 394 { 395 <div class="fs-7"> 396 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 397 </div> 398 } 399 </td> 400 } 401 @foreach (string fieldCell in fieldsHeaders) 402 { 403 FieldValueViewModel fieldValue = new FieldValueViewModel(); 404 bool fieldFound = false; 405 string fieldTitle = default(string); 406407 foreach (CategoryFieldViewModel category in categories) 408 { 409 foreach (var field in category.Fields) 410 { 411 bool noValues = false; 412 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 413 { 414 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 415 noValues = values.Count > 0 ? false : true; 416 } 417 else if (string.IsNullOrEmpty(field.Value.Value.ToString())) 418 { 419 noValues = true; 420 } 421422 if (!noValues) 423 { 424 string fieldName = field.Value.Name; 425 if (fieldName == fieldCell) 426 { 427 fieldValue = field.Value; 428 fieldTitle = fieldName; 429 fieldFound = true; 430 } 431 } 432 } 433 } 434435 if (fieldFound) 436 { 437 <td title="@fieldTitle">@RenderFieldValue(fieldValue)</td> 438 } 439 else 440 { 441 <td>&nbsp;</td> 442 } 443 } 444445 @if (!hideStock) 446 { 447 <td title="@Translate("Stock")"> 448 @if (product.StockLevel > 0) 449 { 450 <span class="text-success">@Translate("In stock")</span> 451 } 452 else 453 { 454 <span class="text-danger">@Translate("Out of stock")</span> 455 } 456 </td> 457 } 458 @if (!hidePrice) 459 { 460 <td align="right" class="pe-2" title="@Translate("Price")"> 461 <div itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 462 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 463464 @if (showPricesWithVat == "false" && !neverShowVat) 465 { 466 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 467 if (product.Price.Price != product.PriceBeforeDiscount.Price) 468 { 469 <span class="text-decoration-line-through opacity-75 me-3"> 470 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 471 </span> 472 } 473 } 474 else 475 { 476 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 477 if (product.Price.Price != product.PriceBeforeDiscount.Price) 478 { 479 <span class="text-decoration-line-through opacity-75 me-3"> 480 @product.PriceBeforeDiscount.PriceFormatted 481 </span> 482 } 483 } 484485 @if (showPricesWithVat == "false" && !neverShowVat) 486 { 487 <span class="text-price">@product.Price.PriceWithoutVatFormatted</span> 488 } 489 else 490 { 491 <span class="text-price">@product.Price.PriceFormatted</span> 492 } 493 </div> 494 @if (showPricesWithVat == "false" && !neverShowVat) 495 { 496 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 497 } 498 </td> 499 } 500 @if (!hideAddToCart) 501 { 502 bool isDiscontinued = product.Discontinued; 503 bool IsNeverOutOfStock = product.NeverOutOfstock; 504 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 505 disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; 506 disableAddToCart = IsNeverOutOfStock ? "" : disableAddToCart; 507508 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 509 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 510 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 511 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; 512513 <td width="@addToCartColWidth" style="min-width: @(addToCartColWidth)px" align="right" title="@Translate("Qty")"> 514 @if (salesType =="standard") { 515 <form method="post" action="@url"> 516 @if (!string.IsNullOrEmpty(contextCart)) 517 { 518 <input type="hidden" name="OrderContext" value="@contextCart"/> 519 <input type="hidden" name="minicartid" value="@contextCart"/> 520 } 521 <input type="hidden" name="redirect" value="false"/> 522 <input type="hidden" name="ProductId" value="@product.Id"/> 523 <input type="hidden" name="ProductName" value="@product.Name"/> 524 <input type="hidden" name="ProductVariantName" value="@product.VariantName"/> 525 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"/> 526 <input type="hidden" name="ProductPrice" value="@product.Price"/> 527 <input type="hidden" name="ProductReferer" value="product_list_related"> 528 <input type="hidden" name="cartcmd" value="add"/> 529530 @if (!string.IsNullOrEmpty(product.VariantId)) 531 { 532 <input type="hidden" name="VariantId" value="@product.VariantId"/> 533 } 534535 @if (quantitySelector) 536 { 537 <div class="flex-fill input-group input-primary-button-group d-flex flex-row"> 538 <label for="Quantity_@(product.Id)_@product.VariantId" class="visually-hidden">@Translate("Quantity")</label> 539 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="0" step="@stepQty" @minQty class="form-control" style="max-width: 100px" type="number" onkeydown="swift.Cart.UpdateOnEnterKey(event)"> 540 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button icon-2 @disableAddToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 541 @if (stepQty != "1") 542 { 543 <div class="invalid-feedback d-none"> 544 @Translate("Please select a quantity that is dividable by") @stepQty 545 </div> 546 } 547 </div> 548 } 549 else 550 { 551 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" type="hidden"> 552 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button @disableAddToCart icon-2" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 553 } 554 </form> 555 } 556 else 557 { 558 <p class="small my-2"><span class="fw-bold">@Translate("Bestillingsvare")</span></p> 559 } 560 </td> 561 } 562 </tr> 563 } 564 </tbody> 565 </table> 566 </div> 567 } 568569570 </div> 571 } 572573 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "slider") 574 { 575 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 576 <script type="module"> 577 swift.AssetLoader.Load('Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 578 </script> 579 <div class="h-100 grid gap-0"> 580 @foreach (var productDict in productLists) 581 { 582 Guid guid = Guid.NewGuid(); 583584585 <div class="g-col-12 mt-4 item_@(Model.Item.SystemName.ToLower())"> 586 <h3 class="mb-4">@productDict.Key</h3> 587 <div id="Slider_@guid" class="swiffy-slider slider-item-show5 slider-nav-chevron-default slider-item-reveal slider-nav-on-slides slider-indicators-dash" style="--swiffy-slider-nav-light:var(--swift-foreground-color);--swiffy-slider-nav-dark:var(--swift-background-color);"> 588 <ul class="slider-container"> 589 @foreach (var product in productDict.Value) 590 { 591 @RenderProduct(product) 592 } 593 </ul> 594 <button type="button" title="@Translate("Previous slide")" class="slider-nav" style="z-index:2;"> 595 <span class="visually-hidden">@Translate("Previous slide")</span> 596 </button> 597 <button type="button" title="@Translate("Next slide")" class="slider-nav slider-nav-next" style="z-index:2;"> 598 <span class="visually-hidden">@Translate("Next slide")</span> 599 </button> 600601 <div class="slider-indicators" style="z-index:2;"> 602 @{ 603 bool isActive = true; 604 int slideCount = 1; 605 } 606607 @foreach (var item in productDict.Value) 608 { 609 <button @(isActive ? "class=\"active\"" : string.Empty) type="button" title='@Translate("Go to slide") @slideCount'> 610 <span class="visually-hidden">@Translate("Go to slide") @slideCount</span> 611 </button> 612 { 613 slideCount++; 614 } 615 isActive = false; 616 } 617 </div> 618 </div> 619620621622 <script type="module"> 623 document.addEventListener('load.swift.assetloader', () => { 624 swiffyslider.initSlider(document.querySelector('#Slider_@guid')); 625 document.querySelector('#Slider_@guid').style.opacity = 1; 626 document.querySelector('#Slider_@guid').style.visibility = "visible"; 627 }); 628 </script> 629 </div> 630631632633 } 634 </div> 635 } 636637638 } 639640 @helper RenderProduct(ProductViewModel product) { 641 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 642 bool anonymousUser = Pageview.User == null; 643 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 644 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 645646 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 647 string ratioCssClass = ratio != "" ? "ratio" : ""; 648 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 649650 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 651 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 652 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 653 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 654 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 655 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 656657 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 658 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 659660 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 661 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 662663 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 664 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 665 link += $"&ProductID={product.Id}"; 666 link += variantIdForLink; 667 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 668669 string imagePath = product?.DefaultImage.Value.ToString() ?? ""; 670 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 671672 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 673 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 674 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 675 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 676 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 677678 var badgeParms = new Dictionary<string, object>(); 679 badgeParms.Add("saleBadgeType", saleBadgeType); 680 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 681 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 682 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 683 badgeParms.Add("newPublicationDays", newPublicationDays); 684685 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 686 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 687 DateTime createdDate = product.Created.Value; 688 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 689 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 690 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 691 <li> 692 <a href="@link" class="text-decoration-none d-block h-100"> 693 <div class="h-100 d-flex flex-column justify-content-between theme theme-gray-border"> 694 <div style="border: 1px solid transparent;"> 695 <div class="ratio position-relative" style="--bs-aspect-ratio: 75%"> 696 @if (showBadges) { 697 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 698 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 699 </div> 700 } 701 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 " style="object-fit: contain;" alt="@product.Name"> 702 </div> 703 </div> 704 <div class="flex-fill d-flex flex-column justify-content-between p-3"> 705 <h3 class="h6 opacity-85">@product.Name @product.VariantName</h3> 706707 @if (!hidePrice) { 708 <div> 709710 @if( !anonymousUser) { 711 <p class="mb-0 small">@Translate("Listepris")</p> 712 } 713 <p class="h6 m-0"> 714 @if (showPricesWithVat == "false" && !neverShowVat) 715 { 716 if (product.Price.Price != product.PriceBeforeDiscount.Price) 717 { 718 <span class="text-decoration-line-through opacity-75 me-1"> 719 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 720 </span> 721 } 722 } 723 else 724 { 725 if (product.Price.Price != product.PriceBeforeDiscount.Price) 726 { 727 <span class="text-decoration-line-through opacity-75 me-1"> 728 @product.PriceBeforeDiscount.PriceFormatted 729 </span> 730 } 731 } 732733 @if (showPricesWithVat == "false" && !neverShowVat) 734 { 735 <span class="text-price fw-bold">@product.Price.PriceWithoutVatFormatted</span> 736 } 737 else 738 { 739 <span class="text-price fw-bold">@product.Price.PriceFormatted</span> 740 } 741 </p> 742 @if (showPricesWithVat == "false" && !neverShowVat) 743 { 744 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 745 } 746 @if( !anonymousUser) { 747 <p class="mb-0 small opacity-75">@Translate("Fragt tilføjes")</p> 748 } 749 </div> 750 } 751 </div> 752 </div> 753 </a> 754 </li> 755 } 756757758 @helper RenderFieldValue(FieldValueViewModel field) { 759 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 760761 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 762 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 763764 bool isColor = false; 765766 if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 767 { 768 int valueCount = 0; 769 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 770 int totalValues = values.Count; 771772 foreach (FieldOptionValueViewModel option in values) 773 { 774 if (option.Value.Substring(0,1) == "#") { 775 isColor = true; 776 } 777778 if (!isColor) { 779 @option.Name 780 } else { 781 <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Value"></span> 782 } 783784 if (valueCount != totalValues && valueCount < (totalValues - 1)) { 785 if (isColor) { 786 <text> </text> 787 } else { 788 <text>, </text> 789 } 790 } 791 valueCount++; 792 } 793 } 794 else if (fieldValue != "") 795 { 796 if (fieldValue.Substring(0,1) == "#") { 797 isColor = true; 798 } 799800 if (!isColor) { 801 @fieldValue 802 } else { 803 <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> 804 } 805 } 806 } 807808809810 @helper RenderCheckboxOption(FacetViewModel facet, FacetOptionViewModel facetOption) 811 { 812 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 813 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 814 string selected = facetOption.Selected ? "checked" : ""; 815816 if (facetLabel.ToLower() == "true") 817 { 818 facetLabel = Translate("Yes"); 819 } 820821 if (facetLabel.ToLower() == "false") 822 { 823 facetLabel = Translate("No"); 824 } 825826 <label class="form-check mb-1" @disabled> 827 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected> 828 <span class="form-check-label d-flex align-items-center"> 829 <span class="flex-fill">@facetLabel </span> 830 <small class="opacity-85">@facetOption.Count</small> 831 </span> 832 </label> 833 } 834835 @helper RenderColorOption(FacetViewModel facet, FacetOptionViewModel facetOption) 836 { 837 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 838 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 839 string selected = facetOption.Selected ? "checked" : ""; 840841 string image = facetOption.Value; 842 string colorCode = facetOption.Value; 843844 var variantOption = Dynamicweb.Ecommerce.Services.VariantOptions.GetVariantOption(facetOption.Value.ToString(), Dynamicweb.Ecommerce.Common.Context.LanguageID); 845 if (variantOption != null) 846 { 847 image = variantOption.LargeImage; 848 colorCode = variantOption.Color; 849 } 850851 <div class="colorbox"> 852 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="@disabled @selected" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected title="@facetOption.Label"> 853 @if (colorCode.Contains("#")) 854 { 855 <span class="colorbox-background" style="background-color: @colorCode"></span> 856 } 857 else 858 { 859 <img class="colorbox-background" src="/Admin/Public/GetImage.ashx?width=25&height=25&image=@image" /> 860 } 861 </div> 862 } 863
Error executing template "/Designs/Swift/Paragraph/Related_ProductList_Custom.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.Core.Encoders 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Frontend 6 7 @{ 8 ProductViewModel dwProduct = new ProductViewModel(); 9 10 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 11 { 12 dwProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 13 } 14 List<RelatedGroupViewModel> dwProductRelGroups = dwProduct.RelatedGroups; 15 16 if (!dwProductRelGroups.Any()) 17 { 18 return; 19 } 20 21 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 22 bool anonymousUser = Pageview.User == null; 23 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 24 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 25 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 26 27 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 28 if (!url.Contains("LayoutTemplate")) 29 { 30 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 31 } 32 33 string iconPath = "/Files/icons/"; 34 35 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 36 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 37 38 IEnumerable<string> selectedDisplayGroupsList = Model.Item.GetRawValueString("Fields").Split(',').ToList(); 39 //Collect the titles for all available fields 40 List<string> fieldsHeaders = new List<string>(); 41 Dictionary<string, List<ProductViewModel>> productLists = new Dictionary<string, List<ProductViewModel>>(); 42 List<string> selectedRelGroups = Model.Item.GetRawValueString("VisibleRelatedGroups").Split(',').ToList(); 43 44 45 foreach (RelatedGroupViewModel dwProductGroup in dwProductRelGroups) 46 { 47 if (!selectedRelGroups.Contains(dwProductGroup.Id)) 48 { 49 continue; 50 } 51 52 productLists[dwProductGroup.Name] = new List<ProductViewModel>(); 53 foreach (ProductInfoViewModel dwProductViewModelInfo in dwProductGroup.Products) 54 { 55 ProductViewModelSettings productSetting = new ProductViewModelSettings 56 { 57 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 58 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 59 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 60 ShopId = Pageview.Area.EcomShopId 61 }; 62 63 ProductViewModel productViewModel = dwProductViewModelInfo.ProductId != "" ? ViewModelFactory.CreateView(productSetting, dwProductViewModelInfo.ProductId) : new ProductViewModel(); 64 productLists[dwProductGroup.Name].Add(productViewModel); 65 } 66 } 67 68 foreach (var product in productLists.SelectMany(v => v.Value)) 69 { 70 foreach (var selection in selectedDisplayGroupsList) 71 { 72 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 73 { 74 if (selection.ToString() == group.Id) 75 { 76 foreach (var field in group.Fields) 77 { 78 if (!fieldsHeaders.Contains(field.Value.Name)) 79 { 80 bool noValues = false; 81 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) { 82 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 83 noValues = values.Count > 0 ? false : true; 84 } else if (string.IsNullOrEmpty(field.Value.Value.ToString())) { 85 noValues = true; 86 } 87 88 if (!noValues) 89 { 90 fieldsHeaders.Add(field.Value.Name); 91 } 92 } 93 } 94 } 95 } 96 } 97 } 98 99100101 int pageSizeSetting = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"]) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"].ToString()) : 10; 102 string sourceType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["SourceType"]) ? Dynamicweb.Context.Current.Request.Form["SourceType"].ToString() : "variants"; 103 string requestType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["RequestType"]) ? Dynamicweb.Context.Current.Request.Form["RequestType"].ToString() : ""; 104 string title = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Title"]) ? Dynamicweb.Context.Current.Request.Form["Title"].ToString() : ""; 105 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 106 string paragraphID = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ParagraphID"]) ? Dynamicweb.Context.Current.Request.Form["ParagraphID"].ToString() : ""; 107 string servicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ID"]) ? Dynamicweb.Context.Current.Request.Form["ID"].ToString() : ""; 108 bool hideTitle = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideTitle"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideTitle"].ToString()) : false; 109 bool hideImage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideImage"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideImage"].ToString()) : false; 110 bool hideProductNumber = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductNumber"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductNumber"].ToString()) : false; 111 bool hideProductName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductName"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductName"].ToString()) : false; 112 bool hideStock = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideStock"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideStock"].ToString()) : false; 113 bool quantitySelector = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["QuantitySelector"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["QuantitySelector"].ToString()) : false; 114 string addToCartColWidth = quantitySelector ? "160" : "60"; 115 bool hideFilters = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideFilters"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideFilters"].ToString()) : false; 116117 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 118 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 119 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 120 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 121 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 122123 var badgeParms = new Dictionary<string, object>(); 124 badgeParms.Add("saleBadgeType", saleBadgeType); 125 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 126 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 127 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 128 badgeParms.Add("newPublicationDays", newPublicationDays); 129130 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 131 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 132133 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Theme"]) ? Dynamicweb.Context.Current.Request.Form["Theme"].ToString() : ""; 134 string modalTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ModalTheme"]) ? Dynamicweb.Context.Current.Request.Form["ModalTheme"].ToString() : "theme light"; 135 string titleFontSize = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["TitleFontSize"]) ? Dynamicweb.Context.Current.Request.Form["TitleFontSize"].ToString() : ""; 136 string contentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ContentPadding"]) ? Dynamicweb.Context.Current.Request.Form["ContentPadding"].ToString() : ""; 137138 //Create group id collection and products id collection strings 139 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["GroupId"]) ? Dynamicweb.Context.Current.Request.Form["GroupId"].ToString() : ""; 140 string productIds = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 141 string contextCart = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["OrderContext"]) ? Dynamicweb.Context.Current.Request.Form["OrderContext"].ToString() : ""; 142143 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 144145 string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID"); 146 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 147 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 148 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 149150 if (Model.Item != null) 151 { 152 theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 153 contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 154 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 155 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 156 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 157 contentPadding = contentPadding == "small-x" ? "px-2 px-md-3" : contentPadding; 158 contentPadding = contentPadding == "large-x" ? "px-4 px-md-5" : contentPadding; 159 } 160 } 161162 @if (productLists.Any()) { 163164 //The form that defines what should be rendered 165 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@paragraphID" data-response-target-element="RelatedProductsListFacets_@paragraphID"> 166 <input type="hidden" name="SortOrder" value="DESC" /> 167 <input type="hidden" name="ID" value="@servicePageId" /> 168 <input type="hidden" name="SourceType" value="@sourceType" /> 169 <input type="hidden" name="ParagraphID" value="@paragraphID" /> 170 <input type="hidden" name="RequestType" value="UpdateFacets" id="RelatedProductsListRequestType_@paragraphID" /> 171 <input type="hidden" name="PageSize" value="@pageSizeSetting" id="RelatedProductsListPageSize_@paragraphID" /> 172 <input type="hidden" name="PageSizeSetting" value="@pageSizeSetting" /> 173 <input type="hidden" name="Title" value="@title" /> 174 <input type="hidden" name="HideTitle" value="@hideTitle.ToString()" /> 175 <input type="hidden" name="SelectedDisplayGroups" value="@(string.Join(",", selectedDisplayGroupsList))" /> 176 <input type="hidden" name="HideImage" value="@hideImage.ToString()" /> 177 <input type="hidden" name="HideProductNumber" value="@hideProductNumber.ToString()" /> 178 <input type="hidden" name="HideProductName" value="@hideProductName.ToString()" /> 179 <input type="hidden" name="HideStock" value="@hideStock.ToString()" /> 180 <input type="hidden" name="HideFilters" value="@hideFilters.ToString()" /> 181 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()" /> 182 <input type="hidden" name="Theme" value="@theme" /> 183 <input type="hidden" name="TitleFontSize" value="@titleFontSize" /> 184 <input type="hidden" name="ContentPadding" value="@contentPadding" /> 185186 @if (!string.IsNullOrEmpty(contextCart)) 187 { 188 <input type="hidden" name="OrderContext" value="@contextCart" /> 189 <input type="hidden" name="minicartid" value="@contextCart" /> 190 } 191192 @if (isLazyLoadingForProductInfoEnabled) 193 { 194 <input type="hidden" name="getproductinfo" value="true" /> 195 } 196197 @*--- VARIANTS ---*@ 198 @if (sourceType == "variants") 199 { 200 <input type="hidden" name="MainProductID" value="@productIds" /> 201 } 202203 @*--- MOST SOLD ---*@ 204 @if (sourceType == "most-sold") 205 { 206 <input type="hidden" name="SortBy" value="OrderCount" /> 207 <input type="hidden" name="GroupId" value="@groupId" /> 208 } 209210 @*--- TRENDING ---*@ 211 @if (sourceType == "trending") 212 { 213 <input type="hidden" name="SortBy" value="OrderCountGrowth" /> 214 <input type="hidden" name="GroupId" value="@groupId" /> 215 } 216217 @*--- LATEST ---*@ 218 @if (sourceType == "latest") 219 { 220 <input type="hidden" name="SortBy" value="Created" /> 221 <input type="hidden" name="GroupId" value="@groupId" /> 222 } 223224 @*--- FREQUENTLY BOUGHT ---*@ 225 @if (sourceType == "frequently") 226 { 227 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]" /> 228 } 229230 @*--- RELATED PRODUCTS ---*@ 231 @if (sourceType == "related-products") 232 { 233 <input type="hidden" name="MainProductID" value="@productIds" /> 234 } 235236 @if (sourceType != "variants") 237 { 238 <input type="hidden" name="isVariant" value="false" /> 239 } 240 else 241 { 242 <input type="hidden" name="isVariant" value="true" /> 243 } 244245 <input type="hidden" name="SaleBadgeType" value="@saleBadgeType" /> 246 <input type="hidden" name="SaleBadgeCssClassName" value="@saleBadgeCssClassName" /> 247 <input type="hidden" name="NewBadgeCssClassName" value="@newBadgeCssClassName" /> 248 <input type="hidden" name="NewPublicationDays" value="@newPublicationDays" /> 249250 @if (campaignBadgesValues != "") 251 { 252 <input type="hidden" name="CampaignBadgesValues" value="@campaignBadgesValues" /> 253 } 254 </form> 255256 if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID)) 257 { 258 string itemVariant = string.Empty; 259260 <script> 261 gtag("event", "view_item_list", { 262 item_list_id: "related_product_list", 263 item_list_name: "Related products list", 264 items: [ 265 @foreach (ProductViewModel product in productLists.SelectMany(v => v.Value)) 266 { 267 if (!string.IsNullOrEmpty(product.VariantName)) 268 { 269 itemVariant = $"item_variant:'{product.VariantName}',"; 270 } 271 <text>{ 272 item_id: '@product.Number', 273 item_name: '@product.Name', 274 @itemVariant 275 currency: '@product.Price.CurrencyCode', 276 price: @product.Price.Price 277 },</text> 278 } 279 ] 280 }); 281 </script> 282 } 283 //The products list table 284 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "list") 285 { 286287 <div class="table-responsive w-100"> 288289290291 @foreach (KeyValuePair<string, List<ProductViewModel>> productListDict in productLists) 292 { 293 <div class="h-100 mb-4 @(contentPadding) @theme"> 294 <h3>@productListDict.Key</h3> 295296 <table class="table table-sm table-striped align-middle text-nowrap mobile-responsive-table"> 297 <thead> 298 <tr class="fw-bold"> 299 @if (!hideImage) 300 { 301 <td scope="col">&nbsp;</td> 302 } 303 @if (!hideProductNumber) 304 { 305 <td scope="col" title="#">#</td> 306 } 307 @if (!hideProductName) 308 { 309 <td scope="col" title="@Translate("Product")">@Translate("Product")</td> 310 } 311 @foreach (var header in fieldsHeaders) 312 { 313 <td scope="col" title="@header">@header</td> 314 } 315 @if (!hideStock) 316 { 317 <td scope="col" title="@Translate("Stock")">@Translate("Stock")</td> 318 } 319 @if (!hidePrice) 320 { 321 <td scope="col" align="right" class="pe-2" title="@Translate("Price")">@Translate("Price")</td> 322 } 323 @if (!hideAddToCart) 324 { 325 <td scope="col" title="@Translate("Qty")">@Translate("Qty")</td> 326 } 327 </tr> 328 </thead> 329330 <tbody> 331 @foreach (var product in productListDict.Value) 332 { 333 string image = product.DefaultImage.Value; 334 string popoverImage = product.DefaultImage.Value; 335 image = $"/Admin/Public/GetImage.ashx?image={image}&width=30&format=webp"; 336 popoverImage = $"/Admin/Public/GetImage.ashx?image={popoverImage}&width=350&Format=WebP&Quality=70"; 337338 DateTime createdDate = product.Created.Value; 339 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 340 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 341 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 342343 List<CategoryFieldViewModel> categories = new List<CategoryFieldViewModel>(); 344 foreach (var selection in selectedDisplayGroupsList) 345 { 346 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 347 { 348 if (selection.ToString() == group.Id) 349 { 350 categories.Add(group); 351 } 352 } 353 } 354355 string salesType = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductERPSalesType") ? product.ProductFields["ProductERPSalesType"]?.ToString().ToLower() : null; 356357 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 358 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 359360 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 361 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 362 link += $"&ProductID={product.Id}"; 363 link += variantIdForLink; 364 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 365366 <tr> 367 @if (!hideImage) 368 { 369 <td width="30" scope="row" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="<img src='@popoverImage' style='max-width:100%;' />" data-bs-html="true" data-bs-trigger="hover focus"> 370 <img src="@image"/> 371 </td> 372 } 373 @if (!hideProductNumber) 374 { 375 <td scope="row" title="#"> 376 <a href="@link"> 377 @product.Number 378 </a> 379 </td> 380 } 381 @if (!hideProductName) 382 { 383 <td scope="row" title="@Translate("Product")"> 384 @if (!string.IsNullOrEmpty(product.VariantName)) 385 { 386 <div>@product.Name - @product.VariantName</div> 387 } 388 else 389 { 390 @product.Name 391 } 392393 @if (showBadges) 394 { 395 <div class="fs-7"> 396 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 397 </div> 398 } 399 </td> 400 } 401 @foreach (string fieldCell in fieldsHeaders) 402 { 403 FieldValueViewModel fieldValue = new FieldValueViewModel(); 404 bool fieldFound = false; 405 string fieldTitle = default(string); 406407 foreach (CategoryFieldViewModel category in categories) 408 { 409 foreach (var field in category.Fields) 410 { 411 bool noValues = false; 412 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 413 { 414 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 415 noValues = values.Count > 0 ? false : true; 416 } 417 else if (string.IsNullOrEmpty(field.Value.Value.ToString())) 418 { 419 noValues = true; 420 } 421422 if (!noValues) 423 { 424 string fieldName = field.Value.Name; 425 if (fieldName == fieldCell) 426 { 427 fieldValue = field.Value; 428 fieldTitle = fieldName; 429 fieldFound = true; 430 } 431 } 432 } 433 } 434435 if (fieldFound) 436 { 437 <td title="@fieldTitle">@RenderFieldValue(fieldValue)</td> 438 } 439 else 440 { 441 <td>&nbsp;</td> 442 } 443 } 444445 @if (!hideStock) 446 { 447 <td title="@Translate("Stock")"> 448 @if (product.StockLevel > 0) 449 { 450 <span class="text-success">@Translate("In stock")</span> 451 } 452 else 453 { 454 <span class="text-danger">@Translate("Out of stock")</span> 455 } 456 </td> 457 } 458 @if (!hidePrice) 459 { 460 <td align="right" class="pe-2" title="@Translate("Price")"> 461 <div itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 462 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 463464 @if (showPricesWithVat == "false" && !neverShowVat) 465 { 466 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 467 if (product.Price.Price != product.PriceBeforeDiscount.Price) 468 { 469 <span class="text-decoration-line-through opacity-75 me-3"> 470 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 471 </span> 472 } 473 } 474 else 475 { 476 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 477 if (product.Price.Price != product.PriceBeforeDiscount.Price) 478 { 479 <span class="text-decoration-line-through opacity-75 me-3"> 480 @product.PriceBeforeDiscount.PriceFormatted 481 </span> 482 } 483 } 484485 @if (showPricesWithVat == "false" && !neverShowVat) 486 { 487 <span class="text-price">@product.Price.PriceWithoutVatFormatted</span> 488 } 489 else 490 { 491 <span class="text-price">@product.Price.PriceFormatted</span> 492 } 493 </div> 494 @if (showPricesWithVat == "false" && !neverShowVat) 495 { 496 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 497 } 498 </td> 499 } 500 @if (!hideAddToCart) 501 { 502 bool isDiscontinued = product.Discontinued; 503 bool IsNeverOutOfStock = product.NeverOutOfstock; 504 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 505 disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; 506 disableAddToCart = IsNeverOutOfStock ? "" : disableAddToCart; 507508 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 509 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 510 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 511 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; 512513 <td width="@addToCartColWidth" style="min-width: @(addToCartColWidth)px" align="right" title="@Translate("Qty")"> 514 @if (salesType =="standard") { 515 <form method="post" action="@url"> 516 @if (!string.IsNullOrEmpty(contextCart)) 517 { 518 <input type="hidden" name="OrderContext" value="@contextCart"/> 519 <input type="hidden" name="minicartid" value="@contextCart"/> 520 } 521 <input type="hidden" name="redirect" value="false"/> 522 <input type="hidden" name="ProductId" value="@product.Id"/> 523 <input type="hidden" name="ProductName" value="@product.Name"/> 524 <input type="hidden" name="ProductVariantName" value="@product.VariantName"/> 525 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"/> 526 <input type="hidden" name="ProductPrice" value="@product.Price"/> 527 <input type="hidden" name="ProductReferer" value="product_list_related"> 528 <input type="hidden" name="cartcmd" value="add"/> 529530 @if (!string.IsNullOrEmpty(product.VariantId)) 531 { 532 <input type="hidden" name="VariantId" value="@product.VariantId"/> 533 } 534535 @if (quantitySelector) 536 { 537 <div class="flex-fill input-group input-primary-button-group d-flex flex-row"> 538 <label for="Quantity_@(product.Id)_@product.VariantId" class="visually-hidden">@Translate("Quantity")</label> 539 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="0" step="@stepQty" @minQty class="form-control" style="max-width: 100px" type="number" onkeydown="swift.Cart.UpdateOnEnterKey(event)"> 540 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button icon-2 @disableAddToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 541 @if (stepQty != "1") 542 { 543 <div class="invalid-feedback d-none"> 544 @Translate("Please select a quantity that is dividable by") @stepQty 545 </div> 546 } 547 </div> 548 } 549 else 550 { 551 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" type="hidden"> 552 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button @disableAddToCart icon-2" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 553 } 554 </form> 555 } 556 else 557 { 558 <p class="small my-2"><span class="fw-bold">@Translate("Bestillingsvare")</span></p> 559 } 560 </td> 561 } 562 </tr> 563 } 564 </tbody> 565 </table> 566 </div> 567 } 568569570 </div> 571 } 572573 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "slider") 574 { 575 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 576 <script type="module"> 577 swift.AssetLoader.Load('Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 578 </script> 579 <div class="h-100 grid gap-0"> 580 @foreach (var productDict in productLists) 581 { 582 Guid guid = Guid.NewGuid(); 583584585 <div class="g-col-12 mt-4 item_@(Model.Item.SystemName.ToLower())"> 586 <h3 class="mb-4">@productDict.Key</h3> 587 <div id="Slider_@guid" class="swiffy-slider slider-item-show5 slider-nav-chevron-default slider-item-reveal slider-nav-on-slides slider-indicators-dash" style="--swiffy-slider-nav-light:var(--swift-foreground-color);--swiffy-slider-nav-dark:var(--swift-background-color);"> 588 <ul class="slider-container"> 589 @foreach (var product in productDict.Value) 590 { 591 @RenderProduct(product) 592 } 593 </ul> 594 <button type="button" title="@Translate("Previous slide")" class="slider-nav" style="z-index:2;"> 595 <span class="visually-hidden">@Translate("Previous slide")</span> 596 </button> 597 <button type="button" title="@Translate("Next slide")" class="slider-nav slider-nav-next" style="z-index:2;"> 598 <span class="visually-hidden">@Translate("Next slide")</span> 599 </button> 600601 <div class="slider-indicators" style="z-index:2;"> 602 @{ 603 bool isActive = true; 604 int slideCount = 1; 605 } 606607 @foreach (var item in productDict.Value) 608 { 609 <button @(isActive ? "class=\"active\"" : string.Empty) type="button" title='@Translate("Go to slide") @slideCount'> 610 <span class="visually-hidden">@Translate("Go to slide") @slideCount</span> 611 </button> 612 { 613 slideCount++; 614 } 615 isActive = false; 616 } 617 </div> 618 </div> 619620621622 <script type="module"> 623 document.addEventListener('load.swift.assetloader', () => { 624 swiffyslider.initSlider(document.querySelector('#Slider_@guid')); 625 document.querySelector('#Slider_@guid').style.opacity = 1; 626 document.querySelector('#Slider_@guid').style.visibility = "visible"; 627 }); 628 </script> 629 </div> 630631632633 } 634 </div> 635 } 636637638 } 639640 @helper RenderProduct(ProductViewModel product) { 641 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 642 bool anonymousUser = Pageview.User == null; 643 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 644 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 645646 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 647 string ratioCssClass = ratio != "" ? "ratio" : ""; 648 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 649650 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 651 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 652 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 653 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 654 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 655 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 656657 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 658 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 659660 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 661 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 662663 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 664 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 665 link += $"&ProductID={product.Id}"; 666 link += variantIdForLink; 667 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 668669 string imagePath = product?.DefaultImage.Value.ToString() ?? ""; 670 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 671672 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 673 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 674 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 675 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 676 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 677678 var badgeParms = new Dictionary<string, object>(); 679 badgeParms.Add("saleBadgeType", saleBadgeType); 680 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 681 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 682 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 683 badgeParms.Add("newPublicationDays", newPublicationDays); 684685 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 686 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 687 DateTime createdDate = product.Created.Value; 688 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 689 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 690 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 691 <li> 692 <a href="@link" class="text-decoration-none d-block h-100"> 693 <div class="h-100 d-flex flex-column justify-content-between theme theme-gray-border"> 694 <div style="border: 1px solid transparent;"> 695 <div class="ratio position-relative" style="--bs-aspect-ratio: 75%"> 696 @if (showBadges) { 697 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 698 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 699 </div> 700 } 701 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 " style="object-fit: contain;" alt="@product.Name"> 702 </div> 703 </div> 704 <div class="flex-fill d-flex flex-column justify-content-between p-3"> 705 <h3 class="h6 opacity-85">@product.Name @product.VariantName</h3> 706707 @if (!hidePrice) { 708 <div> 709710 @if( !anonymousUser) { 711 <p class="mb-0 small">@Translate("Listepris")</p> 712 } 713 <p class="h6 m-0"> 714 @if (showPricesWithVat == "false" && !neverShowVat) 715 { 716 if (product.Price.Price != product.PriceBeforeDiscount.Price) 717 { 718 <span class="text-decoration-line-through opacity-75 me-1"> 719 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 720 </span> 721 } 722 } 723 else 724 { 725 if (product.Price.Price != product.PriceBeforeDiscount.Price) 726 { 727 <span class="text-decoration-line-through opacity-75 me-1"> 728 @product.PriceBeforeDiscount.PriceFormatted 729 </span> 730 } 731 } 732733 @if (showPricesWithVat == "false" && !neverShowVat) 734 { 735 <span class="text-price fw-bold">@product.Price.PriceWithoutVatFormatted</span> 736 } 737 else 738 { 739 <span class="text-price fw-bold">@product.Price.PriceFormatted</span> 740 } 741 </p> 742 @if (showPricesWithVat == "false" && !neverShowVat) 743 { 744 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 745 } 746 @if( !anonymousUser) { 747 <p class="mb-0 small opacity-75">@Translate("Fragt tilføjes")</p> 748 } 749 </div> 750 } 751 </div> 752 </div> 753 </a> 754 </li> 755 } 756757758 @helper RenderFieldValue(FieldValueViewModel field) { 759 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 760761 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 762 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 763764 bool isColor = false; 765766 if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 767 { 768 int valueCount = 0; 769 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 770 int totalValues = values.Count; 771772 foreach (FieldOptionValueViewModel option in values) 773 { 774 if (option.Value.Substring(0,1) == "#") { 775 isColor = true; 776 } 777778 if (!isColor) { 779 @option.Name 780 } else { 781 <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Value"></span> 782 } 783784 if (valueCount != totalValues && valueCount < (totalValues - 1)) { 785 if (isColor) { 786 <text> </text> 787 } else { 788 <text>, </text> 789 } 790 } 791 valueCount++; 792 } 793 } 794 else if (fieldValue != "") 795 { 796 if (fieldValue.Substring(0,1) == "#") { 797 isColor = true; 798 } 799800 if (!isColor) { 801 @fieldValue 802 } else { 803 <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> 804 } 805 } 806 } 807808809810 @helper RenderCheckboxOption(FacetViewModel facet, FacetOptionViewModel facetOption) 811 { 812 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 813 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 814 string selected = facetOption.Selected ? "checked" : ""; 815816 if (facetLabel.ToLower() == "true") 817 { 818 facetLabel = Translate("Yes"); 819 } 820821 if (facetLabel.ToLower() == "false") 822 { 823 facetLabel = Translate("No"); 824 } 825826 <label class="form-check mb-1" @disabled> 827 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected> 828 <span class="form-check-label d-flex align-items-center"> 829 <span class="flex-fill">@facetLabel </span> 830 <small class="opacity-85">@facetOption.Count</small> 831 </span> 832 </label> 833 } 834835 @helper RenderColorOption(FacetViewModel facet, FacetOptionViewModel facetOption) 836 { 837 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 838 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 839 string selected = facetOption.Selected ? "checked" : ""; 840841 string image = facetOption.Value; 842 string colorCode = facetOption.Value; 843844 var variantOption = Dynamicweb.Ecommerce.Services.VariantOptions.GetVariantOption(facetOption.Value.ToString(), Dynamicweb.Ecommerce.Common.Context.LanguageID); 845 if (variantOption != null) 846 { 847 image = variantOption.LargeImage; 848 colorCode = variantOption.Color; 849 } 850851 <div class="colorbox"> 852 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="@disabled @selected" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected title="@facetOption.Label"> 853 @if (colorCode.Contains("#")) 854 { 855 <span class="colorbox-background" style="background-color: @colorCode"></span> 856 } 857 else 858 { 859 <img class="colorbox-background" src="/Admin/Public/GetImage.ashx?width=25&height=25&image=@image" /> 860 } 861 </div> 862 } 863
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/3Columns.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.GridRowViewModel> 2 @using Dynamicweb.Content.Items 3 4 @{ 5 string sectionClass = "py-3"; 6 string spaceBetweenRows = Model.Item.GetRawValueString("SpaceBetweenRows", "spacing"); 7 string spaceBetweenRowsMobile = Model.Item.GetRawValueString("SpaceBetweenRowsMobile", "auto"); 8 9 //Row spacing mobile auto 10 if (spaceBetweenRowsMobile == "auto") { 11 spaceBetweenRowsMobile = spaceBetweenRows; 12 } 13 14 //Row spacing mobile 15 switch (spaceBetweenRowsMobile) { 16 case "none": //No spacing 17 sectionClass = "py-0"; 18 break; 19 case "spacing": //Small spacing top and bottom 20 sectionClass = "py-3"; 21 break; 22 case "spacing-small-top": //Small spacing top 23 sectionClass = "pt-3"; 24 break; 25 case "spacing-small-bottom": //Small spacing bottom 26 sectionClass = "pb-3"; 27 break; 28 case "spacing-medium": //Medium spacing top and bottom 29 sectionClass = "py-4"; 30 break; 31 case "spacing-medium-top": //Medium spacing top 32 sectionClass = "pt-4"; 33 break; 34 case "spacing-medium-bottom": //Medium spacing bottom 35 sectionClass = "pb-4"; 36 break; 37 case "spacing-large": //Large spacing top and bottom 38 sectionClass = "py-5"; 39 break; 40 case "spacing-top": //Large spacing top 41 sectionClass = "pt-5"; 42 break; 43 case "spacing-bottom": //Large spacing bottom 44 sectionClass = "pb-5"; 45 break; 46 } 47 48 //Row spacing dekstop 49 switch (spaceBetweenRows) { 50 case "none": //No spacing 51 sectionClass += " py-lg-0"; 52 break; 53 case "spacing": //Small spacing top and bottom 54 sectionClass += " py-lg-3"; 55 break; 56 case "spacing-small-top": //Small spacing top 57 sectionClass += " pt-lg-3 pb-lg-0"; 58 break; 59 case "spacing-small-bottom": //Small spacing bottom 60 sectionClass += " pb-lg-3 pt-lg-0"; 61 break; 62 case "spacing-medium": //Medium spacing top and bottom 63 sectionClass += " py-lg-5"; 64 break; 65 case "spacing-medium-top": //Medium spacing top 66 sectionClass += " pt-lg-5 pb-lg-0"; 67 break; 68 case "spacing-medium-bottom": //Medium spacing bottom 69 sectionClass += " pb-lg-5 pt-lg-0"; 70 break; 71 case "spacing-large": //Large spacing top and bottom 72 sectionClass += " py-lg-6"; 73 break; 74 case "spacing-top": //Large spacing top 75 sectionClass += " pt-lg-6 pb-lg-0"; 76 break; 77 case "spacing-bottom": //Large spacing bottom 78 sectionClass += " pb-lg-6 pt-lg-0"; 79 break; 80 } 81 82 string width = Model.Item.GetRawValueString("Width", "").ToLower(); 83 string containerClass = "container-xl"; 84 if (width == "stretch") 85 { 86 containerClass = "container-fluid"; 87 } 88 if (width == "none") 89 { 90 containerClass = "container-fluid px-0"; 91 } 92 if (width == "compressed") 93 { 94 containerClass = " container-compressed"; 95 } 96 97 string rowClass = string.Empty; 98 string spaceBetweenColumns = Model.Item.GetRawValueString("SpaceBetweenColumns", string.Empty).ToLower(); 99 string spaceBetweenColumnsMobile = Model.Item.GetRawValueString("SpaceBetweenColumnsMobile", string.Empty).ToLower(); 100 //Mobile 101 if (spaceBetweenColumnsMobile == "auto") 102 { 103 spaceBetweenColumnsMobile = spaceBetweenColumns; 104 } 105 if (spaceBetweenColumnsMobile == "stick") { 106 rowClass = " gap-0"; 107 } 108 if (spaceBetweenColumnsMobile == "spacing-medium") 109 { 110 rowClass = " gap-4"; 111 } 112 if (spaceBetweenColumnsMobile == "spacing-large") { 113 rowClass = " gap-5"; 114 } 115 //Desktop 116 if (spaceBetweenColumns == "stick") { 117 rowClass += " gap-lg-0"; 118 } 119 if (spaceBetweenColumns == "spacing-medium") 120 { 121 rowClass += " gap-lg-4"; 122 } 123 if (spaceBetweenColumns == "spacing-large") { 124 rowClass += " gap-lg-5"; 125 } 126127 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 128129 string animationOnScrollCol1 = Model.Item.GetRawValueString("AnimationOnScrollCol1", "no-animation"); 130 animationOnScrollCol1 = animationOnScrollCol1 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol1 + "'" : ""; 131 string animationOnScrollCol2 = Model.Item.GetRawValueString("AnimationOnScrollCol2", "no-animation"); 132 animationOnScrollCol2 = animationOnScrollCol2 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol2 + "'" : ""; 133 string animationOnScrollCol3 = Model.Item.GetRawValueString("AnimationOnScrollCol3", "no-animation"); 134 animationOnScrollCol3 = animationOnScrollCol3 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol3 + "'" : ""; 135136 string hideOverflow = " overflow-hidden"; 137 hideOverflow = 138 animationOnScrollCol1 != "" || 139 animationOnScrollCol2 != "" || 140 animationOnScrollCol3 != "" 141 ? hideOverflow : ""; 142143 Dynamicweb.Frontend.FileViewModel backgroundImage = Model.Item.GetFile("BackgroundImage"); 144 string backgroundImagePath = backgroundImage?.Path ?? string.Empty; 145 backgroundImagePath = !string.IsNullOrEmpty(backgroundImagePath) ? $"/Admin/Public/GetImage.ashx?image={backgroundImagePath}&width=2600&format=webp&compression=75&quality=90" : string.Empty; 146 backgroundImagePath = Dynamicweb.Core.Encoders.HtmlEncoder.UrlPathEncode(backgroundImagePath); 147 string backgroundRepeat = Model.Item.GetRawValueString("BackgroundImageRepeat", "no-repeat"); 148 string backgroundImageSize = Model.Item.GetRawValueString("BackgroundImageSize", "initial"); 149 int xPos = backgroundImage?.FocalPositionFromLeft ?? 50; 150 int yPos = backgroundImage?.FocalPositionFromTop ?? 50; 151 string cssPosition = $"{xPos}% {yPos}%"; 152 string gradient = Model.Item.GetRawValueString("Gradient", string.Empty); 153 string gradientOpacity = Model.Item.GetRawValueString("GradientOpacity", "0.00"); 154 string gradientString = "linear-gradient(" + gradient + "deg," + "rgba(var(--swift-foreground-color-rgb)," + gradientOpacity + "), rgba(var(--swift-background-color-rgb)," + gradientOpacity + "))"; 155 string backgroundImageString = "url(" + backgroundImagePath + ")"; 156 string backgroundImagePositionString = "background-position:" + cssPosition + ";"; 157 string backgroundRepeatString = "background-repeat:" + backgroundRepeat + ";"; 158 string backgroundImageSizeString = "background-size:" + backgroundImageSize + ";"; 159 string styleString = string.Empty; 160161 var decorations = Model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 162 var css = string.Empty; 163 var cssClasses = new List<string> { }; 164165 foreach (var itemId in decorations) 166 { 167 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 168 item.TryGetValue("Class", out object classes); 169 if (classes is null) 170 { 171 continue; 172 } 173174 var cssString = (string)classes; 175 if (cssString.StartsWith("[")) 176 { 177 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 178 cssClasses.AddRange(cssArray); 179 } 180 else 181 { 182 cssClasses.Add(cssString.Replace(",", " ")); 183 } 184 } 185 css = string.Join(" ", cssClasses).Trim(); 186187 @* Only gradient *@ 188189 if (!string.IsNullOrEmpty(gradient) && string.IsNullOrEmpty(backgroundImagePath) && gradientOpacity != ("0.00")) 190 { 191 styleString += "style=\"background-image:" + gradientString + ";\""; 192 } 193194 @* Only background image *@ 195196 else if (string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 197 { 198 styleString += "style=\"background-image:" + backgroundImageString + "; " + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 199 } 200201 @* Gradient and background image *@ 202203 else if (!string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 204 { 205 styleString += "style=\"background-image:" + gradientString + "," + backgroundImageString + ";" + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 206 } 207208 int mobileColumnSize = Dynamicweb.Core.Converter.ToInt32(Model.Item.GetRawValueString("MobileColumnBehaviour", "1")); 209 int mobileOrderFirst = Dynamicweb.Core.Converter.ToInt32(Model.Item.GetRawValueString("MobileOrderFirst", "1")); 210211 if (Pageview.IsVisualEditorMode || !string.IsNullOrWhiteSpace(Model.Column(1).Output()) || !string.IsNullOrWhiteSpace(Model.Column(2).Output()) || !string.IsNullOrWhiteSpace(Model.Column(3).Output())) 212 { 213 <div class="@(sectionClass)@(theme) @(css) item_@Model.Item.SystemName.ToLower()" @styleString data-swift-gridrow> 214 <div class="@containerClass@(hideOverflow)"> 215 <div class="grid grid-@(mobileColumnSize) grid-lg-@Model.Columns.Count()@(rowClass)"> 216 <div class="g-col @(Model.Column(1).ColumnNumber == mobileOrderFirst ? "order-first order-lg-0" : string.Empty)" data-col-size="4" @animationOnScrollCol1 style="--bs-columns:12"> 217 @Model.Column(1).Output() 218 </div> 219 <div class="g-col @(Model.Column(2).ColumnNumber == mobileOrderFirst ? "order-first order-lg-0" : string.Empty)" data-col-size="4" @animationOnScrollCol2 style="--bs-columns:12"> 220 @Model.Column(2).Output() 221 </div> 222 <div class="g-col @(Model.Column(3).ColumnNumber == mobileOrderFirst ? "order-first order-lg-0" : string.Empty)" data-col-size="4" @animationOnScrollCol3 style="--bs-columns:12"> 223 @Model.Column(3).Output() 224 </div> 225 </div> 226 </div> 227 </div> 228 } 229 } 230
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/ProductDetailsAccordion.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.GridRowViewModel> 2 @functions { 3 public bool IsUnstyledMode() 4 { 5 return Dynamicweb.Context.Current.Items.Contains("ProductDetailsAccordionUnstyled") && 6 Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["ProductDetailsAccordionUnstyled"]); 7 } 8 9 public int GetCurrentUnstyledColumnIndex() 10 { 11 if (!Dynamicweb.Context.Current.Items.Contains("ProductDetailsAccordionUnstyledColumnIndex")) 12 { 13 return 0; 14 } 15 16 return Dynamicweb.Core.Converter.ToInt32(Dynamicweb.Context.Current.Items["ProductDetailsAccordionUnstyledColumnIndex"]); 17 } 18 19 public string GetTitleKeyForColumn(int columnIndex) 20 { 21 return $"ProductDetailsAccordionUnstyledTitle_{columnIndex}"; 22 } 23 24 public void BeginUnstyledColumnScope(int columnIndex) 25 { 26 string titleKey = GetTitleKeyForColumn(columnIndex); 27 Dynamicweb.Context.Current.Items["ProductDetailsAccordionUnstyled"] = true; 28 Dynamicweb.Context.Current.Items["ProductDetailsAccordionUnstyledColumnIndex"] = columnIndex; 29 Dynamicweb.Context.Current.Items.Remove(titleKey); 30 } 31 32 public void EndUnstyledColumnScope(int columnIndex) 33 { 34 string titleKey = GetTitleKeyForColumn(columnIndex); 35 Dynamicweb.Context.Current.Items.Remove("ProductDetailsAccordionUnstyled"); 36 Dynamicweb.Context.Current.Items.Remove("ProductDetailsAccordionUnstyledColumnIndex"); 37 Dynamicweb.Context.Current.Items.Remove(titleKey); 38 } 39 40 public void SetTitleForCurrentColumn(string title) 41 { 42 if (!IsUnstyledMode() || string.IsNullOrWhiteSpace(title)) 43 { 44 return; 45 } 46 47 int columnIndex = GetCurrentUnstyledColumnIndex(); 48 if (columnIndex <= 0) 49 { 50 return; 51 } 52 53 string titleKey = GetTitleKeyForColumn(columnIndex); 54 if (!Dynamicweb.Context.Current.Items.Contains(titleKey) || string.IsNullOrWhiteSpace(Dynamicweb.Core.Converter.ToString(Dynamicweb.Context.Current.Items[titleKey]))) 55 { 56 Dynamicweb.Context.Current.Items[titleKey] = title; 57 } 58 } 59 60 public string GetTitleForColumn(int columnIndex) 61 { 62 string titleKey = GetTitleKeyForColumn(columnIndex); 63 return Dynamicweb.Context.Current.Items.Contains(titleKey) 64 ? Dynamicweb.Core.Converter.ToString(Dynamicweb.Context.Current.Items[titleKey]) 65 : string.Empty; 66 } 67 } 68 69 70 @{ 71 string sectionClass = "py-3"; 72 string spaceBetweenRows = Model.Item.GetRawValueString("SpaceBetweenRows", "spacing"); 73 string spaceBetweenRowsMobile = Model.Item.GetRawValueString("SpaceBetweenRowsMobile", "auto"); 74 75 //Row spacing mobile auto 76 if (spaceBetweenRowsMobile == "auto") { 77 spaceBetweenRowsMobile = spaceBetweenRows; 78 } 79 80 //Row spacing mobile 81 switch (spaceBetweenRowsMobile) { 82 case "none": //No spacing 83 sectionClass = "py-0"; 84 break; 85 case "spacing": //Small spacing top and bottom 86 sectionClass = "py-3"; 87 break; 88 case "spacing-small-top": //Small spacing top 89 sectionClass = "pt-3"; 90 break; 91 case "spacing-small-bottom": //Small spacing bottom 92 sectionClass = "pb-3"; 93 break; 94 case "spacing-medium": //Medium spacing top and bottom 95 sectionClass = "py-4"; 96 break; 97 case "spacing-medium-top": //Medium spacing top 98 sectionClass = "pt-4"; 99 break; 100 case "spacing-medium-bottom": //Medium spacing bottom 101 sectionClass = "pb-4"; 102 break; 103 case "spacing-large": //Large spacing top and bottom 104 sectionClass = "py-5"; 105 break; 106 case "spacing-top": //Large spacing top 107 sectionClass = "pt-5"; 108 break; 109 case "spacing-bottom": //Large spacing bottom 110 sectionClass = "pb-5"; 111 break; 112 } 113114 //Row spacing dekstop 115 switch (spaceBetweenRows) { 116 case "none": //No spacing 117 sectionClass += " py-lg-0"; 118 break; 119 case "spacing": //Small spacing top and bottom 120 sectionClass += " py-lg-3"; 121 break; 122 case "spacing-small-top": //Small spacing top 123 sectionClass += " pt-lg-3 pb-lg-0"; 124 break; 125 case "spacing-small-bottom": //Small spacing bottom 126 sectionClass += " pb-lg-3 pt-lg-0"; 127 break; 128 case "spacing-medium": //Medium spacing top and bottom 129 sectionClass += " py-lg-5"; 130 break; 131 case "spacing-medium-top": //Medium spacing top 132 sectionClass += " pt-lg-5 pb-lg-0"; 133 break; 134 case "spacing-medium-bottom": //Medium spacing bottom 135 sectionClass += " pb-lg-5 pt-lg-0"; 136 break; 137 case "spacing-large": //Large spacing top and bottom 138 sectionClass += " py-lg-6"; 139 break; 140 case "spacing-top": //Large spacing top 141 sectionClass += " pt-lg-6 pb-lg-0"; 142 break; 143 case "spacing-bottom": //Large spacing bottom 144 sectionClass += " pb-lg-6 pt-lg-0"; 145 break; 146 } 147148 string width = Model.Item.GetRawValueString("Width"); 149 string containerClass = "container-xl"; 150 if (width == "stretch") 151 { 152 containerClass = "container-fluid"; 153 } 154 if (width == "none") 155 { 156 containerClass = "container-fluid px-0"; 157 } 158 if (width == "compressed") 159 { 160 containerClass = " container-compressed"; 161 } 162163 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 164165 string animationOnScrollCol1 = Model.Item.GetRawValueString("AnimationOnScrollCol1", Model.Item.GetRawValueString("AnimationOnScroll", "no-animation")); 166 animationOnScrollCol1 = animationOnScrollCol1 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol1 + "'" : ""; 167 string animationOnScrollCol2 = Model.Item.GetRawValueString("AnimationOnScrollCol2", "no-animation"); 168 animationOnScrollCol2 = animationOnScrollCol2 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol2 + "'" : ""; 169 string animationOnScrollCol3 = Model.Item.GetRawValueString("AnimationOnScrollCol3", "no-animation"); 170 animationOnScrollCol3 = animationOnScrollCol3 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol3 + "'" : ""; 171 string animationOnScrollCol4 = Model.Item.GetRawValueString("AnimationOnScrollCol4", "no-animation"); 172 animationOnScrollCol4 = animationOnScrollCol4 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol4 + "'" : ""; 173 string animationOnScrollCol5 = Model.Item.GetRawValueString("AnimationOnScrollCol5", "no-animation"); 174 animationOnScrollCol5 = animationOnScrollCol5 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol5 + "'" : ""; 175 string animationOnScrollCol6 = Model.Item.GetRawValueString("AnimationOnScrollCol6", "no-animation"); 176 animationOnScrollCol6 = animationOnScrollCol6 != "no-animation" ? "data-aos=" + "'" + animationOnScrollCol6 + "'" : ""; 177178 string hideOverflow = " overflow-hidden"; 179 hideOverflow = 180 animationOnScrollCol1 != "" || 181 animationOnScrollCol2 != "" || 182 animationOnScrollCol3 != "" || 183 animationOnScrollCol4 != "" || 184 animationOnScrollCol5 != "" || 185 animationOnScrollCol6 != "" 186 ? hideOverflow : ""; 187188 Dynamicweb.Frontend.FileViewModel backgroundImage = Model.Item.GetFile("BackgroundImage"); 189 string backgroundImagePath = backgroundImage?.Path ?? string.Empty; 190 backgroundImagePath = !string.IsNullOrEmpty(backgroundImagePath) ? $"/Admin/Public/GetImage.ashx?image={backgroundImagePath}&width=2600&format=webp&compression=75&quality=90" : string.Empty; 191 backgroundImagePath = Dynamicweb.Core.Encoders.HtmlEncoder.UrlPathEncode(backgroundImagePath); 192 string backgroundRepeat = Model.Item.GetRawValueString("BackgroundImageRepeat", "no-repeat"); 193 string backgroundImageSize = Model.Item.GetRawValueString("BackgroundImageSize", "initial"); 194 int xPos = backgroundImage?.FocalPositionFromLeft ?? 50; 195 int yPos = backgroundImage?.FocalPositionFromTop ?? 50; 196 string cssPosition = $"{xPos}% {yPos}%"; 197 string gradient = Model.Item.GetRawValueString("Gradient", string.Empty); 198 string gradientOpacity = Model.Item.GetRawValueString("GradientOpacity", "0.00"); 199 string gradientString = "linear-gradient(" + gradient + "deg," + "rgba(var(--swift-foreground-color-rgb)," + gradientOpacity + "), rgba(var(--swift-background-color-rgb)," + gradientOpacity + "))"; 200 string backgroundImageString = "url(" + backgroundImagePath + ")"; 201 string backgroundImagePositionString = "background-position:" + cssPosition + ";"; 202 string backgroundRepeatString = "background-repeat:" + backgroundRepeat + ";"; 203 string backgroundImageSizeString = "background-size:" + backgroundImageSize + ";"; 204 string styleString = string.Empty; 205206 var decorations = Model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 207 var css = string.Empty; 208 var cssClasses = new List<string> { }; 209210 foreach (var itemId in decorations) 211 { 212 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 213 item.TryGetValue("Class", out object classes); 214 if (classes is null) 215 { 216 continue; 217 } 218219 var cssString = (string)classes; 220 if (cssString.StartsWith("[")) 221 { 222 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 223 cssClasses.AddRange(cssArray); 224 } 225 else 226 { 227 cssClasses.Add(cssString.Replace(",", " ")); 228 } 229 } 230 css = string.Join(" ", cssClasses).Trim(); 231232 @* Only gradient *@ 233234 if (!string.IsNullOrEmpty(gradient) && string.IsNullOrEmpty(backgroundImagePath) && gradientOpacity != ("0.00")) 235 { 236 styleString += "style=\"background-image:" + gradientString + ";\""; 237 } 238239 @* Only background image *@ 240241 else if (string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 242 { 243 styleString += "style=\"background-image:" + backgroundImageString + "; " + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 244 } 245246 @* Gradient and background image *@ 247248 else if (!string.IsNullOrEmpty(gradient) && !string.IsNullOrEmpty(backgroundImagePath)) 249 { 250 styleString += "style=\"background-image:" + gradientString + "," + backgroundImageString + ";" + backgroundImagePositionString + backgroundRepeatString + backgroundImageSizeString + "\""; 251 } 252253 Func<int, Tuple<object, string>> getUnstyledColumnOutput = columnIndex => 254 { 255 BeginUnstyledColumnScope(columnIndex); 256 try 257 { 258 var output = Model.Column(columnIndex).Output(); 259 string title = GetTitleForColumn(columnIndex); 260 return Tuple.Create((object)output, title); 261 } 262 finally 263 { 264 EndUnstyledColumnScope(columnIndex); 265 } 266 }; 267268 Func<object, bool> hasMeaningfulContent = output => 269 { 270 string outputHtml = Dynamicweb.Core.Converter.ToString(output); 271 if (string.IsNullOrWhiteSpace(outputHtml)) 272 { 273 return false; 274 } 275276 string withoutComments = System.Text.RegularExpressions.Regex.Replace(outputHtml, "<!--.*?-->", string.Empty, System.Text.RegularExpressions.RegexOptions.Singleline); 277 bool containsMedia = System.Text.RegularExpressions.Regex.IsMatch(withoutComments, "<(img|video|iframe|svg|object|embed|canvas)\\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase); 278 if (containsMedia) 279 { 280 return true; 281 } 282283 string withoutTags = System.Text.RegularExpressions.Regex.Replace(withoutComments, "<[^>]+>", " "); 284 string decodedText = System.Net.WebUtility.HtmlDecode(withoutTags ?? string.Empty); 285 string normalizedText = System.Text.RegularExpressions.Regex.Replace(decodedText, "\\s+", " ").Trim(); 286 return !string.IsNullOrWhiteSpace(normalizedText); 287 }; 288289 var column1 = getUnstyledColumnOutput(1); 290 var column2 = getUnstyledColumnOutput(2); 291 var column3 = getUnstyledColumnOutput(3); 292 var column4 = getUnstyledColumnOutput(4); 293 var column5 = getUnstyledColumnOutput(5); 294 var column6 = getUnstyledColumnOutput(6); 295296 var columns = new[] 297 { 298 new { Index = 1, Output = column1.Item1, Title = column1.Item2, HasContent = hasMeaningfulContent(column1.Item1), AnimationOnScroll = animationOnScrollCol1 }, 299 new { Index = 2, Output = column2.Item1, Title = column2.Item2, HasContent = hasMeaningfulContent(column2.Item1), AnimationOnScroll = animationOnScrollCol2 }, 300 new { Index = 3, Output = column3.Item1, Title = column3.Item2, HasContent = hasMeaningfulContent(column3.Item1), AnimationOnScroll = animationOnScrollCol3 }, 301 new { Index = 4, Output = column4.Item1, Title = column4.Item2, HasContent = hasMeaningfulContent(column4.Item1), AnimationOnScroll = animationOnScrollCol4 }, 302 new { Index = 5, Output = column5.Item1, Title = column5.Item2, HasContent = hasMeaningfulContent(column5.Item1), AnimationOnScroll = animationOnScrollCol5 }, 303 new { Index = 6, Output = column6.Item1, Title = column6.Item2, HasContent = hasMeaningfulContent(column6.Item1), AnimationOnScroll = animationOnScrollCol6 } 304 }; 305 var hasAnyColumnContent = columns.Any(column => column.HasContent); 306 var accordionId = $"product-details-accordion-{Guid.NewGuid():N}"; 307308 if (Pageview.IsVisualEditorMode || hasAnyColumnContent) 309 { 310 <div class="@(sectionClass)@(theme) @(css) item_@Model.Item.SystemName.ToLower()" @styleString data-swift-gridrow> 311 <div class="@containerClass@(hideOverflow)"> 312 <div class="accordion" id="@accordionId"> 313 @foreach (var column in columns) 314 { 315 var hasColumnContent = column.HasContent; 316 if (Pageview.IsVisualEditorMode || hasColumnContent) 317 { 318 var isExpanded = Pageview.IsVisualEditorMode; 319 var headingId = $"{accordionId}-heading-{column.Index}"; 320 var collapseId = $"{accordionId}-collapse-{column.Index}"; 321 string manualTitle = Model.Item.GetString($"AccordionTitleCol{column.Index}"); 322 var accordionTitle = !string.IsNullOrWhiteSpace(manualTitle) ? manualTitle 323 : !string.IsNullOrWhiteSpace(column.Title) ? column.Title 324 : $"Section {column.Index}"; 325 <div class="accordion-item"> 326 <h3 class="accordion-header" id="@headingId"> 327 <button class="accordion-button@(isExpanded ? "" : " collapsed")" type="button" data-bs-toggle="collapse" data-bs-target="#@collapseId" aria-expanded="@(isExpanded ? "true" : "false")" aria-controls="@collapseId"> 328 <span class="py-2 fs-5">@accordionTitle</span> 329 </button> 330 </h3> 331 <div id="@collapseId" class="accordion-collapse collapse@(isExpanded ? " show" : "")" aria-labelledby="@headingId"> 332 <div class="accordion-body"> 333 <div class="g-col" data-col-size="12" @column.AnimationOnScroll style="--bs-columns:12"> 334 @column.Output 335 </div> 336 </div> 337 </div> 338 </div> 339 } 340 } 341 </div> 342 </div> 343 </div> 344 } 345 } 346
Error executing template "/Designs/Swift/Paragraph/Related_ProductList_Custom.cshtml"
System.IO.IOException: There is not enough space on the disk.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context)
at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType)
at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType)
at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss)
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.Core.Encoders 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Frontend 6 7 @{ 8 ProductViewModel dwProduct = new ProductViewModel(); 9 10 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 11 { 12 dwProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 13 } 14 List<RelatedGroupViewModel> dwProductRelGroups = dwProduct.RelatedGroups; 15 16 if (!dwProductRelGroups.Any()) 17 { 18 return; 19 } 20 21 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 22 bool anonymousUser = Pageview.User == null; 23 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 24 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 25 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 26 27 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 28 if (!url.Contains("LayoutTemplate")) 29 { 30 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 31 } 32 33 string iconPath = "/Files/icons/"; 34 35 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 36 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 37 38 IEnumerable<string> selectedDisplayGroupsList = Model.Item.GetRawValueString("Fields").Split(',').ToList(); 39 //Collect the titles for all available fields 40 List<string> fieldsHeaders = new List<string>(); 41 Dictionary<string, List<ProductViewModel>> productLists = new Dictionary<string, List<ProductViewModel>>(); 42 List<string> selectedRelGroups = Model.Item.GetRawValueString("VisibleRelatedGroups").Split(',').ToList(); 43 44 45 foreach (RelatedGroupViewModel dwProductGroup in dwProductRelGroups) 46 { 47 if (!selectedRelGroups.Contains(dwProductGroup.Id)) 48 { 49 continue; 50 } 51 52 productLists[dwProductGroup.Name] = new List<ProductViewModel>(); 53 foreach (ProductInfoViewModel dwProductViewModelInfo in dwProductGroup.Products) 54 { 55 ProductViewModelSettings productSetting = new ProductViewModelSettings 56 { 57 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 58 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 59 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 60 ShopId = Pageview.Area.EcomShopId 61 }; 62 63 ProductViewModel productViewModel = dwProductViewModelInfo.ProductId != "" ? ViewModelFactory.CreateView(productSetting, dwProductViewModelInfo.ProductId) : new ProductViewModel(); 64 productLists[dwProductGroup.Name].Add(productViewModel); 65 } 66 } 67 68 foreach (var product in productLists.SelectMany(v => v.Value)) 69 { 70 foreach (var selection in selectedDisplayGroupsList) 71 { 72 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 73 { 74 if (selection.ToString() == group.Id) 75 { 76 foreach (var field in group.Fields) 77 { 78 if (!fieldsHeaders.Contains(field.Value.Name)) 79 { 80 bool noValues = false; 81 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) { 82 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 83 noValues = values.Count > 0 ? false : true; 84 } else if (string.IsNullOrEmpty(field.Value.Value.ToString())) { 85 noValues = true; 86 } 87 88 if (!noValues) 89 { 90 fieldsHeaders.Add(field.Value.Name); 91 } 92 } 93 } 94 } 95 } 96 } 97 } 98 99100101 int pageSizeSetting = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"]) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form["PageSizeSetting"].ToString()) : 10; 102 string sourceType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["SourceType"]) ? Dynamicweb.Context.Current.Request.Form["SourceType"].ToString() : "variants"; 103 string requestType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["RequestType"]) ? Dynamicweb.Context.Current.Request.Form["RequestType"].ToString() : ""; 104 string title = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Title"]) ? Dynamicweb.Context.Current.Request.Form["Title"].ToString() : ""; 105 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 106 string paragraphID = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ParagraphID"]) ? Dynamicweb.Context.Current.Request.Form["ParagraphID"].ToString() : ""; 107 string servicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ID"]) ? Dynamicweb.Context.Current.Request.Form["ID"].ToString() : ""; 108 bool hideTitle = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideTitle"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideTitle"].ToString()) : false; 109 bool hideImage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideImage"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideImage"].ToString()) : false; 110 bool hideProductNumber = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductNumber"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductNumber"].ToString()) : false; 111 bool hideProductName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideProductName"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideProductName"].ToString()) : false; 112 bool hideStock = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideStock"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideStock"].ToString()) : false; 113 bool quantitySelector = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["QuantitySelector"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["QuantitySelector"].ToString()) : false; 114 string addToCartColWidth = quantitySelector ? "160" : "60"; 115 bool hideFilters = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["HideFilters"]) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form["HideFilters"].ToString()) : false; 116117 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 118 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 119 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 120 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 121 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 122123 var badgeParms = new Dictionary<string, object>(); 124 badgeParms.Add("saleBadgeType", saleBadgeType); 125 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 126 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 127 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 128 badgeParms.Add("newPublicationDays", newPublicationDays); 129130 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 131 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 132133 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["Theme"]) ? Dynamicweb.Context.Current.Request.Form["Theme"].ToString() : ""; 134 string modalTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ModalTheme"]) ? Dynamicweb.Context.Current.Request.Form["ModalTheme"].ToString() : "theme light"; 135 string titleFontSize = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["TitleFontSize"]) ? Dynamicweb.Context.Current.Request.Form["TitleFontSize"].ToString() : ""; 136 string contentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["ContentPadding"]) ? Dynamicweb.Context.Current.Request.Form["ContentPadding"].ToString() : ""; 137138 //Create group id collection and products id collection strings 139 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["GroupId"]) ? Dynamicweb.Context.Current.Request.Form["GroupId"].ToString() : ""; 140 string productIds = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["MainProductID"]) ? Dynamicweb.Context.Current.Request.Form["MainProductID"].ToString() : ""; 141 string contextCart = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["OrderContext"]) ? Dynamicweb.Context.Current.Request.Form["OrderContext"].ToString() : ""; 142143 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 144145 string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID"); 146 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 147 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 148 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 149150 if (Model.Item != null) 151 { 152 theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 153 contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 154 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 155 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; 156 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; 157 contentPadding = contentPadding == "small-x" ? "px-2 px-md-3" : contentPadding; 158 contentPadding = contentPadding == "large-x" ? "px-4 px-md-5" : contentPadding; 159 } 160 } 161162 @if (productLists.Any()) { 163164 //The form that defines what should be rendered 165 <form action="/Default.aspx?ID=@servicePageId" id="RelatedProductsListForm_@paragraphID" data-response-target-element="RelatedProductsListFacets_@paragraphID"> 166 <input type="hidden" name="SortOrder" value="DESC" /> 167 <input type="hidden" name="ID" value="@servicePageId" /> 168 <input type="hidden" name="SourceType" value="@sourceType" /> 169 <input type="hidden" name="ParagraphID" value="@paragraphID" /> 170 <input type="hidden" name="RequestType" value="UpdateFacets" id="RelatedProductsListRequestType_@paragraphID" /> 171 <input type="hidden" name="PageSize" value="@pageSizeSetting" id="RelatedProductsListPageSize_@paragraphID" /> 172 <input type="hidden" name="PageSizeSetting" value="@pageSizeSetting" /> 173 <input type="hidden" name="Title" value="@title" /> 174 <input type="hidden" name="HideTitle" value="@hideTitle.ToString()" /> 175 <input type="hidden" name="SelectedDisplayGroups" value="@(string.Join(",", selectedDisplayGroupsList))" /> 176 <input type="hidden" name="HideImage" value="@hideImage.ToString()" /> 177 <input type="hidden" name="HideProductNumber" value="@hideProductNumber.ToString()" /> 178 <input type="hidden" name="HideProductName" value="@hideProductName.ToString()" /> 179 <input type="hidden" name="HideStock" value="@hideStock.ToString()" /> 180 <input type="hidden" name="HideFilters" value="@hideFilters.ToString()" /> 181 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()" /> 182 <input type="hidden" name="Theme" value="@theme" /> 183 <input type="hidden" name="TitleFontSize" value="@titleFontSize" /> 184 <input type="hidden" name="ContentPadding" value="@contentPadding" /> 185186 @if (!string.IsNullOrEmpty(contextCart)) 187 { 188 <input type="hidden" name="OrderContext" value="@contextCart" /> 189 <input type="hidden" name="minicartid" value="@contextCart" /> 190 } 191192 @if (isLazyLoadingForProductInfoEnabled) 193 { 194 <input type="hidden" name="getproductinfo" value="true" /> 195 } 196197 @*--- VARIANTS ---*@ 198 @if (sourceType == "variants") 199 { 200 <input type="hidden" name="MainProductID" value="@productIds" /> 201 } 202203 @*--- MOST SOLD ---*@ 204 @if (sourceType == "most-sold") 205 { 206 <input type="hidden" name="SortBy" value="OrderCount" /> 207 <input type="hidden" name="GroupId" value="@groupId" /> 208 } 209210 @*--- TRENDING ---*@ 211 @if (sourceType == "trending") 212 { 213 <input type="hidden" name="SortBy" value="OrderCountGrowth" /> 214 <input type="hidden" name="GroupId" value="@groupId" /> 215 } 216217 @*--- LATEST ---*@ 218 @if (sourceType == "latest") 219 { 220 <input type="hidden" name="SortBy" value="Created" /> 221 <input type="hidden" name="GroupId" value="@groupId" /> 222 } 223224 @*--- FREQUENTLY BOUGHT ---*@ 225 @if (sourceType == "frequently") 226 { 227 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]" /> 228 } 229230 @*--- RELATED PRODUCTS ---*@ 231 @if (sourceType == "related-products") 232 { 233 <input type="hidden" name="MainProductID" value="@productIds" /> 234 } 235236 @if (sourceType != "variants") 237 { 238 <input type="hidden" name="isVariant" value="false" /> 239 } 240 else 241 { 242 <input type="hidden" name="isVariant" value="true" /> 243 } 244245 <input type="hidden" name="SaleBadgeType" value="@saleBadgeType" /> 246 <input type="hidden" name="SaleBadgeCssClassName" value="@saleBadgeCssClassName" /> 247 <input type="hidden" name="NewBadgeCssClassName" value="@newBadgeCssClassName" /> 248 <input type="hidden" name="NewPublicationDays" value="@newPublicationDays" /> 249250 @if (campaignBadgesValues != "") 251 { 252 <input type="hidden" name="CampaignBadgesValues" value="@campaignBadgesValues" /> 253 } 254 </form> 255256 if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID)) 257 { 258 string itemVariant = string.Empty; 259260 <script> 261 gtag("event", "view_item_list", { 262 item_list_id: "related_product_list", 263 item_list_name: "Related products list", 264 items: [ 265 @foreach (ProductViewModel product in productLists.SelectMany(v => v.Value)) 266 { 267 if (!string.IsNullOrEmpty(product.VariantName)) 268 { 269 itemVariant = $"item_variant:'{product.VariantName}',"; 270 } 271 <text>{ 272 item_id: '@product.Number', 273 item_name: '@product.Name', 274 @itemVariant 275 currency: '@product.Price.CurrencyCode', 276 price: @product.Price.Price 277 },</text> 278 } 279 ] 280 }); 281 </script> 282 } 283 //The products list table 284 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "list") 285 { 286287 <div class="table-responsive w-100"> 288289290291 @foreach (KeyValuePair<string, List<ProductViewModel>> productListDict in productLists) 292 { 293 <div class="h-100 mb-4 @(contentPadding) @theme"> 294 <h3>@productListDict.Key</h3> 295296 <table class="table table-sm table-striped align-middle text-nowrap mobile-responsive-table"> 297 <thead> 298 <tr class="fw-bold"> 299 @if (!hideImage) 300 { 301 <td scope="col">&nbsp;</td> 302 } 303 @if (!hideProductNumber) 304 { 305 <td scope="col" title="#">#</td> 306 } 307 @if (!hideProductName) 308 { 309 <td scope="col" title="@Translate("Product")">@Translate("Product")</td> 310 } 311 @foreach (var header in fieldsHeaders) 312 { 313 <td scope="col" title="@header">@header</td> 314 } 315 @if (!hideStock) 316 { 317 <td scope="col" title="@Translate("Stock")">@Translate("Stock")</td> 318 } 319 @if (!hidePrice) 320 { 321 <td scope="col" align="right" class="pe-2" title="@Translate("Price")">@Translate("Price")</td> 322 } 323 @if (!hideAddToCart) 324 { 325 <td scope="col" title="@Translate("Qty")">@Translate("Qty")</td> 326 } 327 </tr> 328 </thead> 329330 <tbody> 331 @foreach (var product in productListDict.Value) 332 { 333 string image = product.DefaultImage.Value; 334 string popoverImage = product.DefaultImage.Value; 335 image = $"/Admin/Public/GetImage.ashx?image={image}&width=30&format=webp"; 336 popoverImage = $"/Admin/Public/GetImage.ashx?image={popoverImage}&width=350&Format=WebP&Quality=70"; 337338 DateTime createdDate = product.Created.Value; 339 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 340 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 341 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 342343 List<CategoryFieldViewModel> categories = new List<CategoryFieldViewModel>(); 344 foreach (var selection in selectedDisplayGroupsList) 345 { 346 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 347 { 348 if (selection.ToString() == group.Id) 349 { 350 categories.Add(group); 351 } 352 } 353 } 354355 string salesType = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductERPSalesType") ? product.ProductFields["ProductERPSalesType"]?.ToString().ToLower() : null; 356357 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 358 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 359360 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 361 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 362 link += $"&ProductID={product.Id}"; 363 link += variantIdForLink; 364 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 365366 <tr> 367 @if (!hideImage) 368 { 369 <td width="30" scope="row" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="<img src='@popoverImage' style='max-width:100%;' />" data-bs-html="true" data-bs-trigger="hover focus"> 370 <img src="@image"/> 371 </td> 372 } 373 @if (!hideProductNumber) 374 { 375 <td scope="row" title="#"> 376 <a href="@link"> 377 @product.Number 378 </a> 379 </td> 380 } 381 @if (!hideProductName) 382 { 383 <td scope="row" title="@Translate("Product")"> 384 @if (!string.IsNullOrEmpty(product.VariantName)) 385 { 386 <div>@product.Name - @product.VariantName</div> 387 } 388 else 389 { 390 @product.Name 391 } 392393 @if (showBadges) 394 { 395 <div class="fs-7"> 396 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 397 </div> 398 } 399 </td> 400 } 401 @foreach (string fieldCell in fieldsHeaders) 402 { 403 FieldValueViewModel fieldValue = new FieldValueViewModel(); 404 bool fieldFound = false; 405 string fieldTitle = default(string); 406407 foreach (CategoryFieldViewModel category in categories) 408 { 409 foreach (var field in category.Fields) 410 { 411 bool noValues = false; 412 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 413 { 414 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 415 noValues = values.Count > 0 ? false : true; 416 } 417 else if (string.IsNullOrEmpty(field.Value.Value.ToString())) 418 { 419 noValues = true; 420 } 421422 if (!noValues) 423 { 424 string fieldName = field.Value.Name; 425 if (fieldName == fieldCell) 426 { 427 fieldValue = field.Value; 428 fieldTitle = fieldName; 429 fieldFound = true; 430 } 431 } 432 } 433 } 434435 if (fieldFound) 436 { 437 <td title="@fieldTitle">@RenderFieldValue(fieldValue)</td> 438 } 439 else 440 { 441 <td>&nbsp;</td> 442 } 443 } 444445 @if (!hideStock) 446 { 447 <td title="@Translate("Stock")"> 448 @if (product.StockLevel > 0) 449 { 450 <span class="text-success">@Translate("In stock")</span> 451 } 452 else 453 { 454 <span class="text-danger">@Translate("Out of stock")</span> 455 } 456 </td> 457 } 458 @if (!hidePrice) 459 { 460 <td align="right" class="pe-2" title="@Translate("Price")"> 461 <div itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 462 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 463464 @if (showPricesWithVat == "false" && !neverShowVat) 465 { 466 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 467 if (product.Price.Price != product.PriceBeforeDiscount.Price) 468 { 469 <span class="text-decoration-line-through opacity-75 me-3"> 470 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 471 </span> 472 } 473 } 474 else 475 { 476 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 477 if (product.Price.Price != product.PriceBeforeDiscount.Price) 478 { 479 <span class="text-decoration-line-through opacity-75 me-3"> 480 @product.PriceBeforeDiscount.PriceFormatted 481 </span> 482 } 483 } 484485 @if (showPricesWithVat == "false" && !neverShowVat) 486 { 487 <span class="text-price">@product.Price.PriceWithoutVatFormatted</span> 488 } 489 else 490 { 491 <span class="text-price">@product.Price.PriceFormatted</span> 492 } 493 </div> 494 @if (showPricesWithVat == "false" && !neverShowVat) 495 { 496 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 497 } 498 </td> 499 } 500 @if (!hideAddToCart) 501 { 502 bool isDiscontinued = product.Discontinued; 503 bool IsNeverOutOfStock = product.NeverOutOfstock; 504 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 505 disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; 506 disableAddToCart = IsNeverOutOfStock ? "" : disableAddToCart; 507508 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 509 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 510 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 511 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; 512513 <td width="@addToCartColWidth" style="min-width: @(addToCartColWidth)px" align="right" title="@Translate("Qty")"> 514 @if (salesType =="standard") { 515 <form method="post" action="@url"> 516 @if (!string.IsNullOrEmpty(contextCart)) 517 { 518 <input type="hidden" name="OrderContext" value="@contextCart"/> 519 <input type="hidden" name="minicartid" value="@contextCart"/> 520 } 521 <input type="hidden" name="redirect" value="false"/> 522 <input type="hidden" name="ProductId" value="@product.Id"/> 523 <input type="hidden" name="ProductName" value="@product.Name"/> 524 <input type="hidden" name="ProductVariantName" value="@product.VariantName"/> 525 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"/> 526 <input type="hidden" name="ProductPrice" value="@product.Price"/> 527 <input type="hidden" name="ProductReferer" value="product_list_related"> 528 <input type="hidden" name="cartcmd" value="add"/> 529530 @if (!string.IsNullOrEmpty(product.VariantId)) 531 { 532 <input type="hidden" name="VariantId" value="@product.VariantId"/> 533 } 534535 @if (quantitySelector) 536 { 537 <div class="flex-fill input-group input-primary-button-group d-flex flex-row"> 538 <label for="Quantity_@(product.Id)_@product.VariantId" class="visually-hidden">@Translate("Quantity")</label> 539 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="0" step="@stepQty" @minQty class="form-control" style="max-width: 100px" type="number" onkeydown="swift.Cart.UpdateOnEnterKey(event)"> 540 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button icon-2 @disableAddToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 541 @if (stepQty != "1") 542 { 543 <div class="invalid-feedback d-none"> 544 @Translate("Please select a quantity that is dividable by") @stepQty 545 </div> 546 } 547 </div> 548 } 549 else 550 { 551 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" type="hidden"> 552 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button @disableAddToCart icon-2" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)" style="max-width: 3rem;">@ReadFile(iconPath + "shopping-cart.svg")</button> 553 } 554 </form> 555 } 556 else 557 { 558 <p class="small my-2"><span class="fw-bold">@Translate("Bestillingsvare")</span></p> 559 } 560 </td> 561 } 562 </tr> 563 } 564 </tbody> 565 </table> 566 </div> 567 } 568569570 </div> 571 } 572573 if (Model.Item.GetRawValueString("RelatedGroupsLayout") == "slider") 574 { 575 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 576 <script type="module"> 577 swift.AssetLoader.Load('Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 578 </script> 579 <div class="h-100 grid gap-0"> 580 @foreach (var productDict in productLists) 581 { 582 Guid guid = Guid.NewGuid(); 583584585 <div class="g-col-12 mt-4 item_@(Model.Item.SystemName.ToLower())"> 586 <h3 class="mb-4">@productDict.Key</h3> 587 <div id="Slider_@guid" class="swiffy-slider slider-item-show5 slider-nav-chevron-default slider-item-reveal slider-nav-on-slides slider-indicators-dash" style="--swiffy-slider-nav-light:var(--swift-foreground-color);--swiffy-slider-nav-dark:var(--swift-background-color);"> 588 <ul class="slider-container"> 589 @foreach (var product in productDict.Value) 590 { 591 @RenderProduct(product) 592 } 593 </ul> 594 <button type="button" title="@Translate("Previous slide")" class="slider-nav" style="z-index:2;"> 595 <span class="visually-hidden">@Translate("Previous slide")</span> 596 </button> 597 <button type="button" title="@Translate("Next slide")" class="slider-nav slider-nav-next" style="z-index:2;"> 598 <span class="visually-hidden">@Translate("Next slide")</span> 599 </button> 600601 <div class="slider-indicators" style="z-index:2;"> 602 @{ 603 bool isActive = true; 604 int slideCount = 1; 605 } 606607 @foreach (var item in productDict.Value) 608 { 609 <button @(isActive ? "class=\"active\"" : string.Empty) type="button" title='@Translate("Go to slide") @slideCount'> 610 <span class="visually-hidden">@Translate("Go to slide") @slideCount</span> 611 </button> 612 { 613 slideCount++; 614 } 615 isActive = false; 616 } 617 </div> 618 </div> 619620621622 <script type="module"> 623 document.addEventListener('load.swift.assetloader', () => { 624 swiffyslider.initSlider(document.querySelector('#Slider_@guid')); 625 document.querySelector('#Slider_@guid').style.opacity = 1; 626 document.querySelector('#Slider_@guid').style.visibility = "visible"; 627 }); 628 </script> 629 </div> 630631632633 } 634 </div> 635 } 636637638 } 639640 @helper RenderProduct(ProductViewModel product) { 641 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 642 bool anonymousUser = Pageview.User == null; 643 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 644 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 645646 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 647 string ratioCssClass = ratio != "" ? "ratio" : ""; 648 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 649650 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 651 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 652 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 653 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 654 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 655 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 656657 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 658 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 659660 string variantIdForLink = !string.IsNullOrEmpty(product.VariantId) ? $"&VariantID={product.VariantId}" : ""; 661 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(product.DefaultVariantId) ? $"&VariantID={product.DefaultVariantId}" : variantIdForLink; 662663 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 664 link += $"&GroupID={product.PrimaryOrDefaultGroup.Id}"; 665 link += $"&ProductID={product.Id}"; 666 link += variantIdForLink; 667 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 668669 string imagePath = product?.DefaultImage.Value.ToString() ?? ""; 670 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 671672 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 673 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 674 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 675 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 676 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 677678 var badgeParms = new Dictionary<string, object>(); 679 badgeParms.Add("saleBadgeType", saleBadgeType); 680 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 681 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 682 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 683 badgeParms.Add("newPublicationDays", newPublicationDays); 684685 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 686 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 687 DateTime createdDate = product.Created.Value; 688 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 689 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 690 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 691 <li> 692 <a href="@link" class="text-decoration-none d-block h-100"> 693 <div class="h-100 d-flex flex-column justify-content-between theme theme-gray-border"> 694 <div style="border: 1px solid transparent;"> 695 <div class="ratio position-relative" style="--bs-aspect-ratio: 75%"> 696 @if (showBadges) { 697 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 698 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 699 </div> 700 } 701 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 " style="object-fit: contain;" alt="@product.Name"> 702 </div> 703 </div> 704 <div class="flex-fill d-flex flex-column justify-content-between p-3"> 705 <h3 class="h6 opacity-85">@product.Name @product.VariantName</h3> 706707 @if (!hidePrice) { 708 <div> 709710 @if( !anonymousUser) { 711 <p class="mb-0 small">@Translate("Listepris")</p> 712 } 713 <p class="h6 m-0"> 714 @if (showPricesWithVat == "false" && !neverShowVat) 715 { 716 if (product.Price.Price != product.PriceBeforeDiscount.Price) 717 { 718 <span class="text-decoration-line-through opacity-75 me-1"> 719 @product.PriceBeforeDiscount.PriceWithoutVatFormatted 720 </span> 721 } 722 } 723 else 724 { 725 if (product.Price.Price != product.PriceBeforeDiscount.Price) 726 { 727 <span class="text-decoration-line-through opacity-75 me-1"> 728 @product.PriceBeforeDiscount.PriceFormatted 729 </span> 730 } 731 } 732733 @if (showPricesWithVat == "false" && !neverShowVat) 734 { 735 <span class="text-price fw-bold">@product.Price.PriceWithoutVatFormatted</span> 736 } 737 else 738 { 739 <span class="text-price fw-bold">@product.Price.PriceFormatted</span> 740 } 741 </p> 742 @if (showPricesWithVat == "false" && !neverShowVat) 743 { 744 <small class="opacity-85 fst-normal">@product.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 745 } 746 @if( !anonymousUser) { 747 <p class="mb-0 small opacity-75">@Translate("Fragt tilføjes")</p> 748 } 749 </div> 750 } 751 </div> 752 </div> 753 </a> 754 </li> 755 } 756757758 @helper RenderFieldValue(FieldValueViewModel field) { 759 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 760761 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 762 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 763764 bool isColor = false; 765766 if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 767 { 768 int valueCount = 0; 769 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 770 int totalValues = values.Count; 771772 foreach (FieldOptionValueViewModel option in values) 773 { 774 if (option.Value.Substring(0,1) == "#") { 775 isColor = true; 776 } 777778 if (!isColor) { 779 @option.Name 780 } else { 781 <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Value"></span> 782 } 783784 if (valueCount != totalValues && valueCount < (totalValues - 1)) { 785 if (isColor) { 786 <text> </text> 787 } else { 788 <text>, </text> 789 } 790 } 791 valueCount++; 792 } 793 } 794 else if (fieldValue != "") 795 { 796 if (fieldValue.Substring(0,1) == "#") { 797 isColor = true; 798 } 799800 if (!isColor) { 801 @fieldValue 802 } else { 803 <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> 804 } 805 } 806 } 807808809810 @helper RenderCheckboxOption(FacetViewModel facet, FacetOptionViewModel facetOption) 811 { 812 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 813 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 814 string selected = facetOption.Selected ? "checked" : ""; 815816 if (facetLabel.ToLower() == "true") 817 { 818 facetLabel = Translate("Yes"); 819 } 820821 if (facetLabel.ToLower() == "false") 822 { 823 facetLabel = Translate("No"); 824 } 825826 <label class="form-check mb-1" @disabled> 827 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected> 828 <span class="form-check-label d-flex align-items-center"> 829 <span class="flex-fill">@facetLabel </span> 830 <small class="opacity-85">@facetOption.Count</small> 831 </span> 832 </label> 833 } 834835 @helper RenderColorOption(FacetViewModel facet, FacetOptionViewModel facetOption) 836 { 837 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 838 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 839 string selected = facetOption.Selected ? "checked" : ""; 840841 string image = facetOption.Value; 842 string colorCode = facetOption.Value; 843844 var variantOption = Dynamicweb.Ecommerce.Services.VariantOptions.GetVariantOption(facetOption.Value.ToString(), Dynamicweb.Ecommerce.Common.Context.LanguageID); 845 if (variantOption != null) 846 { 847 image = variantOption.LargeImage; 848 colorCode = variantOption.Color; 849 } 850851 <div class="colorbox"> 852 <input type="checkbox" onclick="swift.PageUpdater.Update(event)" class="@disabled @selected" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected title="@facetOption.Label"> 853 @if (colorCode.Contains("#")) 854 { 855 <span class="colorbox-background" style="background-color: @colorCode"></span> 856 } 857 else 858 { 859 <img class="colorbox-background" src="/Admin/Public/GetImage.ashx?width=25&height=25&image=@image" /> 860 } 861 </div> 862 } 863