De CBT Necer Carbon Ultegra DI2 Racefiets is perfect voor de prestatiegerichte wielrenner. Dankzij het vederlichte maar toch supersterke frame weegt de fiets slechts 7,55 kilogram! Voorzien van zeer duurzame en hoogwaardige Zipp wielset met Continental UltraSport II banden voor een perfecte wegligging. De fiets is afgemonteerd met een hoogwaardige Shimano Ultegra DI2 Racefiets groep waar je heel veel kilometers plezier van zal hebben. Ben jij dus op zoek naar een goede racefiets waar je heel lang plezier van wilt hebben, dan is deze CBT Necer Carbon een erg mooie keuze!
Article number: 6727-0001-001-N1806
Free shipping
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat est sed nunc vulputate, ac venenatis mauris faucibus. Nulla sollicitudin nisi varius, sollicitudin tellus vel, ultricies elit. Nunc malesuada sagittis ante, vel blandit odio bibendum sit amet. Aliquam erat volutpat. In eros tellus, gravida sed erat eu, dignissim semper urna. Aenean vulputate tempor fringilla. Suspendisse molestie dictum enim eu dapibus. Mauris id lorem convallis, dictum nibh at, maximus odio. Duis sem arcu, sollicitudin a fermentum ac, elementum aliquet augue. Morbi eget nunc magna. Vivamus lacus nunc, laoreet at venenatis et, rhoncus et est. Duis aliquam condimentum lorem, at convallis massa rhoncus at.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat est sed nunc vulputate, ac venenatis mauris faucibus. Nulla sollicitudin nisi varius, sollicitudin tellus vel, ultricies elit. Nunc malesuada sagittis ante, vel blandit odio bibendum sit amet. Aliquam erat volutpat. In eros tellus, gravida sed erat eu, dignissim semper urna. Aenean vulputate tempor fringilla. Suspendisse molestie dictum enim eu dapibus. Mauris id lorem convallis, dictum nibh at, maximus odio. Duis sem arcu, sollicitudin a fermentum ac, elementum aliquet augue. Morbi eget nunc magna. Vivamus lacus nunc, laoreet at venenatis et, rhoncus et est. Duis aliquam condimentum lorem, at convallis massa rhoncus at.
Error compiling template "Designs/ClientBase_generated/Paragraph/ProductDetailWidgetProductCarousel.cshtml" Line 61: The type or namespace name 'ProductDetailWidgetProductCarousel' could not be found (are you missing a using directive or an assembly reference?) Line 61: 'Services' is obsolete: 'Use Dynamicweb.Content.Services instead.' Line 61: 'Services.Items' is obsolete: 'Use Dynamicweb.Content.Services.Items instead.' Line 61: The type or namespace name 'ProductDetailWidgetProductCarousel' could not be found (are you missing a using directive or an assembly reference?) Line 61: The type or namespace name 'ProductDetailWidgetProductCarousel' could not be found (are you missing a using directive or an assembly reference?)Template file not found (in RenderRazorTemplate()): C:\home\site\wwwroot\files\Templates\Paragraph\ProductDetailWidgetRelatedProductsBasic.cshtml
1 //------------------------------------------------------------------------------ 2 // <auto-generated> 3 // This code was generated by a tool. 4 // Runtime Version:4.0.30319.42000 5 // 6 // Changes to this file may cause incorrect behavior and will be lost if 7 // the code is regenerated. 8 // </auto-generated> 9 //------------------------------------------------------------------------------ 10 11 namespace CompiledRazorTemplates.Dynamic { 12 using System; 13 using System.Collections.Generic; 14 using System.Linq; 15 16 #line 3 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 17 using Dynamicweb.Ecommerce.ProductCatalog; 18 19 #line default 20 #line hidden 21 22 #line 4 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 23 using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 24 25 #line default 26 #line hidden 27 28 #line 5 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 29 using Dynamicweb.Ecommerce.Extensibility.Provider; 30 31 #line default 32 #line hidden 33 34 #line 6 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 35 using Dynamicweb.Ecommerce.Products; 36 37 #line default 38 #line hidden 39 40 #line 7 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 41 using Dynamicweb.Ecommerce.Specialized.RelatedProductListProviders; 42 43 #line default 44 #line hidden 45 46 47 public class RazorEngine_bdfc8a8a14f84f818048f50e4072225a : Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> { 48 49 #line hidden 50 51 public RazorEngine_bdfc8a8a14f84f818048f50e4072225a() { 52 } 53 54 public override void Execute() { 55 WriteLiteral("\r\n"); 56 57 58 #line 9 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 59 60 string paragraphID = Pageview.CurrentParagraph.ID.ToString(); 61 ProductDetailWidgetProductCarousel _data = Dynamicweb.Services.Items.GetItem("ProductDetailWidgetProductCarousel", Model.ItemId).ToCodeFirstItem<ProductDetailWidgetProductCarousel>() ?? new ProductDetailWidgetProductCarousel(); 62 63 ProductViewModel product = new ProductViewModel(); 64 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 65 { 66 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 67 } 68 69 string urlParams = ""; 70 string groupOption = _data.GroupOption; 71 IList<string> relatedProductIds = new List<string> { }; 72 urlParams += "&SortOrder=DESC"; 73 urlParams += $"&PageSize={_data.ProductAmount}"; 74 75 if(groupOption == "popular") 76 { 77 urlParams += "&SortBy=OrderCountGrowth"; 78 } 79 80 if(groupOption == "most-sold") 81 { 82 urlParams += "&SortBy=OrderCount"; 83 } 84 85 if(groupOption == "recently-viewed") 86 { 87 List<Product> YouHaveSeenTheseProductsList = new YouHaveSeenTheseProductsList().GetCollection(new RelatedProductListProviderEventArgs()).Reverse().Take(_data.ProductAmount).ToList(); 88 if(YouHaveSeenTheseProductsList.Any()) 89 { 90 foreach (Product recentProduct in YouHaveSeenTheseProductsList) 91 { 92 relatedProductIds.Add(recentProduct.Id); 93 } 94 string productIds = string.Join(",", relatedProductIds); 95 urlParams += !string.IsNullOrEmpty(productIds) ? "&ProductIDs=" + productIds : ""; 96 } 97 } 98 99 if(groupOption == "related" && product.RelatedGroups != null) 100 { 101 var relatedGroup = product.RelatedGroups.Where(g => g.Id == _data.RelatedGroupID).First(); 102 foreach (var relatedProduct in relatedGroup.Products) 103 { 104 relatedProductIds.Add(relatedProduct.ProductId); 105 } 106 string productIds = string.Join(",", relatedProductIds); 107 urlParams += !string.IsNullOrEmpty(productIds) ? "&ProductIDs=" + productIds : ""; 108 } 109 110 string link = "/Default.aspx?ID=1718&LayoutTemplate=VisualEditorPageAPI.cshtml" + urlParams; 111 string relatedGroupName = _data.Header; 112 113 114 115 #line default 116 #line hidden 117 WriteLiteral("\r\n\r\n<div"); 118 119 WriteAttribute("id", Tuple.Create(" id=\"", 2387), Tuple.Create("\"", 2404) 120 121 #line 65 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 122 , Tuple.Create(Tuple.Create("", 2392), Tuple.Create<System.Object, System.Int32>(paragraphID 123 124 #line default 125 #line hidden 126 , 2392), false) 127 ); 128 129 WriteAttribute("class", Tuple.Create(" class=\"", 2405), Tuple.Create("\"", 2454) 130 , Tuple.Create(Tuple.Create("", 2413), Tuple.Create("pdp-paragraph", 2413), true) 131 , Tuple.Create(Tuple.Create(" ", 2426), Tuple.Create("pdp-paragraph__", 2427), true) 132 133 #line 65 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 134 , Tuple.Create(Tuple.Create("", 2442), Tuple.Create<System.Object, System.Int32>(paragraphID 135 136 #line default 137 #line hidden 138 , 2442), false) 139 ); 140 141 WriteLiteral(">\r\n\t<section"); 142 143 WriteLiteral(" class=\"products-module__container\""); 144 145 WriteLiteral(">\r\n\t\t<div"); 146 147 WriteLiteral(" class=\"container\""); 148 149 WriteLiteral(">\r\n\t\t\t\r\n"); 150 151 152 #line 69 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 153 154 155 #line default 156 #line hidden 157 158 #line 69 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 159 if(!string.IsNullOrWhiteSpace(relatedGroupName)) 160 { 161 162 163 #line default 164 #line hidden 165 WriteLiteral("\t\t\t\t<header"); 166 167 WriteLiteral(" class=\"products-module__header\""); 168 169 WriteLiteral(">\r\n\t\t\t\t\t<h2"); 170 171 WriteLiteral(" class=\"products-module__title\""); 172 173 WriteLiteral(">"); 174 175 176 #line 72 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 177 Write(relatedGroupName); 178 179 180 #line default 181 #line hidden 182 WriteLiteral("</h2>\r\n\t\t\t\t</header>\r\n"); 183 184 185 #line 74 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 186 } 187 188 189 #line default 190 #line hidden 191 WriteLiteral("\r\n\t\t\t<div"); 192 193 WriteLiteral(" class=\"product-carousel\""); 194 195 WriteLiteral(" data-url=\""); 196 197 198 #line 76 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 199 Write(link); 200 201 202 #line default 203 #line hidden 204 WriteLiteral("\""); 205 206 WriteLiteral(" data-id=\""); 207 208 209 #line 76 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 210 Write(paragraphID); 211 212 213 #line default 214 #line hidden 215 WriteLiteral("\""); 216 217 WriteLiteral("></div>\r\n\t\t\r\n\t\t</div>\r\n\t</section>\r\n</div>\r\n\r\n<script"); 218 219 WriteLiteral(" type=\"module\""); 220 221 WriteLiteral(" src=\"https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js\""); 222 223 WriteLiteral("></script>\r\n<script"); 224 225 WriteLiteral(" type=\"module\""); 226 227 WriteLiteral(">\r\n\r\n\tdocument.addEventListener(\'initCarousel__"); 228 229 230 #line 85 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 231 Write(paragraphID); 232 233 234 #line default 235 #line hidden 236 WriteLiteral("\', function () {\r\n\t\tvar carousel = document.querySelector(\".pdp-paragraph__"); 237 238 239 #line 86 "C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetProductCarousel.cshtml" 240 Write(paragraphID); 241 242 243 #line default 244 #line hidden 245 WriteLiteral(" .products-module__container--carousel\");\r\n\r\n\t\tif(carousel) {\r\n\t\t\tvar flkty = new" + 246 " Flickity(carousel, {\r\n\t\t\t\tcellAlign: \'left\',\r\n\t\t\t\tcontain: true,\r\n\t\t\t\tpageDots:" + 247 " false\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\r\n</script>\r\n"); 248 249 } 250 } 251 } 252
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using Dynamicweb.Ecommerce.ProductCatalog; 4 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 5 @using Dynamicweb.Ecommerce.Extensibility.Provider; 6 @using Dynamicweb.Ecommerce.Products; 7 @using Dynamicweb.Ecommerce.Specialized.RelatedProductListProviders; 8 9 @{ 10 string paragraphID = Pageview.CurrentParagraph.ID.ToString(); 11 ProductDetailWidgetProductCarousel _data = Dynamicweb.Services.Items.GetItem("ProductDetailWidgetProductCarousel", Model.ItemId).ToCodeFirstItem<ProductDetailWidgetProductCarousel>() ?? new ProductDetailWidgetProductCarousel(); 12 13 ProductViewModel product = new ProductViewModel(); 14 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 15 { 16 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 17 } 18 19 string urlParams = ""; 20 string groupOption = _data.GroupOption; 21 IList<string> relatedProductIds = new List<string> { }; 22 urlParams += "&SortOrder=DESC"; 23 urlParams += $"&PageSize={_data.ProductAmount}"; 24 25 if(groupOption == "popular") 26 { 27 urlParams += "&SortBy=OrderCountGrowth"; 28 } 29 30 if(groupOption == "most-sold") 31 { 32 urlParams += "&SortBy=OrderCount"; 33 } 34 35 if(groupOption == "recently-viewed") 36 { 37 List<Product> YouHaveSeenTheseProductsList = new YouHaveSeenTheseProductsList().GetCollection(new RelatedProductListProviderEventArgs()).Reverse().Take(_data.ProductAmount).ToList(); 38 if(YouHaveSeenTheseProductsList.Any()) 39 { 40 foreach (Product recentProduct in YouHaveSeenTheseProductsList) 41 { 42 relatedProductIds.Add(recentProduct.Id); 43 } 44 string productIds = string.Join(",", relatedProductIds); 45 urlParams += !string.IsNullOrEmpty(productIds) ? "&ProductIDs=" + productIds : ""; 46 } 47 } 48 49 if(groupOption == "related" && product.RelatedGroups != null) 50 { 51 var relatedGroup = product.RelatedGroups.Where(g => g.Id == _data.RelatedGroupID).First(); 52 foreach (var relatedProduct in relatedGroup.Products) 53 { 54 relatedProductIds.Add(relatedProduct.ProductId); 55 } 56 string productIds = string.Join(",", relatedProductIds); 57 urlParams += !string.IsNullOrEmpty(productIds) ? "&ProductIDs=" + productIds : ""; 58 } 59 60 string link = "/Default.aspx?ID=1718&LayoutTemplate=VisualEditorPageAPI.cshtml" + urlParams; 61 string relatedGroupName = _data.Header; 62 63 } 64 65 <div id="@paragraphID" class="pdp-paragraph pdp-paragraph__@paragraphID"> 66 <section class="products-module__container"> 67 <div class="container"> 68 69 @if(!string.IsNullOrWhiteSpace(relatedGroupName)) 70 { 71 <header class="products-module__header"> 72 <h2 class="products-module__title">@relatedGroupName</h2> 73 </header> 74 } 75 76 <div class="product-carousel" data-url="@link" data-id="@paragraphID"></div> 77 78 </div> 79 </section> 80 </div> 81 82 <script type="module" src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script> 83 <script type="module"> 84 85 document.addEventListener('initCarousel__@paragraphID', function () { 86 var carousel = document.querySelector(".pdp-paragraph__@paragraphID .products-module__container--carousel"); 87 88 if(carousel) { 89 var flkty = new Flickity(carousel, { 90 cellAlign: 'left', 91 contain: true, 92 pageDots: false 93 }); 94 } 95 }); 96 97 </script> 98
Article number: 6727-0001-001-N1806
Nieuwe serie Polaris Elements kralen in 4 en 6 mm met glanzende of matte coating. Verwerk de kralen in een trendy armband of in statement oorbellen. Door de kralen op dun artistic wire te wikkelen om dikker om dikker artistic wire, ontwerp je stijlvolle oorbellen!
Nieuwe serie Polaris Elements kralen in 4 en 6 mm met glanzende of matte coating. Verwerk de kralen in een trendy armband of in statement oorbellen. Door de kralen op dun artistic wire te wikkelen om dikker om dikker artistic wire, ontwerp je stijlvolle oorbellen!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat est sed nunc vulputate, ac venenatis mauris faucibus. Nulla sollicitudin nisi varius, sollicitudin tellus vel, ultricies elit. Nunc malesuada sagittis ante, vel blandit odio bibendum sit amet. Aliquam erat volutpat. In eros tellus, gravida sed erat eu, dignissim semper urna. Aenean vulputate tempor fringilla. Suspendisse molestie dictum enim eu dapibus. Mauris id lorem convallis, dictum nibh at, maximus odio. Duis sem arcu, sollicitudin a fermentum ac, elementum aliquet augue. Morbi eget nunc magna. Vivamus lacus nunc, laoreet at venenatis et, rhoncus et est. Duis aliquam condimentum lorem, at convallis massa rhoncus at.
Heel verhaal...
De CBT Necer Carbon Ultegra DI2 Racefiets is perfect voor de prestatiegerichte wielrenner. Dankzij het vederlichte maar toch supersterke frame weegt de fiets slechts 7,55 kilogram! Voorzien van zeer duurzame en hoogwaardige Zipp wielset met Continental UltraSport II banden voor een perfecte wegligging. De fiets is afgemonteerd met een hoogwaardige Shimano Ultegra DI2 Racefiets groep waar je heel veel kilometers plezier van zal hebben. Ben jij dus op zoek naar een goede racefiets waar je heel lang plezier van wilt hebben, dan is deze CBT Necer Carbon een erg mooie keuze!
De CBT Necer Carbon Ultegra DI2 Racefiets is perfect voor de prestatiegerichte wielrenner. Dankzij het vederlichte maar toch supersterke frame weegt de fiets slechts 7,55 kilogram! Voorzien van zeer duurzame en hoogwaardige Zipp wielset met Continental UltraSport II banden voor een perfecte wegligging. De fiets is afgemonteerd met een hoogwaardige Shimano Ultegra DI2 Racefiets groep waar je heel veel kilometers plezier van zal hebben. Ben jij dus op zoek naar een goede racefiets waar je heel lang plezier van wilt hebben, dan is deze CBT Necer Carbon een erg mooie keuze!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat est sed nunc vulputate, ac venenatis mauris faucibus. Nulla sollicitudin nisi varius, sollicitudin tellus vel, ultricies elit. Nunc malesuada sagittis ante, vel blandit odio bibendum sit amet. Aliquam erat volutpat. In eros tellus, gravida sed erat eu, dignissim semper urna. Aenean vulputate tempor fringilla. Suspendisse molestie dictum enim eu dapibus. Mauris id lorem convallis, dictum nibh at, maximus odio. Duis sem arcu, sollicitudin a fermentum ac, elementum aliquet augue. Morbi eget nunc magna. Vivamus lacus nunc, laoreet at venenatis et, rhoncus et est. Duis aliquam condimentum lorem, at convallis massa rhoncus at.
Voeg snel artikelen toe aan de winkelmand door een bestand in XSLX formaat te uploaden.
Een voorbeeldbestand download u hier: Voorbeeld bestand XSLX upload
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tincidunt mauris elit, eget iaculis risus egestas eget. Etiam iaculis vehicula tortor ut viverra. Mauris venenatis lectus diam, eget ultricies arcu volutpat at. Suspendisse ac dolor varius, consectetur nisl id, tristique ipsum. Maecenas sed nunc in sapien posuere semper.
Article number: 6727-0001-001-N1806
Voor 12:00 uur besteld, morgen in huis
Error executing template "/Designs/ClientBase_generated/Paragraph/ProductDetailWidgetSpecifications.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_34d7f95567ba499fba94f80c7cd51da0.Execute() in C:\home\site\wwwroot\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetSpecifications.cshtml:line 82 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Linq; 3 @using System.Web; 4 @using System.Collections.Generic; 5 @using Dynamicweb; 6 @using Dynamicweb.Content.Items; 7 @using Dynamicweb.Ecommerce.ProductCatalog; 8 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 9 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution.Frontend; 10 @using Bluedesk.DynamicWeb.ItemTypes; 11 @using System.Text.RegularExpressions; 12 13 @{ 14 string paragraphID = Pageview.CurrentParagraph.ID.ToString(); 15 ProductDetailWidgetSpecifications _data = Dynamicweb.Content.Services.Items.GetItem("ProductDetailWidgetSpecifications", Model.ItemId).ToCodeFirstItem<ProductDetailWidgetSpecifications>() ?? new ProductDetailWidgetSpecifications(); 16 17 bool IsNotContentManager = false; 18 bool isVisualEditor = Pageview.IsVisualEditorMode; 19 20 if (isVisualEditor) 21 { 22 Dynamicweb.Context.Current.Session["PreviousPage"] = Pageview.Page.ID; 23 IsNotContentManager = (Dynamicweb.Security.UserManagement.User.GetCurrentBackendUser()?.Groups?.All(g => g.Name != "Content managers") ?? true); 24 } 25 26 ProductViewModel product = new ProductViewModel(); 27 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 28 { 29 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 30 } 31 32 List<ProductDetailWidgetSpecificationProductField> selectedProductFields = _data.SelectedProductFields; 33 List<ProductDetailWidgetSpecificationCategoryItem> selectedCategories = _data.SelectedCategories; 34 List<ProductDetailWidgetSpecificationCategoryField> selectedCategoryValues = _data.SelectedCategoryValues; 35 bool showLabels = _data.ProductFieldsShowLabels; 36 bool combinedList = _data.CategoryCombinedList; 37 bool alphabeticalSorting = _data.SortOrder == "alphabetical"; 38 int columns = _data.Columns > 0 ? _data.Columns : 1; 39 bool hasCustomTemplate = _data.UseCustomTemplate && !string.IsNullOrWhiteSpace(_data.Template); 40 41 var specificationsList = new List<dynamic>(); 42 var defaultCategory = new 43 { 44 CategoryName = _data.ListHeader, 45 CategoryId = "default-category", 46 CategoryClass = "default-category", 47 Fields = new List<dynamic>() 48 }; 49 50 if (selectedProductFields.Any()) 51 { 52 foreach (ProductDetailWidgetSpecificationProductField prField in selectedProductFields) 53 { 54 if (product.ProductFields != null && product.ProductFields.ContainsKey(prField.ProductField)) 55 { 56 var field = product.ProductFields[prField.ProductField]; 57 if (!string.IsNullOrWhiteSpace(field.Value.ToString()) && field.Value is List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel> list && list.Any()) 58 { 59 defaultCategory.Fields.Add(new 60 { 61 Label = Translate("Specification_" + field.SystemName, field.Name.ToString()), 62 Value = GetFieldValue(field), 63 }); 64 } 65 } 66 } 67 } 68 69 if (selectedCategoryValues.Any()) 70 { 71 foreach (ProductDetailWidgetSpecificationCategoryField i in selectedCategoryValues) 72 { 73 string catName = i.CategoryValue.Split(';')[0]; 74 string fieldName = i.CategoryValue.Split(';')[1]; 75 76 if (product.ProductCategories != null && product.ProductCategories.ContainsKey(catName)) 77 { 78 var category = product.ProductCategories[catName]; 79 if (category.Fields.ContainsKey(fieldName)) 80 { 81 var field = category.Fields[fieldName]; 82 if (!string.IsNullOrWhiteSpace(field.Value.ToString()) && field.Value is List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel> list && list.Any()) 83 { 84 defaultCategory.Fields.Add(new 85 { 86 Label = Translate("Specification_" + catName + "_" + field.SystemName, field.Name.ToString()), 87 Value = GetFieldValue(field), 88 }); 89 } 90 } 91 } 92 } 93 } 94 95 if (defaultCategory.Fields.Any()) 96 { 97 specificationsList.Add(defaultCategory); 98 } 99 100 if (selectedCategories.Any()) 101 { 102 foreach (ProductDetailWidgetSpecificationCategoryItem cat in selectedCategories) 103 { 104 if (product.ProductCategories != null && product.ProductCategories.ContainsKey(cat.Category)) 105 { 106 var category = product.ProductCategories[cat.Category]; 107 108 var categoryObj = new 109 { 110 CategoryName = category.Name, 111 CategoryId = category.Id, 112 CategoryClass = category.Id.ToLower(), 113 Fields = category.Fields 114 .Where(field => !string.IsNullOrWhiteSpace(field.Value.ToString())) 115 .Select(field => new 116 { 117 Label = Translate("Specification_" + cat.Category + "_" + field.Value.SystemName, field.Value.Name.ToString()), 118 Value = field.Value 119 }).ToList() 120 }; 121 122 if (categoryObj.Fields.Any()) 123 { 124 if (alphabeticalSorting) 125 { 126 categoryObj.Fields.Sort((a, b) => string.Compare(a.Label, b.Label, StringComparison.OrdinalIgnoreCase)); 127 } 128 129 if (combinedList) 130 { 131 foreach (var f in categoryObj.Fields) 132 { 133 defaultCategory.Fields.Add(f); 134 } 135 } 136 else 137 { 138 specificationsList.Add(categoryObj); 139 } 140 } 141 } 142 } 143 } 144 145 if (alphabeticalSorting) 146 { 147 defaultCategory.Fields.Sort((a, b) => string.Compare(a.Label, b.Label, StringComparison.OrdinalIgnoreCase)); 148 } 149 150 string ElementID = !string.IsNullOrWhiteSpace(_data.CustomID) ? _data.CustomID : paragraphID; 151 152 } 153 154 <div id="@ElementID" class="pdp-paragraph @_data.CssClass"> 155 156 157 @if (!string.IsNullOrWhiteSpace(_data.ListHeader)){ 158 // <div class="product-specifications__header">@_data.ListHeader</div> 159 } 160 161 @if(!hasCustomTemplate) 162 { 163 var specifications = specificationsList.Where(s => s.Fields.Count > 0); 164 165 if(specifications.Any()) 166 { 167 foreach (var spec in specifications) 168 { 169 string className = $"product-specifications__list-{spec.CategoryClass}"; 170 171 string ProductSpecificationTitle = !string.IsNullOrWhiteSpace(_data.ListHeader) ? _data.ListHeader : spec.CategoryName; 172 173 <section class="product-specifications__category @className"> 174 @if(!string.IsNullOrWhiteSpace(spec.CategoryName)) 175 { 176 <h3 class="product-specifications__title">@ProductSpecificationTitle</h3> 177 } 178 <ul class="product-specifications__list" style="--column: @columns"> 179 @foreach (var field in spec.Fields) 180 { 181 <li class="product-specifications__list-item"> 182 @if(showLabels) 183 { 184 <span class="product-specifications__label">@field.Label</span> 185 } 186 <span class="product-specifications__value">@field.Value</span> 187 </li> 188 } 189 </ul> 190 </section> 191 } 192 } else { 193 if (_data.HideTabWhenEmpty) 194 { 195 <script> 196 document.addEventListener('DOMContentLoaded', function () { 197 var paragraphElement = document.getElementById('@paragraphID'); 198 if (!paragraphElement) { 199 return; 200 } 201 202 var parentElement = paragraphElement.closest('.content-tab'); 203 if (!parentElement) { 204 return; 205 } 206 207 var tabElement = document.querySelector('[data-tab-target="' + parentElement.id + '"]'); 208 if (!tabElement) { 209 return; 210 } 211 212 var tabContent = paragraphElement.closest('.content-tab'); 213 if(!tabContent) { 214 return; 215 } 216 217 var tabLinkElement = document.querySelector('a[href*="' + tabContent.id + '"]'); 218 if(!tabLinkElement) { 219 return; 220 } 221 222 @{ 223 if (isVisualEditor && IsNotContentManager) 224 { 225 <text>tabElement.style.display = 'flex';</text> 226 } 227 else 228 { 229 <text>tabElement.style.display = 'none';</text> 230 <text>tabLinkElement.style.display = 'none';</text> 231 } 232 } 233 }); 234 </script> 235 } 236 } 237 } else { 238 string fieldContent = ExtractContent(_data.Template, "{{field}}", "{{/field}}").Trim(); 239 string categoryContent = ExtractContent(_data.Template, "{{category}}", "{{/category}}").Trim(); 240 241 // Replace all matches with {{catsplaceholder}} 242 string fieldPattern = @"\{\{field\}\}[\s\S]*?\{\{/field\}\}"; 243 categoryContent = Regex.Replace(categoryContent, fieldPattern, "{{catsplaceholder}}"); 244 245 // Replace all matches with {{placeholder}} 246 string catPattern = @"\{\{category\}\}[\s\S]*?\{\{/category\}\}"; 247 string wrapperContent = Regex.Replace(_data.Template, catPattern, "{{placeholder}}"); 248 249 var categoryTemplate = new System.Text.StringBuilder(); 250 var valuesTemplate = new System.Text.StringBuilder(); 251 252 foreach (var spec in specificationsList.Where(s => s.Fields.Count > 0)) 253 { 254 string categoryHtmlLine = categoryContent.Replace("{{category}}", ""); 255 categoryTemplate.AppendLine(categoryHtmlLine); 256 foreach (var field in spec.Fields) 257 { 258 string valueHtmlLine = fieldContent.Replace("{{label}}", field.Label).Replace("{{value}}", field.Value); 259 valuesTemplate.AppendLine(valueHtmlLine); 260 } 261 } 262 263 string customHtmlTemplate = wrapperContent.Replace("{{placeholder}}", categoryTemplate.ToString()).Replace("{{catsplaceholder}}", valuesTemplate.ToString()); 264 265 @customHtmlTemplate 266 } 267 </div> 268 269 @functions { 270 private string GetFieldValue(dynamic field) 271 { 272 if (field.Type == "List") 273 { 274 var valueList = new List<string>(); 275 foreach (dynamic v in field.Value) 276 { 277 valueList.Add($"{v.Value}"); 278 } 279 return string.Join(", ", valueList); 280 } 281 else 282 { 283 return field.Value?.ToString() ?? ""; 284 } 285 } 286 287 private string ExtractContent(string input, string startPattern, string endPattern) 288 { 289 int startIndex = input.IndexOf(startPattern) + startPattern.Length; 290 int endIndex = input.IndexOf(endPattern, startIndex); 291 if (startIndex == -1 || endIndex == -1) 292 { 293 // Handle error - Patterns not found 294 } 295 return input.Substring(startIndex, endIndex - startIndex).Trim(); 296 } 297 } 298