DELIVERY 1-2 BUSINESS DAYS| Free shipping in Denmark on purchases of more than EUR 40| Free shipping in Sweden on purchases of more than EUR 67
Error executing template "Designs/Rapido/eCom/Product/Product.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<RenderStickers>b__14_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 510
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<RenderImage>b__15_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 582
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 192
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 134
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 214
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 123
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 214
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 134
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<RenderProductTop>b__58_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2999
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 192
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 106
   at CompiledRazorTemplates.Dynamic.RazorEngine_e2be7b86992a4fd583f4f42056e43d8a.Execute() in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2989
   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.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 3 @using System.Web 4 @using Dynamicweb.Extensibility 5 @using Dynamicweb.Content 6 @using System 7 @using System.IO 8 @using Dynamicweb.Core 9 @using System.Web 10 @using System.Globalization 11 @using System.Web.UI.HtmlControls 12 @using Dynamicweb.Rapido.Blocks 13 @using Dynamicweb.Ecommerce 14 15 @functions { 16 List<LoopItem> downloadDocuments = new List<LoopItem>(); 17 //downloadDocuments variable, will be defined in Fields.cshtml and used in ProductAssets.cshtml 18 19 BlocksPage productsPage = BlocksPage.GetBlockPage("Product"); 20 21 public static string ToPascalCase(string str) { 22 return CultureInfo.InvariantCulture.TextInfo 23 .ToTitleCase(str.ToLowerInvariant()) 24 .Replace("-", "") 25 .Replace("_", "") 26 .Replace(" ", ""); 27 } 28 } 29 30 @{ 31 string productBlocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info"; 32 bool productInfoOnTheRight = productBlocksPosition.LastIndexOf("info") == productBlocksPosition.Length - 4; 33 34 Block productTop = new Block() { 35 Id = "Top", 36 SortId = 10, 37 SkipRenderBlocksList = true, 38 Template = RenderProductTop() 39 }; 40 productsPage.Add(productTop); 41 42 Block productMainInfo = new Block() { 43 Id = "MainInformation", 44 SortId = productInfoOnTheRight ? 20 : 10, 45 Design = new Design { 46 Size = "auto", 47 RenderType = RenderType.Column 48 } 49 }; 50 productsPage.Add("Top", productMainInfo); 51 52 //Optional mini tabs block 53 Block miniTabsBlock = new Block() { 54 Id = "MiniTabs", 55 SortId = 40, 56 Template = RenderProductMiniTabs(), 57 SkipRenderBlocksList = true 58 }; 59 productsPage.Add("MainInformation", miniTabsBlock); 60 //----- 61 62 Block productTabsBlock = new Block() { 63 Id = "Tabs", 64 SortId = 30, 65 Template = RenderProductTabs(), 66 SkipRenderBlocksList = true 67 }; 68 productsPage.Add(productTabsBlock); 69 70 Block productDetailsBlock = new Block() { 71 Id = "Section", 72 SortId = 30 73 }; 74 productsPage.Add(productDetailsBlock); 75 76 Block productSnippetsBlock = new Block() { 77 Id = "Snippets", 78 SortId = 40 79 }; 80 productsPage.Add(productSnippetsBlock); 81 } 82 83 @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ 84 @using System.Text.RegularExpressions 85 @using System.Collections.Generic 86 @using System.Reflection 87 @using System.Web.UI.HtmlControls 88 @using Dynamicweb.Rapido.Blocks.Components 89 @using Dynamicweb.Rapido.Blocks.Components.Articles 90 @using Dynamicweb.Rapido.Blocks.Components.Documentation 91 @using Dynamicweb.Rapido.Blocks 92 93 94 @*--- START: Base block renderers ---*@ 95 96 @helper RenderBlockList(List<Block> blocks) 97 { 98 blocks = blocks.OrderBy(item => item.SortId).ToList(); 99 100 foreach (Block item in blocks) 101 { 102 <!-- START: @item.Id --> 103 104 if (item.Design == null) 105 { 106 @RenderBlock(item) 107 } 108 else if (item.Design.RenderType == RenderType.None) { 109 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 110 111 <div class="@cssClass dw-mod"> 112 @RenderBlock(item) 113 </div> 114 } 115 else if (item.Design.RenderType != RenderType.Hide) 116 { 117 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 118 119 if (!item.SkipRenderBlocksList) { 120 if (item.Design.RenderType == RenderType.Row) 121 { 122 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id"> 123 @RenderBlock(item) 124 </div> 125 } 126 127 if (item.Design.RenderType == RenderType.Column) 128 { 129 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 130 string size = item.Design.Size ?? "12"; 131 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; 132 133 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding @cssClass dw-mod" id="Block__@item.Id"> 134 @RenderBlock(item) 135 </div> 136 } 137 138 if (item.Design.RenderType == RenderType.Table) 139 { 140 <table class="table @cssClass dw-mod" id="Block__@item.Id"> 141 @RenderBlock(item) 142 </table> 143 } 144 145 if (item.Design.RenderType == RenderType.TableRow) 146 { 147 <tr class="@cssClass dw-mod" id="Block__@item.Id"> 148 @RenderBlock(item) 149 </tr> 150 } 151 152 if (item.Design.RenderType == RenderType.TableColumn) 153 { 154 <td class="@cssClass dw-mod" id="Block__@item.Id"> 155 @RenderBlock(item) 156 </td> 157 } 158 159 if (item.Design.RenderType == RenderType.CardHeader) 160 { 161 <div class="card-header @cssClass dw-mod"> 162 @RenderBlock(item) 163 </div> 164 } 165 166 if (item.Design.RenderType == RenderType.CardBody) 167 { 168 <div class="card @cssClass dw-mod"> 169 @RenderBlock(item) 170 </div> 171 } 172 173 if (item.Design.RenderType == RenderType.CardFooter) 174 { 175 <div class="card-footer @cssClass dw-mod"> 176 @RenderBlock(item) 177 </div> 178 } 179 } 180 else 181 { 182 @RenderBlock(item) 183 } 184 } 185 186 <!-- END: @item.Id --> 187 } 188 } 189 190 @helper RenderBlock(Block item) 191 { 192 if (item.Template != null) 193 { 194 @BlocksPage.RenderTemplate(item.Template) 195 } 196 197 if (item.Component != null) 198 { 199 string methodName = item.Component.HelperName; 200 dynamic[] methodParameters = new dynamic[1]; 201 methodParameters[0] = item.Component; 202 Type methodType = this.GetType(); 203 MethodInfo generalMethod = methodType.GetMethod(methodName); 204 205 if (generalMethod != null) { 206 @generalMethod.Invoke(this, methodParameters).ToString(); 207 } else { 208 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked"); 209 } 210 } 211 212 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList) 213 { 214 @RenderBlockList(item.BlocksList) 215 } 216 } 217 218 @*--- END: Base block renderers ---*@ 219 220 221 @* Include the Blocks for the page *@ 222 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 223 @using Dynamicweb.Core 224 @using System 225 @using System.Web 226 @using System.Collections.Generic 227 @using Dynamicweb.Rapido.Blocks 228 229 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 230 @using System.Linq; 231 232 @functions{ 233 public class Sticker { 234 public string className { get; set; } 235 public string text { get; set; } 236 public string groupColor { get; set; } 237 public string image { get; set; } 238 public string imageSrc { get; set; } 239 } 240 241 public class StickersContainer { 242 public string position { get; set; } 243 public List<Sticker> Stickers { get; set; } 244 } 245 246 public void AddSticker(List<StickersContainer> list, Sticker sticker, string stickerPosition) { 247 StickersContainer stickersContainerTemp; 248 if (string.IsNullOrEmpty(stickerPosition)) { 249 stickerPosition = "top-left"; 250 } 251 stickersContainerTemp = list.FirstOrDefault(stickersContainer => stickersContainer.position == stickerPosition); 252 if (stickersContainerTemp == null) { 253 stickersContainerTemp = new StickersContainer() { 254 position = stickerPosition, 255 Stickers = new List<Sticker>() 256 }; 257 list.Add(stickersContainerTemp); 258 } 259 stickersContainerTemp.Stickers.Add(sticker); 260 } 261 262 public List<StickersContainer> GetStickersContainersList(List<LoopItem> discountsLoop, double discountPrice, double price, DateTime createdDate, string customStickerValue, string groupName, string newGroupColor) { 263 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 264 bool isSaleStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetBoolean("Enable"); 265 bool isNewsStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable"); 266 bool isCustomStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetBoolean("Enable"); 267 bool b2cUser = false; 268 if (Pageview.User == null || Pageview.User != null && Pageview.User.HasGroup(7913)) { 269 b2cUser = true; 270 } 271 272 List<StickersContainer> resultList = new List<StickersContainer>(); 273 274 if (!pointShopOnly && isSaleStickersEnabled && b2cUser) { 275 string contentType = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetString("ContentType"); 276 contentType = !string.IsNullOrEmpty(contentType) ? contentType : "Name"; 277 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); 278 Sticker saleSticker = new Sticker(); 279 saleSticker.className = "stickers-container__tag--sale"; 280 281 switch (contentType) { 282 case "Name": 283 foreach (LoopItem discount in discountsLoop) { 284 saleSticker.text = discount.GetString("Ecom:Product.Discount.Name"); 285 saleSticker.image = discount.GetString("Ecom:Product.Discount.CampaignImage"); 286 if (!string.IsNullOrEmpty(saleSticker.image)) { 287 int startPath = saleSticker.image.IndexOf("src=\"")+5; 288 saleSticker.imageSrc = saleSticker.image.Substring(startPath, saleSticker.image.IndexOf("\" ") - startPath); 289 } 290 saleSticker.groupColor = discount.GetString("Ecom:Product.Discount.CampaignColor"); 291 } 292 break; 293 case "Amount": 294 if (discountsLoop.Count > 0) { 295 saleSticker.text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, discountPrice - price); 296 } 297 break; 298 case "Percents": 299 double percents = 0; 300 foreach (LoopItem discount in discountsLoop) { 301 percents += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 302 } 303 if (percents > 0) { 304 saleSticker.text = Math.Round(percents, 0) + "%"; 305 } 306 break; 307 case "Amount+and+percents": 308 double amount = 0; 309 double percent = 0; 310 foreach (LoopItem discount in discountsLoop) { 311 if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT") { 312 percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 313 } else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT") { 314 amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT"); 315 } 316 } 317 318 if (percent > 0) { 319 saleSticker.text = percent + "%"; 320 } else if (amount > 0) { 321 saleSticker.text = "-" + Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); 322 } 323 break; 324 default: 325 if (discountsLoop.Count > 0) { 326 saleSticker.text = Translate("Sale!"); 327 } 328 break; 329 } 330 331 string saleStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position") != null ? 332 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position").SelectedValue : "topLeft"; 333 if (!string.IsNullOrEmpty(saleSticker.text)) { 334 AddSticker(resultList, saleSticker, saleStickerPosition); 335 } 336 } 337 338 if (!pointShopOnly && isNewsStickersEnabled && createdDate.AddDays(Converter.ToDouble(Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetString("Expiration"))) > DateTime.Now) { 339 Sticker newSticker = new Sticker(); 340 newSticker.className = "stickers-container__tag--new"; 341 newSticker.text = Translate("New!"); 342 string newStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position") != null ? 343 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position").SelectedValue : "topLeft"; 344 AddSticker(resultList, newSticker, newStickerPosition); 345 } 346 347 if (!pointShopOnly && isCustomStickersEnabled && !string.IsNullOrEmpty(customStickerValue)) { 348 Sticker customSticker = new Sticker(); 349 customSticker.className = "stickers-container__tag--custom"; 350 customSticker.text = customStickerValue; 351 string customStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ? 352 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft"; 353 AddSticker(resultList, customSticker, customStickerPosition); 354 } 355 if (!string.IsNullOrWhiteSpace(groupName)) { 356 Sticker groupSticker = new Sticker(); 357 groupSticker.className = "stickers-container__tag--group"; 358 groupSticker.text = groupName; 359 if (!string.IsNullOrWhiteSpace(newGroupColor)) { 360 groupSticker.className += " " + newGroupColor; 361 } 362 363 //følger bare custom sticker pos. kan evt. udvides efter behov. 364 string groupStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ? 365 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft"; 366 AddSticker(resultList, groupSticker, groupStickerPosition); 367 368 } 369 370 return resultList; 371 } 372 } 373 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 374 375 376 @* 377 This is a temporary fallback for the DefaultImage. The image pattern MUST be set up like this: 378 379 ImageSmall = /{ProductNumber}.jpg 380 ImageMedium = /{ProductNumber}{VariantOptionLevel1}.jpg 381 ImageLarge = /{ProductNumber}{VariantComboName}.jpg 382 383 In addition to the ImageDefault setting 384 *@ 385 386 @functions { 387 public string GetProductImage(LoopItem productObject = null) 388 { 389 string theImage = ""; 390 391 if (productObject == null) { 392 theImage = GetString("Ecom:Product.ImageDefault.Default.Clean"); 393 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Clean") : theImage; 394 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageMedium.Clean") : theImage; 395 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageSmall.Clean") : theImage; 396 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage; 397 } else { 398 theImage = productObject.GetString("Ecom:Product.ImageDefault.Default.Clean"); 399 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Clean") : theImage; 400 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageMedium.Clean") : theImage; 401 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageSmall.Clean") : theImage; 402 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage; 403 } 404 405 return theImage; 406 } 407 } 408 409 @functions { 410 BlocksPage mainImagePage = BlocksPage.GetBlockPage("Product"); 411 bool showThumbs; 412 bool thumbsOnTheSide; 413 } 414 415 @{ 416 string imageBlockWidth = Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout").SelectedValue : "6"; 417 string blocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info"; 418 bool infoOnTheRight = blocksPosition.LastIndexOf("info") == blocksPosition.Length - 4; 419 showThumbs = blocksPosition.IndexOf("thumbs") != -1; 420 thumbsOnTheSide = showThumbs && blocksPosition.IndexOf("thumbsBottom") == -1; 421 bool thumbsOnTheLeft = blocksPosition.IndexOf("image") > blocksPosition.IndexOf("thumbs"); 422 //imageBlockWidth = imageBlockPosition == "left-left" || imageBlockPosition == "left-right" ? Converter.ToString(12 - Converter.ToInt32(imageBlockWidth)) : imageBlockWidth; 423 424 Block mainImageBlock = new Block() 425 { 426 Id = "MainImage", 427 SortId = infoOnTheRight ? 10 : 20, 428 Design = new Design 429 { 430 Size = imageBlockWidth, 431 RenderType = RenderType.Column 432 }, 433 BlocksList = new List<Block> 434 { 435 new Block { 436 Id = "MainImageRow", 437 SortId = 10, 438 Design = new Design 439 { 440 RenderType = RenderType.Row 441 }, 442 BlocksList = new List<Block> 443 { 444 new Block 445 { 446 Id = "Carousel", 447 SortId = 10, 448 Template = RenderThumbnails(), 449 Design = new Design 450 { 451 Size = thumbsOnTheSide ? "2" : "12", 452 RenderType = RenderType.Column, 453 CssClass = thumbsOnTheSide ? "u-hidden-xxs" : "" 454 } 455 } 456 } 457 } 458 } 459 }; 460 mainImagePage.Add("Top", mainImageBlock); 461 462 mainImagePage.Add("MainImageRow", 463 new Block() 464 { 465 Id = "ProductImageModal", 466 SortId = 0, 467 Template = RenderModal() 468 }); 469 470 if (showThumbs) 471 { 472 mainImagePage.Add("MainImageRow", 473 new Block 474 { 475 Id = "Image", 476 SortId = thumbsOnTheLeft ? 20 : 0, 477 Template = RenderImage(), 478 Design = new Design 479 { 480 Size = thumbsOnTheSide ? "auto" : "12", 481 RenderType = RenderType.Column 482 } 483 }); 484 } 485 } 486 487 @helper RenderModal() 488 { 489 <!-- Trigger for the gallery modal --> 490 <input type="checkbox" id="GalleryModalTrigger" class="modal-trigger" /> 491 492 if (!string.IsNullOrEmpty(GetString("Ecom:Product.ImageLarge.Default.Clean"))) 493 { 494 <!-- Gallery modal --> 495 <div class="modal-container"> 496 <label for="GalleryModalTrigger" id="GalleryModalOverlay" class="modal-overlay"></label> 497 <div class="modal" id="GalleryModal"> 498 <div class="modal__body modal__body--full"> 499 @RenderCarousel("modalCarousel", 1, "horizontal", 3, true) 500 <label class="modal__close-btn dw-mod" for="GalleryModalTrigger"></label> 501 </div> 502 </div> 503 </div> 504 } 505 } 506 507 @helper RenderStickers() 508 { 509 var primaryProductGroup = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); 510 string groupColor = "" + primaryProductGroup.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value; 511 bool isVariant = !string.IsNullOrWhiteSpace(GetString("Ecom:Product.VariantID")); 512 513 if (isVariant) 514 { 515 foreach (var i in Dynamicweb.Ecommerce.Products.Group.GetGroupsByProduct(Dynamicweb.Ecommerce.Products.Product.GetProductById(GetString("Ecom:Product.ID")))) 516 { 517 groupColor += i.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value; 518 } 519 } 520 List<StickersContainer> StickersContainers = GetStickersContainersList( 521 GetLoop("ProductDiscounts"), 522 GetDouble("Ecom:Product.Discount.Price.Price"), 523 GetDouble("Ecom:Product.Price.Price"), 524 GetDate("Ecom:Product.Created"), 525 GetString("Ecom:Product:Field.CustomSticker.Value"), 526 GetString("Ecom:Group.Name"), 527 groupColor 528 529 ); 530 531 @*foreach (StickersContainer stickersContainer in StickersContainers) 532 { 533 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod"> 534 @foreach (Sticker sticker in stickersContainer.Stickers) 535 { 536 <div class="stickers-container__tag @sticker.className dw-mod">@sticker.text</div> 537 } 538 </div> 539 }*@ 540 541 foreach (StickersContainer stickersContainer in StickersContainers) 542 { 543 string isImageClass = ""; 544 545 //if (!String.IsNullOrWhiteSpace(stickersContainer.Stickers(image))) 546 //{ 547 // isImageClass = "withImage"; 548 //} 549 550 bool anyWithImage = stickersContainer.Stickers.Any(x => String.IsNullOrWhiteSpace(x.image)); 551 if (anyWithImage) 552 { 553 isImageClass = "withImage"; 554 } 555 556 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod @(isImageClass)"> 557 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => String.IsNullOrWhiteSpace(x.image))) 558 { 559 <div class="stickers-container__tag @sticker.className dw-mod"> 560 @sticker.text 561 </div> 562 } 563 564 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => !String.IsNullOrWhiteSpace(x.image))) 565 { 566 <div class="stickers-container__tag @sticker.className dw-mod sticker-with-image"> 567 @sticker.image 568 </div> 569 } 570 </div> 571 } 572 } 573 574 @helper RenderImage() 575 { 576 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 577 string productId = GetString("Ecom:Product.ID"); 578 string image = GetProductImage(); 579 580 <label for="GalleryModalTrigger" class="product__image-container u-position-relative"> 581 <img class="product__image-container__image dw-mod b-lazy" src="/Files/Images/placeholder.gif" data-src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" id="Image_@productId" data-for="FullImage" data-number="0" onclick="modalCarousel.GoToSlide('modalCarousel', this.getAttribute('data-number'))" /> 582 @RenderStickers() 583 </label> 584 } 585 586 @helper RenderThumbnails() 587 { 588 <div class="@(showThumbs ? "product__thumbs" : "") dw-mod"> 589 @RenderCarousel( 590 "productCarousel", 591 !showThumbs ? 1 : 5, 592 thumbsOnTheSide ? "vertical" : "horizontal", 593 !showThumbs ? 3 : 2 594 ) 595 @if (!showThumbs) 596 { 597 @RenderStickers() 598 } 599 </div> 600 } 601 602 @helper RenderCarousel(string id, int slidesInView, string direction, int preloaderSize, bool isModal = false) 603 { 604 <div class="carousel dw-mod" id="@id"> 605 <div class="thumb-list carousel__container @(slidesInView != 1 ? "carousel__container--hidden" : "") js-carousel-slides dw-mod"> 606 @*Main image thumb*@ 607 @RenderProductImage(GetProductImage(), slidesInView == 1, isModal ? "modal--full__img" : "", true, isModal) 608 609 @foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 610 { 611 if (!string.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"))) 612 { 613 @RenderProductImage(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal) 614 } 615 } 616 617 @foreach (LoopItem detail in GetLoop("Details")) 618 { 619 if (!string.IsNullOrEmpty(detail.GetString("Ecom:Product:Detail.Image.Clean"))) 620 { 621 string ext = Path.GetExtension(detail.GetString("Ecom:Product:Detail.Image.Clean")).ToLower(); 622 if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png") 623 { 624 @RenderProductImage(detail.GetString("Ecom:Product:Detail.Image.Clean"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal) 625 } 626 } 627 } 628 </div> 629 630 <script> 631 document.addEventListener("DOMContentLoaded", function () { 632 @id = new CarouselModule('#@id', { 633 slidesInView: @slidesInView, 634 direction: "@direction", 635 preloaderSize: @preloaderSize, 636 showCounter: @isModal.ToString().ToLower() 637 }); 638 }); 639 </script> 640 </div> 641 } 642 643 @helper RenderProductImage(string image, bool isBig, string cssClass = "", bool isActive = false, bool isModal = false) 644 { 645 //Add product image to the og meta data 646 Pageview.Meta.AddTag("og:image", string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, GetProductImage())); 647 648 string productId = GetString("Ecom:Product.ID"); 649 string thumbPrefix = "/Admin/Public/GetImage.ashx?width=200&amp;height=200&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 650 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 651 652 <div class="carousel__slide dw-mod"> 653 @if (isModal) 654 { 655 <img src="@imagePrefix@image" class="@cssClass" alt="@GetString("Ecom:Product.Name")"> 656 } 657 else if (isBig) 658 { 659 <label for="GalleryModalTrigger"> 660 <img src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());"> 661 </label> 662 } 663 else 664 { 665 <div class="thumb-list__item dw-mod js-thumb js-gallery @(isActive ? "js-thumb--active thumb-list__item--active" : "")" data-for="Image_@productId" data-image="@imagePrefix@image" onmouseover="Gallery.openImage(this)"> 666 <label for="GalleryModalTrigger"> 667 <img src="@thumbPrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@imagePrefix@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());"> 668 </label> 669 </div> 670 } 671 </div> 672 } 673 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 674 @using Dynamicweb.Core 675 @using System 676 @using System.Web 677 @using System.Collections.Generic 678 @using Dynamicweb.Rapido.Blocks 679 @functions { 680 bool useFacebookPixel; 681 bool useGoogleTagManager; 682 BlocksPage mainInfoPage = BlocksPage.GetBlockPage("Product"); 683 } 684 685 @{ 686 //ck ændrede fra 1 til 10 for at omgå problem med at få vist pris. Kan muligvis have forårsaget andet visnings gejl. 687 bool mainInfoRenderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 10 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 688 689 useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 690 useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 691 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice"); 692 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton"); 693 694 Block mainInfoHeader = new Block() 695 { 696 Id = "MainInfoHeader", 697 SortId = 21, 698 Template = RenderMainInfoHeader() 699 }; 700 mainInfoPage.Add("MainInformation", mainInfoHeader); 701 702 Block mainInfoDescription = new Block() 703 { 704 Id = "ShortDescription", 705 SortId = 30, 706 Template = RenderShortDescription() 707 }; 708 mainInfoPage.Add("MainInformation", mainInfoDescription); 709 710 if (!mainInfoRenderVariantsAsProducts) 711 { 712 Block mainInfoVariants = new Block() 713 { 714 Id = "Variants", 715 SortId = 50, 716 Template = RenderMainInfoVariants() 717 }; 718 mainInfoPage.Add("MainInformation", mainInfoVariants); 719 } 720 721 Block mainInfoBOM = new Block() 722 { 723 Id = "BOM", 724 SortId = 60, 725 Template = RenderMainInfoBOM() 726 }; 727 mainInfoPage.Add("MainInformation", mainInfoBOM); 728 729 if (!mainInfoRenderVariantsAsProducts) 730 { 731 if (!hidePrice && !hideAddToCartButton) 732 { 733 Block mainInfoBuy = new Block() 734 { 735 Id = "Buy", 736 SortId = 31, 737 Template = RenderMainInfoBuy() 738 }; 739 mainInfoPage.Add("MainInformation", mainInfoBuy); 740 } 741 742 Block stockAndShipping = new Block() 743 { 744 Id = "StockAndShipping", 745 SortId = 90, 746 Template = RenderStockAndShipping() 747 }; 748 mainInfoPage.Add("MainInformation", stockAndShipping); 749 } 750 } 751 752 @helper RenderMainInfoHeader() 753 { 754 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 755 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 756 string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted"); 757 // bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 758 bool hideProductNumber = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumber"); 759 760 bool useFontAwesomePro = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetBoolean("UseFontAwesomePro"); 761 // var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 762 //string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 763 // string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 764 765 //fix for displaying variant name - don't remove next line! 766 GetLoop("VariantCombinations"); 767 768 string helsamLink = "http://www.helsam.dk/_cart.asp?action=add&ProductEAN=" + GetString("Ecom:Product.ID.UrlEncoded") + "&quantity=1"; 769 string helsebixLink = "http://www.helsebixen.dk/shop/easyshopping/index/updatecart/?e_sku=" + GetString("Ecom:Product.ID.UrlEncoded") + "&e_qty=1"; 770 771 bool b2cUser = false; 772 if (Pageview.User != null) 773 { 774 b2cUser = Pageview.User.GroupsIds.Contains(7913); 775 776 } 777 else 778 { 779 b2cUser = true; 780 } 781 782 <div> 783 @if (!b2cUser) { 784 var findDealer = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "finddealer"); 785 786 if (Pageview.User == null || !Pageview.User.GroupsIds.Contains(91)) { 787 string discernibleHelsam = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsam"); 788 string discernibleHelsebixen = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsebixen"); 789 <div class="product_direct_sale"> 790 @*<div class="find-shop-img"> 791 <a href="@helsamLink" target="_blank" title="helsam - @Translate("Buy here")" class="" aria-label="@discernibleHelsam"> 792 <img src="/Files/Images/Graphics/helsam.png" class="" alt="helsam" /> 793 </a> 794 <a href="@helsebixLink" target="_blank" title="helsebixen.dk - @Translate("Buy here")" class="" aria-label="@discernibleHelsebixen"> 795 <img src="/Files/Images/Graphics/helsebixen.png" class="" alt="helse bixen" /> 796 </a> 797 </div>*@ 798 @if (findDealer != null) { 799 string link = "/Default.aspx?ID=" + findDealer.ID; 800 801 <div class="find-shop-link"> 802 <a href="@link" title="@Translate("Find shop")" class="btn btn--secondary dw-mod"> 803 <i class="fal fa-map-signs"></i> 804 @Translate("Find shop") 805 </a> 806 807 808 809 810 811 812 @* ------------------------------------------------------------ *@ 813 814 @* ------------------------------------------------------------ *@ 815 </div> 816 } 817 818 </div> 819 } 820 } 821 822 <div class="u-pull--left product__title dw-mod"> 823 824 <h1 class="u-no-margin">@GetString("Ecom:Product.Name") </h1> 825 826 @*@if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.SelectedVariantComboName"))) { 827 <h2>@GetString("Ecom:Product.SelectedVariantComboName")</h2> 828 }*@ 829 830 @*@if (!hideProductNumber && Pageview.User != null) { 831 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.Number"))) { 832 <div class="item-number dw-mod">@Translate("Product number"): @GetString("Ecom:Product.Number")</div> 833 } 834 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.EAN"))) { 835 <div class="item-number item-ean-number dw-mod">@Translate("EAN"): @GetString("Ecom:Product:Field.EAN")</div> 836 } 837 }*@ 838 839 @* -- -- -- -- *@ 840 <div class="item-number dw-mod"> 841 <div class="item-number dw-mod"> 842 843 @if (!hideProductNumber) { 844 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.Number"))) { 845 <span class="item-number dw-mod">@Translate("Product number"): @GetString("Ecom:Product.Number")</span> 846 } 847 848 if (Pageview.User != null && Pageview.User.GroupsIds.Contains(91)) { 849 850 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.EAN"))) { 851 <span class="item-number item-ean-number dw-mod">| @Translate("EAN"): @GetString("Ecom:Product:Field.EAN")</span> 852 } 853 } 854 } 855 </div> 856 857 </div> 858 </div> 859 860 @{ 861 bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 862 // bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 863 864 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 865 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 866 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 867 } 868 <div class="u-pull--right"> 869 @*@if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) {*@ 870 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) { 871 872 string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); 873 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod"> 874 <div> 875 @{ 876 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon; 877 string AddToWishlist = "fbq('track', 'AddToWishlist', {" + 878 "content_name: '" + GetString("Ecom:Product.Name") + "'," + 879 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," + 880 "value: " + GetDouble("Ecom:Product.Price.Price") + "," + 881 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" + 882 "});"; 883 } 884 <label for="FavoriteTrigger"><i class="@favorite fa-1_5x"></i></label> 885 </div> 886 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" /> 887 888 <div class="dropdown"> 889 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 890 <ul class="list list--clean dw-mod"> 891 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) { 892 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) { 893 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) { 894 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction"); 895 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon; 896 string listElementName = list.GetString("Ecom:CustomerCenter.List.Name") == "My favorites" ? Translate("My favorites") : list.GetString("Ecom:CustomerCenter.List.Name"); 897 <li> 898 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @listElementName</a> 899 </li> 900 } 901 } 902 } else { 903 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites"); 904 string isInListIcon = favoriteOutlineIcon; 905 <li> 906 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a> 907 </li> 908 } 909 </ul> 910 </div> 911 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> 912 </div> 913 </div> 914 } 915 </div> 916 </div> 917 } 918 919 @helper RenderStockAndShipping() 920 { 921 bool hideStockState = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideStockState"); 922 bool hideDelivery = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideShipping"); 923 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 924 925 if (!onlyPreview && (!string.IsNullOrEmpty(GetString("Ecom:Product:Stock.Text")) || !string.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")))) 926 { 927 string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "stock-icon--in" : "stock-icon--not"; 928 929 <div class="product__stock-delivery dw-mod"> 930 @if (!hideStockState) 931 { 932 @GetString("Ecom:Product:Stock.Text") <div class="stock-icon @stockIcon"></div> 933 } 934 935 @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")) && !hideDelivery) 936 { 937 <span>@Translate("Shipping")</span> <span>@GetString("Ecom:Product:Stock.DeliveryText")</span> <span>@GetString("Ecom:Product:Stock.DeliveryUnit")</span> 938 } 939 </div> 940 } 941 } 942 943 @helper RenderShortDescription() 944 { 945 var livsstilOptions = GetLoop("Livsstil.Options").Where(x => x.GetBoolean("Livsstil.Option.IsSelected")); 946 947 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.ShortDescription"))) 948 { 949 Pageview.Meta.AddTag("og:description", GetString("Ecom:Product.ShortDescription").Replace("<p>", "").Replace("</p>", "").Trim()); 950 <div class="introduction-text"> 951 @GetString("Ecom:Product.ShortDescription") 952 </div> 953 } 954 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Salgsfeatures"))) 955 { 956 <p>@GetString("Ecom:Product:Field.Salgsfeatures")</p> 957 } 958 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anvendelse"))) 959 { 960 961 <p><strong>@Translate(GetString("Ecom:Product:Field.Anvendelse.Name")):. </strong> @GetString("Ecom:Product:Field.Anvendelse")</p> 962 } 963 964 if (livsstilOptions.Any()) 965 { 966 <ul class="lifestyle-icons"> 967 @foreach (var i in livsstilOptions) 968 { 969 string iconSrc = "/Files/Images/Graphics/Icons/Lifestyle/" + i.GetString("Livsstil.Option.Value") + ".png"; 970 string iconName = Translate(i.GetString("Livsstil.Option.Name")); 971 <li> 972 <img src="@iconSrc" title="@iconName" alt="@iconName" class="" /> 973 </li> 974 } 975 </ul> 976 } 977 978 } 979 980 @helper RenderMainInfoVariants() 981 { 982 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 983 string productId = GetString("Ecom:Product.ID"); 984 string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : ""; 985 string hideHelpText = ""; 986 987 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 988 { 989 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) 990 { 991 if (variantoption.GetBoolean("Ecom:VariantOption.Selected")) 992 { 993 hideHelpText = "u-hidden"; 994 } 995 } 996 } 997 998 if (GetLoop("VariantGroups").Count > 0) 999 { 1000 var variantCombinationsObject = new List<Array>(); 1001 foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) 1002 { 1003 string[] combinations = variantcomb.GetString("Ecom:VariantStockCombination.VariantID").Split('.'); 1004 variantCombinationsObject.Add(combinations); 1005 } 1006 1007 string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'"); 1008 1009 var variantGroupsObject = new List<List<String>>(); 1010 foreach (LoopItem variantGroup in GetLoop("VariantGroups")) 1011 { 1012 var variantsObject = new List<String>(); 1013 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) 1014 { 1015 variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID")); 1016 } 1017 variantGroupsObject.Add(variantsObject); 1018 } 1019 string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'"); 1020 string productGroupId = HttpContext.Current.Request["GroupId"]; 1021 <div> 1022 <div class="js-variants" data-total-variant-groups="@GetLoop("VariantGroups").Count" data-combinations="@combinationsJson" data-variants="@variantsJson" data-variant-selections="@variantSelection" data-selection-complete="UpdatePage" data-page-id="@pageId" data-product-id="@productId" data-group-id="@productGroupId"> 1023 @foreach (LoopItem variantGroup in GetLoop("VariantGroups")) 1024 { 1025 string groupId = variantGroup.GetString("Ecom:VariantGroup.ID"); 1026 1027 <div> 1028 <div class="product__variant-group-name u-bold dw-mod">@variantGroup.GetString("Ecom:VariantGroup.Name")</div> 1029 <div class="u-margin-top"> 1030 @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) 1031 { 1032 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; 1033 string color = !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Colorcode")) ? variantOption.GetString("Ecom:VariantOption.Colorcode") : null; 1034 color = color == null && !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Color")) ? variantOption.GetString("Ecom:VariantOption.Color") : color; 1035 1036 if (!string.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean"))) 1037 { 1038 string variantImage = "/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/" + variantOption.GetString("Ecom: VariantOption.ImgSmall.Clean"); 1039 <img data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" src="@variantImage" onclick="MatchVariants.SelectThis(event)" alt="@variantOption.GetString("Ecom:VariantOption.Name")" title="@variantOption.GetString("Ecom:VariantOption.Name")" class="btn btn--tag @selected js-variant-option" data-check="@selected" /> 1040 } 1041 else if (!String.IsNullOrEmpty(color)) 1042 { 1043 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--colorbox u-margin-right @selected js-variant-option" data-check="@selected" style="background-color: @color"></button> 1044 } 1045 else 1046 { 1047 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag @selected js-variant-option" data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</button> 1048 } 1049 } 1050 </div> 1051 </div> 1052 } 1053 </div> 1054 <small class="js-help-text help-text @hideHelpText">@Translate("Please select variant!")</small> 1055 </div> 1056 } 1057 } 1058 1059 @helper RenderMainInfoBOM() 1060 { 1061 if (GetLoop("BOMProducts").Count > 0) 1062 { 1063 <h2 class="section-title">@Translate("Including products")</h2> 1064 foreach (LoopItem BOMProductItem in GetLoop("BOMProducts")) 1065 { 1066 string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : ""); 1067 <div class="grid__col--border grid"> 1068 <div class="grid__cell grid__cell--align-middle-left"> 1069 <a href="@link" class="u-pull--left u-margin-right"> 1070 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=50&image=@GetProductImage(BOMProductItem)&Compression=99" alt="@BOMProductItem.GetString("Ecom:Product.Name")" /> 1071 </a> 1072 <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a> 1073 </div> 1074 </div> 1075 } 1076 } 1077 } 1078 1079 @helper RenderMainInfoBuy() 1080 { 1081 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 1082 string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); 1083 string productId = GetString("Ecom:Product.ID"); 1084 string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; 1085 1086 string productIndicativePrice = GetString("Ecom:Product:Field.Vejledendepris"); 1087 1088 1089 <div class="product__price-actions js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div> 1090 <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" /> 1091 @RenderMainInfoBuyScripts() 1092 } 1093 1094 @helper RenderMainInfoBuyScripts() 1095 { 1096 1097 1098 /* Custom user level start*/ 1099 int userRank = 99; 1100 bool b2cUser = false; 1101 if (Pageview.User != null) 1102 { 1103 b2cUser = Pageview.User.GroupsIds.Contains(7913); 1104 for (int i = 1; i <= 3; i++) 1105 { 1106 if (Pageview.User.HasGroup(Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetInt32("EcomCustomerRank" + i))) 1107 { 1108 userRank = i; 1109 break; 1110 } 1111 } 1112 } 1113 /* Custom user level end*/ 1114 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice"); 1115 //Hiding cart options for lower user ranks 1116 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddTshowVATPriceoCartButton") || userRank > 2; 1117 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null || userRank > 2; 1118 string b2cSoldoutDisable = ""; 1119 if (Pageview.User == null) 1120 { 1121 b2cUser = true; 1122 } 1123 if (b2cUser) 1124 { 1125 hideAddToCartButton = false; 1126 1127 if (GetBoolean("Ecom:Product:Field.B2cCurrentlySoldout")) 1128 { 1129 b2cSoldoutDisable = "disabled"; 1130 } 1131 } 1132 1133 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 1134 string variantId = HttpContext.Current.Request.QueryString.Get("variantId") ?? ""; 1135 string feedId = GetGlobalValue("Global:Page.ID").ToString() + "&ProductID=" + GetString("Ecom:Product.ID") + "&VariantID=" + variantId + "&Feed=True&redirect=false"; 1136 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 1137 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT"); 1138 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 1139 1140 @* Handlebars templates *@ 1141 <script id="PricesAndActionsTemplate" type="text/x-template"> 1142 {{#.}} 1143 @if (!onlyPreview || b2cUser) 1144 { 1145 if (!hidePrice) 1146 { 1147 <div class="product__price-actions__price dw-mod u-margin-bottom--lg u-margin-top--lg"> 1148 @if (pointShopOnly) 1149 { 1150 <text> 1151 {{#if havePointPrice}} 1152 <div class="price price--product-page dw-mod">{{points}} @Translate("points")</div> 1153 {{else}} 1154 @Translate("Not available") 1155 {{/if}} 1156 </text> 1157 } 1158 else 1159 { 1160 1161 if (!b2cUser) 1162 { 1163 <div class="u-flex grid--wrap"> 1164 <div class="grid__col-md-6"></div> 1165 <div class="price price--product-page dw-mod">@Translate("Normal pris pr. stk.")</div> 1166 <div class="price price--product-page dw-mod" style="margin-left: auto">{{vejledendePris}}</div> 1167 </div> 1168 <div class="u-flex grid--wrap"> 1169 <div class="grid__col-md-6"></div> 1170 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Din pris pr. stk.")</div> 1171 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceFormatted}}</div> 1172 </div> 1173 } 1174 else 1175 { 1176 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 1177 <div class="u-flex grid--wrap"> 1178 <div class="grid__col-md-6"></div> 1179 @*<div class="price price--product-page dw-mod">Pris pr. stk.</div>*@ 1180 @*<div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}} @GetString("Ecom:Product.Currency.Code")</div>*@ 1181 <div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}}</div> 1182 </div> 1183 } 1184 1185 if (showVATPrice && false) 1186 { 1187 1188 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 1189 @if (isPricesWithVATEnabled) 1190 { 1191 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 1192 } 1193 else 1194 { 1195 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 1196 } 1197 </small> 1198 } 1199 } 1200 </div> 1201 } 1202 if (!hideAddToCartButton) 1203 { 1204 <div class="buttons-collection buttons-collection--right product__price-actions__actions dw-mod"> 1205 1206 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" /> 1207 <div class="dropdown u-w150px u-w80px--xs use-btn-primary-height dw-mod {{hasUnits}}"> 1208 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label> 1209 <div id="unitOptions" class="dropdown__content dw-mod"> 1210 {{#unitOptions}} 1211 {{>UnitOption}} 1212 {{/unitOptions}} 1213 </div> 1214 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label> 1215 </div> 1216 1217 @*<span class="package-size"> 1218 @Translate("Kollistørrelse"): @GetString("Ecom:Product:Field.Kollistoerrelse") 1219 </span>*@ 1220 1221 <input type="hidden" value="{{unitId}}" name="Unit" id="Unit_{{id}}" /> 1222 @if (pointShopOnly) 1223 { 1224 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints" 1225 onclick="Cart.AddToCart(event, { 1226 id: '{{productId}}', 1227 variantId: '{{variantid}}', 1228 unitId: '{{unitId}}', 1229 quantity: 1, 1230 buyForPoints: true, 1231 productInfo: {{productInfo}} 1232 }); {{facebookPixelAction}}"> 1233 <i class="@cartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span> 1234 </button> 1235 <text> 1236 {{#unless canBePurchasedWithPoints}} 1237 {{#if havePointPrice}} 1238 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small> 1239 {{/if}} 1240 {{/unless}} 1241 </text> 1242 } 1243 else 1244 { 1245 1246 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0"> 1247 <div class="grid__col-md-6"></div> 1248 @if (!b2cUser) 1249 { 1250 <div class="price price--product-page grid--align-self-center dw-mod" style="font-size: 16px"> 1251 {{#if packageSize}} 1252 @Translate("Kollistørrelse"): {{packageSize}} 1253 {{/if}} 1254 </div> 1255 } 1256 1257 <div style="margin-left: auto"> 1258 1259 1260 @if (!string.IsNullOrWhiteSpace(b2cSoldoutDisable)) 1261 { 1262 <button style="opacity:1 !important" disabled type="button" id="" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit"> 1263 <span>@Translate("Currently soldout")</span> 1264 @*<span class="u-hidden-xs u-hidden-xxs"> @Translate("Currently soldout")</span>*@ 1265 </button> 1266 } 1267 else 1268 { 1269 <input type="number" class="product__quantity-selector u-w70px use-btn-primary-height dw-mod" id="Quantity_{{id}}" name="Quantity" value="{{quantity}}" min="1" onchange="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&quantity=' + (+(this.value) <= 0 ? 1 : +(this.value)))" style="margin-bottom: 0"> 1270 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit" 1271 onclick="Cart.AddToCart(event, { 1272 id: '{{productId}}', 1273 variantId: '{{variantid}}', 1274 unitId: '{{unitId}}', 1275 quantity: document.getElementById('Quantity_{{id}}').value, 1276 productInfo: {{productInfo}} 1277 }); {{facebookPixelAction}}"> 1278 <i class="@cartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 1279 </button> 1280 } 1281 </div> 1282 </div> 1283 if (!b2cUser) 1284 { 1285 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0"> 1286 <div class="grid__col-md-6"></div> 1287 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Total")</div> 1288 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceTotalFormatted}}</div> 1289 </div> 1290 } 1291 1292 1293 @*bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 1294 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 1295 1296 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 1297 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 1298 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 1299 1300 <div class=""> 1301 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) { 1302 string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); 1303 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod"> 1304 <div> 1305 @{ 1306 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon; 1307 string AddToWishlist = "fbq('track', 'AddToWishlist', {" + 1308 "content_name: '" + GetString("Ecom:Product.Name") + "'," + 1309 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," + 1310 "value: " + GetDouble("Ecom:Product.Price.Price") + "," + 1311 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" + 1312 "});"; 1313 } 1314 <label for="FavoriteTrigger"><i class="@favorite"></i> @Translate("Add to favorites")</label> 1315 </div> 1316 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" /> 1317 1318 <div class="dropdown"> 1319 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 1320 <ul class="list list--clean dw-mod"> 1321 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) { 1322 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) { 1323 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) { 1324 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction"); 1325 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon; 1326 <li> 1327 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")</a> 1328 </li> 1329 } 1330 } 1331 } else { 1332 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites"); 1333 string isInListIcon = favoriteOutlineIcon; 1334 <li> 1335 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a> 1336 </li> 1337 } 1338 </ul> 1339 </div> 1340 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> 1341 </div> 1342 </div> 1343 } 1344 </div>*@ 1345 } 1346 </div> 1347 if (Pageview.User != null && !pointShopOnly && Dynamicweb.Security.Licensing.LicenseManager.LicenseHasFeature("LoyaltyPoints")) 1348 { 1349 <text> 1350 {{#if canBePurchasedWithPoints}} 1351 <form method="post" role="form" class="u-no-margin u-margin-top"> 1352 <input type="hidden" name="ProductID" value="{{id}}" /> 1353 <button type="submit" class="btn btn--loyalty-points u-no-margin dw-mod pull-right u-no-margin js-cart-btn {{disabledBuyButton}}" name="CartCmd" value="addWithPoints">@Translate("Buy for") {{points}} @Translate("points")</button> 1354 </form> 1355 {{/if}} 1356 </text> 1357 } 1358 } 1359 else 1360 { 1361 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 1362 } 1363 } 1364 else 1365 { 1366 <div class="product__price-actions__price dw-mod u-margin-bottom--lg"> 1367 @if (pointShopOnly) 1368 { 1369 // something. 1370 } 1371 else 1372 { 1373 @*<div class="before-price {{onSale}} dw-mod">{{discount}}</div>*@ 1374 1375 <div class="price price--product-page dw-mod"> 1376 {{#ifCond vejledendePrisDouble '>' 0}} 1377 @Translate("Vejl. pris"): @Translate("DKK") {{vejledendePris}} 1378 {{/ifCond}} 1379 </div> 1380 @*if(showVATPrice) { 1381 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 1382 @if(isPricesWithVATEnabled) { 1383 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 1384 } else { 1385 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 1386 } 1387 </small> 1388 }*@ 1389 } 1390 </div> 1391 } 1392 {{/.}} 1393 </script> 1394 1395 <script id="Units" type="text/x-template"> 1396 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&UnitID={{value}}')">{{{name}}}</div> 1397 </script> 1398 1399 <script id="UnitOption" type="text/x-template"> 1400 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{{name}}}</div> 1401 </script> 1402 1403 1404 <script> 1405 document.addEventListener("DOMContentLoaded", function () { 1406 if (document.getElementById("PriceAndActions")) { 1407 document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) { 1408 if (document.querySelector(".js-variants") != null) { 1409 MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing"); 1410 } 1411 }); 1412 } 1413 }); 1414 </script> 1415 } 1416 1417 @if (useGoogleTagManager) 1418 { 1419 var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); 1420 //var gtmPrice = (GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price")); 1421 var gtmPrice = GetDouble("Ecom:Product:Field.Vejledendepris.Value.Raw"); 1422 <script> 1423 // Measure a view of product details. This example assumes the detail view occurs on pageload, 1424 // and also tracks a standard pageview of the details page. 1425 1426 dataLayer.push({ 1427 "ecommerce": { 1428 "detail": { 1429 "actionField": {}, // 'detail' actions have an optional list property. 1430 "products": [{ 1431 "name": "@GetString("Ecom:Product.Name")", // Name or ID is required. 1432 "id": "@GetString("Ecom:Product.ID")", 1433 "price": "@gtmPrice", 1434 "brand": "@GetString("Ecom:Product:Field.brand.Value")", 1435 "category": "@(groupObject != null ? groupObject.Name : "")", 1436 "variant": "@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))" 1437 }] 1438 } 1439 } 1440 }); 1441 </script> 1442 } 1443 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1444 @using Dynamicweb.Core 1445 @using System 1446 @using System.Web 1447 @using System.Collections.Generic 1448 @using Dynamicweb.Rapido.Blocks 1449 @using System.Web.WebPages.Html 1450 1451 @functions { 1452 BlocksPage productSnippetsPage = BlocksPage.GetBlockPage("Product"); 1453 } 1454 1455 @{ 1456 Block googleProductSchema = new Block() 1457 { 1458 Id = "GoogleProductSchema", 1459 SortId = 10, 1460 Template = RenderGoogleProductSchema() 1461 }; 1462 1463 productSnippetsPage.Add("Snippets", googleProductSchema); 1464 } 1465 1466 @helper RenderGoogleProductSchema() 1467 { 1468 string brand = "Natur-Drogeriet"; 1469 string image = GetProductImage(); 1470 string siteUrl = HttpContext.Current.Request.Form["siteUrl"]; 1471 string hostDomain = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host; 1472 string productLink = GetString("Ecom:Product.Link.Clean"); 1473 string seoProductLink = hostDomain + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(productLink); 1474 string description = GetString("Ecom:Product.ShortDescription"); 1475 double fb_price = GetDouble("Ecom:Product.Discount.Price.PriceWithVAT"); 1476 string formattedPrice = fb_price.ToString(System.Globalization.CultureInfo.InvariantCulture); 1477 1478 string strippedDescription = System.Net.WebUtility.HtmlDecode(Dynamicweb.Core.Helpers.StringHelper.StripHtml(description)); 1479 1480 <script type="application/ld+json"> 1481 { 1482 "@@context": "http://schema.org/", 1483 "@@type": "Product", 1484 "name": "@GetString("Ecom:Product.Name")", 1485 @if (!string.IsNullOrEmpty(image)) 1486 { 1487 <text>"image": [ 1488 "@hostDomain@image" 1489 ],</text> 1490 } 1491 "description": "@strippedDescription", 1492 "sku": "@GetString("Ecom:Product.Number")", 1493 @if (!string.IsNullOrEmpty(brand)) 1494 { 1495 <text>"brand": { 1496 "@@type": "Brand", 1497 "name": "@brand" 1498 },</text> 1499 } 1500 "offers": { 1501 "@@type": "Offer", 1502 "url": "@seoProductLink", 1503 "priceCurrency": "@GetString("Ecom:Product.Price.Currency.Code")", 1504 "price": "@formattedPrice", 1505 "availability": "@(GetInteger("Ecom:Product.Stock") > 0 ? "InStock" : "InStock")" 1506 } 1507 } 1508 </script> 1509 } 1510 1511 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1512 @using Dynamicweb.Core 1513 @using System 1514 @using System.Web 1515 @using System.Collections.Generic 1516 @using Dynamicweb.Rapido.Blocks 1517 @functions { 1518 BlocksPage productAssetsPage = BlocksPage.GetBlockPage("Product"); 1519 } 1520 1521 @{ 1522 string productAssetsLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductAssetsLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue : "Section"; 1523 productAssetsLayout = productAssetsLayout == "Ribbon" ? "Section" : productAssetsLayout; 1524 1525 if (productAssetsLayout != "hide") 1526 { 1527 Block productAssetsBlock = new Block() 1528 { 1529 Name = productAssetsLayout != "MainInformation" ? Translate("Product assets") : "", 1530 Id = "ProductAssets", 1531 SortId = 10, 1532 @*downloadDocuments variable, declared in Product.cshtml and defined in Fields.cshtml*@ 1533 Template = RenderProductAssets(productAssetsLayout, downloadDocuments), 1534 Design = new Design 1535 { 1536 Size = "12", 1537 RenderType = RenderType.Column, 1538 HidePadding = true 1539 } 1540 }; 1541 productAssetsPage.Add(productAssetsLayout, productAssetsBlock); 1542 } 1543 } 1544 1545 @helper RenderProductAssets(string layout, List<LoopItem> documents) 1546 { 1547 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1548 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; 1549 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 1550 1551 //images 1552 1553 HashSet<string> images = new HashSet<string>(); 1554 1555 images.Add(GetProductImage()); 1556 1557 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 1558 { 1559 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 1560 1561 if (!string.IsNullOrEmpty(alt_image)) 1562 { 1563 images.Add(alt_image); 1564 } 1565 } 1566 1567 foreach (LoopItem detail in GetLoop("Details")) 1568 { 1569 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean"); 1570 1571 if (!string.IsNullOrEmpty(detail_image)) 1572 { 1573 images.Add(detail_image); 1574 } 1575 } 1576 1577 <div class="product__section @ribbonClasses dw-mod"> 1578 <div class="product__description center-container @ribbonSubClasses dw-mod"> 1579 @if (layout == "Section") 1580 { 1581 <h2>@Translate("Product assets")</h2> 1582 } 1583 1584 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")" method="post" class="u-flex grid--direction-column u-no-margin"> 1585 <div class="grid"> 1586 @if (images.Count > 0) 1587 { 1588 <div class="grid__col-md-4"> 1589 <div class="u-margin-bottom"> 1590 <input type="checkbox" class="u-no-margin form__control" id="allImages" onchange="selectAll(this)" /> 1591 <label for="allImages" class="u-bold u-inline-block">@Translate("Images") (@(images.Count))</label> 1592 </div> 1593 1594 <ul class="panel-list"> 1595 @foreach (string image in images) 1596 { 1597 @RenderPanelListItem(image) 1598 } 1599 </ul> 1600 </div> 1601 } 1602 1603 @if (documents.Count > 0) 1604 { 1605 <div class="grid__col-md-4"> 1606 <div class="u-margin-bottom"> 1607 <input type="checkbox" class="u-no-margin form__control" id="allDocuments" onchange="selectAll(this)" /> 1608 <label for="allDocuments" class="u-bold u-inline-block">@Translate("Documents") (@documents.Count)</label> 1609 </div> 1610 1611 <ul class="panel-list"> 1612 @foreach (LoopItem document in documents) 1613 { 1614 string fieldValue; 1615 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 1616 { 1617 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 1618 @RenderDocument(fieldValue) 1619 } 1620 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1621 { 1622 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 1623 @RenderDocument(fieldValue) 1624 } 1625 } 1626 </ul> 1627 </div> 1628 } 1629 <div class="grid__col-md-4"> 1630 <input id="ID" name="ID" type="hidden" value="532" /> 1631 <input id="download" name="download" type="hidden" value="true" /> 1632 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" /> 1633 1634 <div class="u-bold u-margin-bottom">@Translate("Export")</div> 1635 1636 <label for="exportLanguage">@Translate("Language")</label> 1637 <select id="exportLanguage" name="RequestLanguageId" class="u-full-width"> 1638 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 1639 { 1640 var selected = lang.IsDefault ? "selected" : ""; 1641 <option value="@lang.LanguageId" @selected>@lang.Name</option> 1642 } 1643 </select> 1644 1645 <label for="purpose">@Translate("Image purpose")</label> 1646 <select id="purpose" name="purpose" class="u-full-width"> 1647 <option value="Office">@Translate("Office")</option> 1648 <option value="Original">@Translate("Original")</option> 1649 <option value="Print">@Translate("Print")</option> 1650 <option value="Web">@Translate("Web")</option> 1651 </select> 1652 1653 <label for="exportFormat">@Translate("Export format")</label> 1654 <select id="exportFormat" name="format" class="u-full-width"> 1655 <option value="csv">Csv</option> 1656 <option value="json">Json</option> 1657 <option value="xml">Xml</option> 1658 </select> 1659 1660 <input type="submit" value="@Translate("Download")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Download")" /> 1661 </div> 1662 </div> 1663 </form> 1664 </div> 1665 </div> 1666 <script> 1667 function selectAll(checkbox) { 1668 Array.prototype.slice.call(checkbox.parentElement.nextElementSibling.getElementsByTagName('input')).forEach(function (input) { 1669 input.checked = checkbox.checked; 1670 }); 1671 } 1672 </script> 1673 } 1674 1675 @helper RenderPanelListItem(string imageName) 1676 { 1677 <li class="panel-list__item"> 1678 <div class="panel-list__item-check"> 1679 <input type="checkbox" name="Image_@imageName" class="u-no-margin form__control" id="Image_@imageName" /> 1680 <label for="Image_@imageName"></label> 1681 </div> 1682 <div class="panel-list__item-image"> 1683 <label for="Image_@imageName"> 1684 <img class="b-lazy flex-img" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=55&amp;height=55&amp;crop=5&amp;FillCanvas=True&amp;Compression=75&amp;image=@imageName" alt="@Path.GetFileName(imageName)"> 1685 </label> 1686 </div> 1687 <div class="panel-list__item-name"> 1688 <label for="Image_@imageName" class="u-truncate-text u-w170px"> 1689 @Path.GetFileName(imageName) 1690 </label> 1691 </div> 1692 </li> 1693 } 1694 1695 @helper RenderDocument(string fieldValue) 1696 { 1697 <li class="panel-list__item"> 1698 <div class="panel-list__item-check"> 1699 <input type="checkbox" name="Document_@fieldValue" class="u-no-margin form__control" id="Document_@fieldValue" /> 1700 <label for="Document_@fieldValue"></label> 1701 </div> 1702 <div class="panel-list__item-name"> 1703 <label for="Document_@fieldValue" class="u-truncate-text u-max-w220px"> 1704 @Path.GetFileName(fieldValue) 1705 </label> 1706 </div> 1707 </li> 1708 } 1709 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1710 @using Dynamicweb.Core 1711 @using System 1712 @using System.Web 1713 @using System.Collections.Generic 1714 @using Dynamicweb.Rapido.Blocks 1715 1716 @functions { 1717 BlocksPage productGeneratePDFPage = BlocksPage.GetBlockPage("Product"); 1718 } 1719 1720 @{ 1721 string generatePDFLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("GeneratePDFLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue : "Section"; 1722 generatePDFLayout = generatePDFLayout == "Ribbon" ? "Section" : generatePDFLayout; 1723 1724 if (GetPageIdByNavigationTag("PdfFolder") > 0 && generatePDFLayout != "hide") 1725 { 1726 Block generatePDFBlock = new Block() 1727 { 1728 Name = generatePDFLayout != "MainInformation" ? Translate("Generate PDF") : "", 1729 Id = "GeneratePDF", 1730 SortId = 10, 1731 Template = RenderGeneratePDFSection(generatePDFLayout), 1732 Design = new Design 1733 { 1734 Size = "12", 1735 RenderType = RenderType.Column, 1736 HidePadding = true 1737 } 1738 }; 1739 1740 productGeneratePDFPage.Add(generatePDFLayout, generatePDFBlock); 1741 } 1742 } 1743 1744 @helper RenderGeneratePDFSection(string layout) 1745 { 1746 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1747 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 1748 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 1749 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 1750 int pdfFolderId = GetPageIdByNavigationTag("PdfFolder"); 1751 1752 <div class="product__section @ribbonClasses grid dw-mod"> 1753 <div class="dw-mod grid__col-md-4 @ribbonSubClasses"> 1754 @if (layout == "Section") { 1755 <h2>@Translate("Generate PDF")</h2> 1756 } 1757 1758 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")&GeneratePdf=true" method="post" class="u-no-margin"> 1759 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" /> 1760 1761 <label for="PdfLanguageId">@Translate("Language")</label> 1762 <select id="PdfLanguageId" name="PdfLanguageId" class="u-full-width"> 1763 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 1764 { 1765 var selected = lang.IsDefault ? "selected" : ""; 1766 <option value="@lang.LanguageId" @selected>@lang.Name</option> 1767 } 1768 </select> 1769 <label for="PdfPageId">@Translate("Generate PDF")</label> 1770 <select id="PdfPageId" name="PdfPageId" class="u-full-width"> 1771 <option value="" selected>@Translate("Select type")</option> 1772 @foreach (Dynamicweb.Content.Page page in ServiceLocator.Current.GetPageService().GetPagesByParentID(pdfFolderId)) 1773 { 1774 <option value="@page.ID">@page.MenuText</option> 1775 } 1776 </select> 1777 1778 <input type="submit" value="@Translate("Generate PDF")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Generate PDF")" /> 1779 </form> 1780 </div> 1781 </div> 1782 } 1783 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1784 @using Dynamicweb.Core 1785 @using System 1786 @using System.Web 1787 @using System.Collections.Generic 1788 @using Dynamicweb.Rapido.Blocks 1789 1790 @functions { 1791 BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product"); 1792 } 1793 1794 @{ 1795 string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section"; 1796 fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout; 1797 1798 if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide") { 1799 Block detailsDescription = new Block() { 1800 Name = fullDesctiptionLayout != "MainInformation" ? Translate("Detailed description") : "", 1801 Id = "FullDescription", 1802 SortId = 10, 1803 Template = RenderProductDescription(fullDesctiptionLayout), 1804 Design = new Design { 1805 Size = "12", 1806 RenderType = RenderType.Column, 1807 HidePadding = true 1808 } 1809 }; 1810 productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription); 1811 } 1812 1813 } 1814 1815 @helper RenderProductDescription(string layout) { 1816 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1817 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 1818 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 1819 1820 bool b2cUser = false; 1821 if (Pageview.User != null) { 1822 b2cUser = Pageview.User.GroupsIds.Contains(7913); 1823 1824 } else { 1825 b2cUser = true; 1826 } 1827 1828 <div class="product__section @ribbonClasses dw-mod"> 1829 <div class="product__description center-container @ribbonSubClasses dw-mod"> 1830 @if (layout == "Section") { 1831 <h2>@Translate("Description")</h2> 1832 } 1833 @GetString("Ecom:Product.LongDescription") 1834 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Kollistoerrelse")) && !b2cUser) { 1835 <p class="color-gray">@Translate(GetString("Ecom:Product:Field.Kollistoerrelse.Name")): @GetString("Ecom:Product:Field.Kollistoerrelse")</p> 1836 } 1837 1838 </div> 1839 </div> 1840 } 1841 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1842 @using Dynamicweb.Core 1843 @using System 1844 @using System.Web 1845 @using System.Globalization; 1846 @using System.Collections.Generic 1847 @using Dynamicweb.Rapido.Blocks 1848 1849 @functions { 1850 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product"); 1851 1852 static string ConvertBytes(long bytes) 1853 { 1854 double size = bytes / 1024; //KB 1855 if (size > 1024) 1856 { 1857 size = (bytes / 1024f) / 1024f; //MB 1858 return string.Format("{0:n1} MB", size); 1859 } 1860 else 1861 { 1862 return string.Format("{0:n0} KB", size); 1863 } 1864 } 1865 1866 static bool isImage(string path) 1867 { 1868 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower()); 1869 } 1870 1871 string getIconForFile(string fileName) 1872 { 1873 string ext = Path.GetExtension(fileName); 1874 string icon = ""; 1875 switch (ext.ToLower()) 1876 { 1877 case ".xls": 1878 case ".xlsx": 1879 icon = "fa-file-excel"; 1880 break; 1881 case ".ppt": 1882 case ".pptx": 1883 icon = "fa-file-powerpoint"; 1884 break; 1885 case ".doc": 1886 case ".docx": 1887 icon = "fa-file-word"; 1888 break; 1889 case ".jpg": 1890 case ".jpeg": 1891 case ".png": 1892 case ".gif": 1893 case ".pdf": 1894 return "<img class='product__document-img' alt='" + fileName + "' src='/Admin/Public/GetImage.ashx?crop=5&height=70&width=120&Compression=75&DoNotUpscale=true&image=" + fileName + "' />"; 1895 default: 1896 icon = "fa-file"; 1897 break; 1898 } 1899 return "<i class='product__document-icon far " + icon + "'></i> "; 1900 } 1901 } 1902 1903 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@ 1904 1905 @{ 1906 foreach (LoopItem customField in GetLoop("CustomFieldValues")) 1907 { 1908 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "Custom sticker") 1909 { 1910 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 1911 { 1912 downloadDocuments.Add(customField); 1913 } 1914 } 1915 } 1916 1917 foreach (LoopItem customField in GetLoop("ProductCategories")) 1918 { 1919 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields")) 1920 { 1921 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value"))) 1922 { 1923 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1924 { 1925 downloadDocuments.Add(field); 1926 } 1927 } 1928 } 1929 } 1930 1931 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 1932 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section"; 1933 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout; 1934 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section"; 1935 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout; 1936 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section"; 1937 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout; 1938 1939 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid"; 1940 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid"; 1941 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid"; 1942 1943 //Fjern && false for at få vist detajle fanen 1944 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide" && false) 1945 { 1946 Block detailsCustom = new Block() 1947 { 1948 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "", 1949 Id = "CustomFields", 1950 SortId = 30, 1951 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView)), 1952 Design = new Design 1953 { 1954 Size = "12", 1955 RenderType = RenderType.Column, 1956 HidePadding = true 1957 } 1958 }; 1959 1960 productFieldsPage.Add(detailFieldsLayout, detailsCustom); 1961 } 1962 1963 if (categoryFieldsLayout != "hide") 1964 { 1965 foreach (LoopItem categoryGroup in GetLoop("ProductCategories")) 1966 { 1967 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null; 1968 1969 if (collectAllDownloads) { 1970 int downloadableCount = 0; 1971 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields")) 1972 { 1973 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1974 { 1975 downloadableCount++; 1976 } 1977 } 1978 1979 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count) { 1980 hasFields = false; 1981 } 1982 } 1983 1984 if (hasFields) 1985 { 1986 Block detailsCategoryFields = new Block() 1987 { 1988 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "", 1989 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")), 1990 SortId = 40, 1991 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)), 1992 Design = new Design 1993 { 1994 Size = "12", 1995 RenderType = RenderType.Column, 1996 HidePadding = true 1997 } 1998 }; 1999 2000 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields); 2001 } 2002 } 2003 } 2004 2005 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true) 2006 { 2007 Block detailsDownloads = new Block() 2008 { 2009 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "", 2010 Id = "StandardDownloads", 2011 SortId = 50, 2012 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)), 2013 Design = new Design 2014 { 2015 Size = "12", 2016 RenderType = RenderType.Column, 2017 HidePadding = true 2018 } 2019 }; 2020 2021 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads); 2022 } 2023 } 2024 2025 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType) 2026 { 2027 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 2028 2029 foreach (LoopItem customField in fieldsLoop) 2030 { 2031 string customSystemField = customField.GetString("Product.CustomField.System"); 2032 if( customSystemField == "Indholddagsdosis" || 2033 customSystemField == "Kollistoerrelse" || 2034 customSystemField == "Anprisninger" || 2035 customSystemField == "Pligttekst" || 2036 customSystemField == "Anvendelse" || 2037 customSystemField == "Salgsfeatures" || 2038 customSystemField == "Livsstil" || 2039 customSystemField == "Ingredienser" || 2040 customSystemField == "Naeringsindhold" || 2041 customSystemField == "Indeholder" || 2042 customSystemField == "EAN" || 2043 customSystemField == "Vejledendepris") { 2044 continue; 2045 } 2046 string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); 2047 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 2048 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 2049 2050 if (customField.GetLoop("Product.CustomField.Options").Count > 0) 2051 { 2052 fieldValue = customField.GetString("Product.CustomField.Label"); 2053 } 2054 2055 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker") 2056 { 2057 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath")) && collectAllDownloads == false) 2058 { 2059 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType); 2060 } 2061 else if (collectAllDownloads == false) 2062 { 2063 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download"); 2064 } 2065 } 2066 } 2067 } 2068 2069 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer) { 2070 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2071 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2072 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : ""; 2073 2074 <div class="product__section @ribbonClasses dw-mod"> 2075 <div class="center-container @ribbonSubClasses dw-mod"> 2076 @if (layout == "Section") 2077 { 2078 <h2>@name</h2> 2079 } 2080 2081 @if (viewType != "table") 2082 { 2083 <div class="grid grid--bleed u-margin-bottom--lg"> 2084 @writer 2085 </div> 2086 } 2087 else 2088 { 2089 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; 2090 2091 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2092 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> 2093 <table class="table--no-top-border"> 2094 @writer 2095 </table> 2096 </div> 2097 </div> 2098 } 2099 </div> 2100 </div> 2101 } 2102 2103 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType) { 2104 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 2105 2106 foreach (LoopItem categoryField in fieldsLoop) 2107 { 2108 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value"); 2109 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 2110 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 2111 2112 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue)) 2113 { 2114 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false) 2115 { 2116 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15") 2117 { 2118 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType); 2119 } 2120 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8") 2121 { 2122 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link"); 2123 } 2124 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9") 2125 { 2126 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download"); 2127 } 2128 else 2129 { 2130 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType); 2131 } 2132 } 2133 } 2134 } 2135 } 2136 2137 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType) { 2138 foreach (LoopItem document in fieldsLoop) 2139 { 2140 string fieldValue; 2141 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 2142 { 2143 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 2144 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download") 2145 } 2146 2147 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 2148 { 2149 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 2150 @RenderFieldItem(fieldValue, fieldValue, viewType, "download") 2151 } 2152 } 2153 } 2154 2155 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean") 2156 { 2157 if (viewType != "table") 2158 { 2159 string fieldColumns = viewType == "list" ? "12" : "4"; 2160 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom"> 2161 <div class="u-bold"> 2162 @name 2163 </div> 2164 <div> 2165 @RenderFieldItemContent(name, value, fieldType) 2166 </div> 2167 </div> 2168 } 2169 else 2170 { 2171 <tr> 2172 <th>@name</th> 2173 <td> 2174 @RenderFieldItemContent(name, value, fieldType) 2175 </td> 2176 </tr> 2177 } 2178 } 2179 2180 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean") 2181 { 2182 if (fieldType == "link") 2183 { 2184 <a target="_blank" rel="noopener" href="@value"> 2185 @if (isImage(value)) 2186 { 2187 @getIconForFile(value) 2188 } 2189 else 2190 { 2191 @value 2192 } 2193 </a> 2194 } 2195 else if (fieldType == "download") 2196 { 2197 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value)); 2198 2199 if (info.Exists) 2200 { 2201 <div class="grid grid--no-wrap"> 2202 <a href="@value" download title="@Translate("Download")" class="product__document u-min-w120px u-ta-center dw-mod">@getIconForFile(value)</a> 2203 <div class="product__document-info dw-mod"> 2204 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a> 2205 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small> 2206 </div> 2207 </div> 2208 } 2209 } 2210 else 2211 { 2212 @value 2213 } 2214 } 2215 2216 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2217 @using Dynamicweb.Core 2218 @using System 2219 @using System.Web 2220 @using System.Collections.Generic 2221 @using Dynamicweb.Rapido.Blocks 2222 2223 @functions{ 2224 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product"); 2225 } 2226 2227 @{ 2228 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section"; 2229 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout; 2230 2231 int videosCount = 0; 2232 2233 foreach (LoopItem detailField in GetLoop("Details")) 2234 { 2235 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1) 2236 { 2237 videosCount++; 2238 } 2239 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) 2240 { 2241 videosCount++; 2242 } 2243 } 2244 2245 if (videosCount > 0 && videosLayout != "hide") 2246 { 2247 Block detailsVideos = new Block() 2248 { 2249 Name = videosLayout != "MainInformation" ? Translate("Videos") : "", 2250 Id = "Videos", 2251 SortId = 60, 2252 Template = ProductVideos(videosCount, videosLayout), 2253 Design = new Design 2254 { 2255 Size = "12", 2256 RenderType = RenderType.Column 2257 } 2258 }; 2259 productVideoPage.Add(videosLayout, detailsVideos); 2260 } 2261 } 2262 2263 @helper ProductVideos(int videosCount, string layout) { 2264 string videoColumn = "12"; 2265 videoColumn = videosCount == 2 ? "6" : videoColumn; 2266 videoColumn = videosCount > 2 ? "4" : videoColumn; 2267 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2268 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2269 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2270 2271 <div class="product__section @ribbonClasses dw-mod"> 2272 <div class="center-container @ribbonSubClasses dw-mod"> 2273 @if (layout == "Section") { 2274 <h2>@Translate("Videos")</h2> 2275 } 2276 2277 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2278 @foreach (LoopItem detailField in GetLoop("Details")) 2279 { 2280 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1 || detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) 2281 { 2282 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> 2283 <div class="video-wrapper"> 2284 @detailField.GetString("Ecom:Product:Detail.Text") 2285 </div> 2286 </div> 2287 } 2288 } 2289 </div> 2290 </div> 2291 </div> 2292 } 2293 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2294 @using Dynamicweb.Core 2295 @using System 2296 @using System.Web 2297 @using System.Collections.Generic 2298 @using Dynamicweb.Rapido.Blocks 2299 2300 @functions{ 2301 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product"); 2302 } 2303 2304 @{ 2305 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section"; 2306 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout; 2307 bool relatedOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 2308 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping"); 2309 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton"); 2310 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 2311 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null; 2312 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 2313 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 2314 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton"); 2315 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 2316 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View"; 2317 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber"); 2318 2319 // int relatedProductsPageSize = 4; 2320 int relatedProductsPageSize = 16; 2321 int relatedProductsColumnWidth = 3; 2322 2323 if (Pageview.Device.ToString() == "Mobile") { 2324 relatedProductsPageSize = 1; 2325 relatedProductsColumnWidth = 12; 2326 } 2327 2328 if (Pageview.Device.ToString() == "Tablet") { 2329 relatedProductsPageSize = 3; 2330 relatedProductsColumnWidth = 4; 2331 } 2332 2333 if (relatedProductsLayout != "hide") { 2334 if (GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Any()) { 2335 2336 string[] customersWhoSawThisAlsoSawProductIds = GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Select(x => x.GetString("Ecom:Product.ID")).ToArray(); 2337 string relatedGroupId = "OtherSeenProducts"; 2338 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + 4 + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; 2339 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + string.Join(",", customersWhoSawThisAlsoSawProductIds); 2340 string relatedGroupName = "otherSeenProducts"; 2341 Block detailsRelated = new Block() { 2342 Name = relatedGroupName, 2343 Id = relatedGroupId, 2344 SortId = 70, 2345 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("CustomersWhoSawThisAlsoSaw")), 2346 Design = new Design { 2347 Size = "12", 2348 RenderType = RenderType.Column, 2349 HidePadding = true 2350 } 2351 }; 2352 2353 productRelatedPage.Add(relatedProductsLayout, detailsRelated); 2354 } 2355 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups")) { 2356 string relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name")); 2357 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; 2358 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID") + "&GroupName=" + relatedGroupId; 2359 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : ""; 2360 Block detailsRelated = new Block() { 2361 Name = relatedGroupName, 2362 Id = relatedGroupId, 2363 SortId = 80, 2364 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("Relaterede varer")), 2365 Design = new Design { 2366 Size = "12", 2367 RenderType = RenderType.Column, 2368 HidePadding = true 2369 } 2370 }; 2371 2372 productRelatedPage.Add(relatedProductsLayout, detailsRelated); 2373 } 2374 2375 //CustomersWhoSawThisAlsoSaw 2376 2377 2378 } 2379 } 2380 2381 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout, string header = "") { 2382 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2383 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2384 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2385 2386 <div class="product__section @ribbonClasses dw-mod"> 2387 <div class="center-container @ribbonSubClasses dw-mod"> 2388 <h2>@header</h2> 2389 @if (layout == "Section") { 2390 @*<h2>@name</h2>*@ 2391 2392 } 2393 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div> 2394 </div> 2395 </div> 2396 } 2397 2398 @* Script templates for related products *@ 2399 <script id="ProductPreRenderContainer" type="text/x-template"> 2400 <div class="u-h600px u-full-width"> 2401 <div class="grid"> 2402 <div class="grid__col-12"> 2403 <div class="pre-render-element pre-render-element--md"></div> 2404 </div> 2405 </div> 2406 </div> 2407 </script> 2408 2409 <script id="ProductContainer" type="text/x-template"> 2410 {{#.}} 2411 @*<h2>@Translate("Relaterede varer")</h2>*@ 2412 <div class="u-min-h400px u-full-width"> 2413 <div class="grid"> 2414 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-left"><button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fas fa-chevron-left fa-2x"></i></button></div></div>*@ 2415 <div class="grid__col-auto grid__col--bleed-x"> 2416 <div id="ProductsContainer" data-template="ProductGridItemContainer" class="grid product-list dw-mod" data-save-cookie="true"> 2417 {{#ProductsContainer}} 2418 <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item dw-mod"> 2419 {{#Product}} 2420 @if (useGoogleTagManager) { 2421 <text>{{{googleEnchantImpression 'Related products' currency googleImpression}}}</text> 2422 } 2423 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 2424 <a href="{{link}}" onclick="Scroll.SavePosition(event)" class="u-block u-position-relative"> 2425 <img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=jpg&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2426 {{#StickersContainers}} 2427 {{>StickersContainer}} 2428 {{/StickersContainers}} 2429 </a> 2430 @if (relatedShowFavoriteButton) { 2431 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 2432 {{#Favorite}} 2433 {{>FavoriteTemplate}} 2434 {{/Favorite}} 2435 </div> 2436 } 2437 </div> 2438 2439 <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> 2440 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}"><h6 class="u-condensed-text">{{{name}}}</h6></a> 2441 2442 @if (relatedShowNumber) { 2443 <div class="item-number dw-mod">@Translate("Product number"): {{number}}</div> 2444 } 2445 2446 @if (relatedShowPrice && !relatedOnlyPreview) { 2447 if (relatedPointShopOnly) { 2448 <text> 2449 {{#if havePointPrice}} 2450 <div>{{points}} @Translate("points")</div> 2451 {{else}} 2452 @Translate("Not available") 2453 {{/if}} 2454 </text> 2455 } else { 2456 <div class="price price--product-list dw-mod">{{livePriceFormatted}}</div> 2457 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 2458 } 2459 } 2460 </div> 2461 2462 <div class="product-list__grid-item__footer dw-mod"> 2463 @if (relatedShowCartButton && !relatedOnlyPreview) { 2464 <div class="u-ta-center u-inline-block"> 2465 <div class="buttons-collection {{hideBuyOptions}}"> 2466 @if (relatedPointShopOnly) { 2467 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints" 2468 onclick="Cart.AddToCart(event, { 2469 id: {{productId}}', 2470 variantId: '{{variantid}}', 2471 unitId: '{{unitId}}', 2472 quantity: 1, 2473 buyForPoints: true, 2474 productInfo: {{productInfo}} 2475 }); {{facebookPixelAction}}" {{disabledBuyButton}}> 2476 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span> 2477 </button> 2478 } else { 2479 <button type="button" id="CartButton_{{id}}" class="js-cart-btn btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod {{disabledBuyButton}}" name="submit" 2480 onclick="Cart.AddToCart(event, { 2481 id: '{{productId}}', 2482 variantId: '{{variantid}}', 2483 unitId: '{{unitId}}', 2484 quantity: document.getElementById('Quantity_{{id}}').value, 2485 productInfo: {{productInfo}} 2486 }); {{facebookPixelAction}}" {{disabledBuyButton}}> 2487 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 2488 </button> 2489 <input type="number" class="u-w80px u-pull--right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> 2490 } 2491 </div> 2492 </div> 2493 2494 if (relatedShowViewButton) { 2495 <div class="u-ta-center {{hideViewMore}}"> 2496 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary btn--full u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a> 2497 </div> 2498 } 2499 2500 } else if (relatedShowViewButton) { 2501 <div class="u-ta-center"> 2502 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary btn--full u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a> 2503 </div> 2504 } 2505 2506 @if (!relatedOnlyPreview && relatedShowStock) { 2507 <div class="u-margin-top"> 2508 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div> 2509 <div> 2510 {{#if deliveryText}} 2511 {{deliveryText}} 2512 {{else}} 2513 - 2514 {{/if}} 2515 </div> 2516 </div> 2517 } 2518 2519 @if (showAddToDownloadButton && Pageview.User != null) { 2520 <button type="button" class="btn btn--primary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 2521 <i class="fas fa-plus js-button-icon"></i> 2522 <span class="js-button-text">@Translate("Add")</span> 2523 </button> 2524 } 2525 </div> 2526 {{/Product}} 2527 </div> 2528 {{/ProductsContainer}} 2529 </div> 2530 </div> 2531 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-right"><button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fas fa-chevron-right fa-2x"></i></button></div></div>*@ 2532 </div> 2533 </div> 2534 {{/.}} 2535 </script> 2536 2537 @* Favorites templates *@ 2538 2539 <script id="FavoriteTemplate" type="text/x-template"> 2540 <div class="favorites-list u-ta-left"> 2541 <label for="FavoriteTrigger_{{id}}" class="u-no-margin"><i class="{{favoriteIcon}} fa-1_5x"></i></label> 2542 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 2543 <div class="dropdown dropdown--absolute-position"> 2544 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 2545 <ul class="list list--clean dw-mod"> 2546 {{#FavoriteLists}} 2547 {{>FavoriteListItem}} 2548 {{/FavoriteLists}} 2549 </ul> 2550 </div> 2551 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 2552 </div> 2553 </div> 2554 </script> 2555 2556 <script id="StickersContainer" type="text/x-template"> 2557 <div class="stickers-container stickers-container--{{position}} dw-mod"> 2558 {{#Stickers}} 2559 {{>Sticker}} 2560 {{/Stickers}} 2561 </div> 2562 </script> 2563 2564 @*<script id="Sticker" type="text/x-template"> 2565 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 2566 </script>*@ 2567 2568 <script id="Sticker" type="text/x-template"> 2569 {{#if groupColor}} 2570 <div class="stickers-container__tag {{className}} dw-mod" style="background-color:{{groupColor}};">{{text}}</div> 2571 {{else}} 2572 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 2573 {{/if}} 2574 </script> 2575 2576 <script id="FavoriteListItem" type="text/x-template"> 2577 <li> 2578 <a href="{{link}}" class="list__link u-no-underline dw-mod" onclick="{{facebookPixelAction}}"><i class="{{favoriteIcon}}"></i> {{{name}}}</a> 2579 </li> 2580 </script> 2581 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2582 @using Dynamicweb.Core 2583 @using System 2584 @using System.Web 2585 @using System.Collections.Generic 2586 @using Dynamicweb.Rapido.Blocks 2587 2588 @functions { 2589 BlocksPage productVariantsPage = BlocksPage.GetBlockPage("Product"); 2590 } 2591 2592 @{ 2593 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 2594 bool variantsOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 2595 bool showProductNumberForVariants = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers"); 2596 bool showImageForEachVariant = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant"); 2597 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 2598 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 2599 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 2600 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 2601 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section"; 2602 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout; 2603 2604 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT"); 2605 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 2606 2607 if (renderVariantsAsProducts && variantsListLayout != "hide") 2608 { 2609 Block detailsVariantsList = new Block() 2610 { 2611 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "", 2612 Id = "VariantsList", 2613 SortId = 20, 2614 Template = RenderVariantsProductList(variantsListLayout), 2615 Design = new Design 2616 { 2617 Size = "12", 2618 RenderType = RenderType.Column, 2619 HidePadding = true 2620 } 2621 }; 2622 productVariantsPage.Add(variantsListLayout, detailsVariantsList); 2623 } 2624 } 2625 2626 @helper RenderVariantsProductList(string layout) 2627 { 2628 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 2629 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 2630 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2631 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2632 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2633 2634 <div class="product__section @ribbonClasses dw-mod"> 2635 <div class="center-container @ribbonSubClasses dw-mod"> 2636 @if (layout == "Section") { 2637 <h2>@Translate("Variants")</h2> 2638 } 2639 2640 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div> 2641 </div> 2642 </div> 2643 } 2644 2645 2646 @* Script templates for variant products *@ 2647 2648 <script id="VariantProductsContainer" type="text/x-template"> 2649 {{#.}} 2650 <div class=""> 2651 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod"> 2652 <thead> 2653 <tr> 2654 @if (showImageForEachVariant) 2655 { 2656 <td width="75">&nbsp;</td> 2657 } 2658 <td>@Translate("Product")</td> 2659 {{#AvailableCustomFields}} 2660 {{>TableFieldNameTemplate}} 2661 {{/AvailableCustomFields}} 2662 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) { 2663 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 2664 { 2665 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td> 2666 } 2667 } 2668 <td width="360">&nbsp;</td> 2669 </tr> 2670 </thead> 2671 2672 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true"> 2673 {{#ProductsContainer}} 2674 {{>VariantProductItemContainer}} 2675 {{/ProductsContainer}} 2676 </tbody> 2677 </table> 2678 </div> 2679 2680 <div class="grid"> 2681 <div class="grid__col-12 grid__col--bleed-y"> 2682 <button type="button" id="LoadMoreButton" class="btn btn--primary btn--full {{nextdisabled}} dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="VariantProductListContainer" data-feed-url="@variantsFeedUrl{{loadMoreFeedParams}}" onclick="LoadMore.Next(this)" {{nextdisabled}}>@Translate("Load") @Translate("more")</button> 2683 </div> 2684 </div> 2685 {{/.}} 2686 </script> 2687 2688 <script id="VariantProductItemContainer" type="text/x-template"> 2689 {{#.}} 2690 <tr id="VariantProduct{{id}}" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}"> 2691 {{#Product}} 2692 {{>VariantProductItem}} 2693 {{/Product}} 2694 </tr> 2695 {{/.}} 2696 </script> 2697 2698 <script id="VariantProductItem" type="text/x-template"> 2699 {{#.}} 2700 @if (showImageForEachVariant) 2701 { 2702 <td width="75"> 2703 <div class="lightbox u-hidden-xxs"> 2704 <a href="{{link}}" onclick="Scroll.SavePosition(event)"> 2705 <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&amp;height=220&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2706 <div class="u-margin-right {{noImage}}"> 2707 <img src="/Admin/Public/GetImage.ashx?width=75&amp;height=55&amp;crop=5&FillCanvas=true&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2708 </div> 2709 </a> 2710 </div> 2711 </td> 2712 } 2713 2714 <td class="u-va-middle"> 2715 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}"><h6 class="u-no-margin">{{{name}}}</h6></a> 2716 <div class="item-number item-number--compressed dw-mod"> 2717 @if (showProductNumberForVariants) 2718 { 2719 <div class="u-margin-bottom">@Translate("Product number"): {{number}}</div> 2720 } 2721 @*@if (!variantsOnlyPreview) 2722 { 2723 <div> 2724 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}} {{deliveryText}} 2725 </div> 2726 }*@ 2727 else 2728 { 2729 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod"> 2730 {{#Stickers}} 2731 {{>MiniSticker}} 2732 {{/Stickers}} 2733 </div> 2734 } 2735 </div> 2736 </td> 2737 {{#CustomFields}} 2738 {{>TableFieldValueTemplate}} 2739 {{/CustomFields}} 2740 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) 2741 { 2742 <text> 2743 {{#VariantSelectionNames}} 2744 {{>TableFieldNameTemplate}} 2745 {{/VariantSelectionNames}} 2746 </text> 2747 } 2748 <td width="365" class="u-va-middle"> 2749 @if (variantsOnlyPreview) 2750 { 2751 <div class="u-hidden-sm"> 2752 <div class="u-full-width u-ta-right u-padding-right"> 2753 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div> 2754 <div class="price price--product-list price--micro dw-mod">{{livePriceFormatted}}</div> 2755 </div> 2756 </div> 2757 } 2758 else 2759 { 2760 <div class="grid grid--align-center grid--justify-end"> 2761 2762 <div class="u-margin-right"> 2763 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" /> 2764 <div class="dropdown u-w120px {{hasUnits}} dw-mod"> 2765 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label> 2766 <div id="unitOptions" class="dropdown__content dw-mod"> 2767 {{#unitOptions}} 2768 {{>UnitOption}} 2769 {{/unitOptions}} 2770 </div> 2771 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label> 2772 </div> 2773 <input type="hidden" value="{{unitId}}" name="Unit{{id}}" id="Unit_{{id}}" /> 2774 <input type="hidden" value="{{variantid}}" name="VariantID{{id}}" id="Variant_{{id}}" /> 2775 </div> 2776 <div class="u-margin-right u-hidden-xs u-hidden-xxs"> 2777 @if (variantsPointShopOnly) { 2778 <text> 2779 {{#if canBePurchasedWithPoints}} 2780 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div> 2781 {{else}} 2782 {{#if havePointPrice}} 2783 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small> 2784 {{else}} 2785 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small> 2786 {{/if}} 2787 {{/if}} 2788 </text> 2789 } else { 2790 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div> 2791 <div class="price price--condensed price--product-list dw-mod"> 2792 {{price}} 2793 @if (showVATPrice) { 2794 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 2795 @if (isPricesWithVATEnabled) { 2796 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 2797 } else { 2798 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 2799 } 2800 </small> 2801 } 2802 </div> 2803 } 2804 </div> 2805 @if (variantsPointShopOnly) { 2806 <div> 2807 <button {{#unless canBePurchasedWithPoints}} disabled{{/unless}} type="button" 2808 id="CartButton_{{id}}" 2809 class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{#unless canBePurchasedWithPoints}}disabled js-stay-disabled{{/unless}}" 2810 name="CartCmd" 2811 value="addWithPoints" 2812 onclick="Cart.AddToCart(event, { 2813 id: '{{productId}}', 2814 variantId: '{{variantid}}', 2815 unitId: '{{unitId}}', 2816 quantity: 1, 2817 buyForPoints: true, 2818 productInfo: {{productInfo}} 2819 })"> 2820 <i class="@variantsCartIcon"></i> 2821 </button> 2822 </div> 2823 } else { 2824 <div> 2825 <input type="number" class="u-w80px u-no-margin u-margin-right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> 2826 </div> 2827 <div> 2828 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod" name="submit" 2829 onclick="Cart.AddToCart(event, { 2830 id: '{{productId}}', 2831 variantId: '{{variantid}}', 2832 unitId: '{{unitId}}', 2833 quantity: document.getElementById('Quantity_{{id}}').value, 2834 productInfo: {{productInfo}} 2835 });"> 2836 <i class="@variantsCartIcon"></i> 2837 </button> 2838 </div> 2839 } 2840 <div class="favorites u-margin-left {{hasVariants}} dw-mod" {{hasVariants}}> 2841 {{#Favorite}} 2842 {{>FavoriteTemplate}} 2843 {{/Favorite}} 2844 </div> 2845 </div> 2846 } 2847 </td> 2848 {{/.}} 2849 </script> 2850 2851 <script id="TableFieldNameTemplate" type="text/x-template"> 2852 <td class="u-va-middle">{{{name}}}</td> 2853 </script> 2854 2855 <script id="TableFieldValueTemplate" type="text/x-template"> 2856 <td class="u-va-middle">{{value}}</td> 2857 </script> 2858 2859 <script id="MiniSticker" type="text/x-template"> 2860 <div class="stickers-container__tag stickers-container__tag--micro {{className}} dw-mod">{{text}}</div> 2861 </script> 2862 @if(File.Exists(HttpContext.Current.Server.MapPath("/Files/Templates/Designs/Rapido/eCom/Product/Blocks/Custom__Blocks.cshtml"))) { 2863 <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2864 @using Dynamicweb.Core 2865 @using System 2866 @using System.Web 2867 @using System.Collections.Generic 2868 @using Dynamicweb.Rapido.Blocks 2869 2870 @{ 2871 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product"); 2872 2873 //detailFieldsLayout skulle gerne være Tabs 2874 2875 2876 2877 if(detailFieldsLayout != "hide" && (GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected")).Any() || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold")) || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser")))) { 2878 Block contentsBlock = new Block { 2879 Id = "Contents", 2880 Name = Translate("Indhold"), 2881 SortId = 102, 2882 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Indhold"), RenderContents()), 2883 Design = new Design { 2884 Size = "12", 2885 RenderType = RenderType.Column, 2886 HidePadding = true 2887 } 2888 }; 2889 customProductBlocks.Add(detailFieldsLayout, contentsBlock); 2890 } 2891 2892 2893 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Pligttekst"))) { 2894 Block dutyTextBlock = new Block { 2895 Id = "DutyText", 2896 Name = Translate("Pligttekst"), 2897 SortId = 105, 2898 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Pligttekst"), RenderDutyText()), 2899 Design = new Design { 2900 Size = "12", 2901 RenderType = RenderType.Column, 2902 HidePadding = true 2903 } 2904 }; 2905 customProductBlocks.Add(detailFieldsLayout, dutyTextBlock); 2906 } 2907 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anprisninger"))) { 2908 Block excellenceBlock = new Block { 2909 Id = "Excellence", 2910 Name = Translate("Anprisninger"), 2911 SortId = 110, 2912 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Anprisninger"), RenderExcellence()), 2913 Design = new Design { 2914 Size = "12", 2915 RenderType = RenderType.Column, 2916 HidePadding = true 2917 } 2918 }; 2919 customProductBlocks.Add(detailFieldsLayout, excellenceBlock); 2920 } 2921 2922 } 2923 2924 @helper RenderExcellence() { 2925 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2926 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2927 <ul> 2928 @foreach(var i in GetLoop("Anprisninger.Options").Where(x => x.GetBoolean("Anprisninger.Option.IsSelected"))) { 2929 var excellencePage = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, i.GetString("Anprisninger.Option.Value")); 2930 if(excellencePage != null) { 2931 <li> 2932 <a href="/Default.aspx?ID=@excellencePage.ID">@excellencePage.MenuText</a> 2933 </li> 2934 } 2935 } 2936 </ul> 2937 </div> 2938 </div> 2939 } 2940 2941 2942 @helper RenderContents() { 2943 2944 var indeholderLoop = GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected")); 2945 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2946 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2947 2948 @if (indeholderLoop.Any()) { 2949 <div class="u-bold">@Translate("Dette produkt indeholder"):</div> 2950 <ul> 2951 @foreach (var i in indeholderLoop) { 2952 <li>@i.GetString("Indeholder.Option.Name")</li> 2953 } 2954 </ul> 2955 2956 } 2957 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold"))) { 2958 <div class="u-bold">@Translate("Næringsindhold")</div> 2959 <p>@GetString("Ecom:Product:Field.Naeringsindhold")</p> 2960 } 2961 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser"))) { 2962 <div class="u-bold">@Translate("Ingredienser")</div> 2963 <p>@GetString("Ecom:Product:Field.Ingredienser")</p> 2964 } 2965 2966 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Indholddagsdosis"))) { 2967 <div class="u-bold">@Translate("Indhold pr. dagsdosis")</div> 2968 <p>@GetString("Ecom:Product:Field.Indholddagsdosis")</p> 2969 } 2970 2971 </div> 2972 </div> 2973 } 2974 @helper RenderDutyText() { 2975 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2976 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2977 <p> 2978 @GetString("Ecom:Product:Field.Pligttekst") 2979 </p> 2980 </div> 2981 </div> 2982 }</text> 2983 } 2984 2985 2986 <div class="product__info dw-mod u-margin-bottom--lg js-product"> 2987 <div class="grid grid--align-content-start"> 2988 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 2989 @RenderBlockList(productsPage.BlocksRoot.BlocksList) 2990 </div> 2991 </div> 2992 2993 @helper RenderProductTop() { 2994 List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList(); 2995 2996 <div class="product__top paragraph-container paragraph-container--full-width dw-mod"> 2997 <div class="center-container u-padding dw-mod"> 2998 <div class="grid"> 2999 @RenderBlockList(subBlocks) 3000 </div> 3001 </div> 3002 </div> 3003 3004 } 3005 3006 @helper RenderProductMiniTabs() { 3007 List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList(); 3008 3009 if(subBlocks.Count > 0) { 3010 <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod"> 3011 @{ 3012 bool firstTab = true; 3013 foreach(Block item in subBlocks) { 3014 string isChecked = firstTab ? "checked" : ""; 3015 firstTab = false; 3016 3017 <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> 3018 } 3019 } 3020 3021 <div class="tabs__list dw-mod"> 3022 @foreach(Block item in subBlocks) { 3023 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> 3024 } 3025 </div> 3026 3027 <div class="tabs__blocks dw-mod"> 3028 @foreach(Block item in subBlocks) { 3029 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 3030 3031 if(item.Design.RenderType != RenderType.Hide) { 3032 <div class="tabs__block u-border dw-mod" id="Block__@item.Id"> 3033 <block class="product__block paragraph-container product__block--bordered dw-mod"> 3034 <div class="center-container u-padding--lg dw-mod"> 3035 @RenderBlock(item) 3036 </div> 3037 </block> 3038 </div> 3039 } 3040 } 3041 </div> 3042 </div> 3043 } 3044 } 3045 3046 @helper RenderProductTabs() { 3047 List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList(); 3048 3049 <div class="grid__col-12 product__info product__info--tabs tabs dw-mod"> 3050 @{ 3051 bool firstTab = true; 3052 foreach(Block item in subBlocks) { 3053 string isChecked = firstTab ? "checked" : ""; 3054 firstTab = false; 3055 3056 <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> 3057 } 3058 } 3059 3060 <div class="tabs__list dw-mod"> 3061 @foreach(Block item in subBlocks) { 3062 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> 3063 } 3064 </div> 3065 3066 <div class="tabs__blocks dw-mod"> 3067 @foreach(Block item in subBlocks) { 3068 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 3069 3070 if(item.Design.RenderType != RenderType.Hide) { 3071 <div class="tabs__block dw-mod" id="Block__@item.Id"> 3072 <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod"> 3073 <div class="center-container u-padding--lg dw-mod"> 3074 @RenderBlock(item) 3075 </div> 3076 </section> 3077 </div> 3078 } 3079 } 3080 </div> 3081 </div> 3082 } 3083