• Sprog
    • English
    • Deutsch
    • Svenska
    • Norsk
    • Dutch
  • Opnå fordele
  • Produkter
    Sko
    Sko
    Træsko
    Træsko
    Støvler
    Støvler
    Støvlet
    Støvlet
    Sandal
    Sandal
    Tilbehør
    Tilbehør
  • Brancher
    Byggeri og håndværk
    Byggeri og håndværk
    Landbrug, skovbrug og fiskeri
    Landbrug, skovbrug og fiskeri
    Let industri
    Let industri
    Tung industri
    Tung industri
    Transport og lager
    Transport og lager
    Fritid
    Fritid
    Levnedsmiddelindustri
    Levnedsmiddelindustri
    Medicinalindustri
    Medicinalindustri
    Hospital og pleje
    Hospital og pleje
    Hotel, restauration og kantine (HORECA)
    Hotel, restauration og kantine (HORECA)
    Service og rengøring
    Service og rengøring
  • Mærker
    BRYNJE
    SIKA
    ELTEN
    COFRA
    DUNLOP
    VISMO
    GRISPORT
    2-BE
Find den rette sko
Søg
    • Login
      • Log ind
      • Glemt password
    Error executing template "Designs/Swift/Paragraph/Base_Panel.cshtml"
    System.NullReferenceException: Object reference not set to an instance of an object.
       at CompiledRazorTemplates.Dynamic.RazorEngine_9ae15ff2a1324c908ed02e4e2f8692ec.Execute() in D:\Dynamicweb.NET\Solutions\Sika\Files\Templates\Designs\Swift\Paragraph\Base_Panel.cshtml:line 619
       at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
       at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
       at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
       at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
       at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
       at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
       at Dynamicweb.Rendering.Template.RenderRazorTemplate()
    
    1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using System.Collections.Generic 4 @using System.Linq 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @helper RenderButtons() 8 { 9 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 10 int loopCounter = 0; 11 12 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 13 14 string linkType = string.Empty; 15 16 foreach (var button in buttons) 17 { 18 loopCounter++; 19 } 20 21 if (buttons.Any()) 22 { 23 <div class="d-flex flex-wrap grid"> 24 @foreach (var button in buttons) 25 { 26 27 linkType = button.GetItem("Link").GetString("LinkType"); 28 29 if (linkType == "page" && button.GetItem("Link").GetLink("ButtonLink") != null) 30 { 31 link = button.GetItem("Link").GetLink("ButtonLink"); 32 } 33 34 if (linkType == "product-group") 35 { 36 37 IList<ProductGroupViewModel> selectedGroups = button.GetItem("Link").GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 38 39 IList<string> groupIds = new List<string> { }; 40 41 if (selectedGroups != null) 42 { 43 foreach (var fromGroup in selectedGroups) 44 { 45 groupIds.Add(fromGroup.Id); 46 } 47 } 48 link = new Dynamicweb.Frontend.LinkViewModel() 49 { 50 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds).Trim(), 51 IsExternal = false 52 }; 53 } 54 55 if (linkType == "product") 56 { 57 ProductListViewModel products = button.GetItem("Link").GetValue<ProductListViewModel>("ProductLink"); 58 IList<string> productIds = new List<string> { }; 59 string productPrimaryOrDefaultGroupID = string.Empty; 60 string pageTag = "Shop"; 61 62 if (products != null) 63 { 64 foreach (ProductViewModel product in products.Products) 65 { 66 productIds.Add(product.Id); 67 productPrimaryOrDefaultGroupID = product.PrimaryOrDefaultGroup.Id; 68 } 69 } 70 71 string productParameter = "MainProductId"; 72 string productGroupParameter = string.Empty; 73 if (productIds.Count == 1) 74 { 75 productParameter = "ProductID"; 76 if (!string.IsNullOrEmpty(productPrimaryOrDefaultGroupID)) 77 { 78 productGroupParameter = $"&GroupID={productPrimaryOrDefaultGroupID}"; 79 } 80 } 81 82 link = new Dynamicweb.Frontend.LinkViewModel() 83 { 84 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + productGroupParameter + "&" + productParameter + "=" + string.Join(",", productIds).Trim(), 85 IsExternal = false 86 }; 87 } 88 89 if (!string.IsNullOrEmpty(button.GetItem("Link").GetString("ButtonLink")) || !string.IsNullOrEmpty(button.GetItem("Link").GetString("ProductLink"))) 90 { 91 string classes = ""; 92 93 if (button.GetString("ButtonStyling") != "none") 94 { 95 classes = $"btn btn-{button.GetString("ButtonStyling")}"; 96 } 97 98 <p class="@(button.GetBoolean("NoWrap") ? "w-100" : "")"> 99 <a class="@classes" href="@link" target="@(link.Url.Contains("http") == true || link.Url.Contains("/Files/Files/") ? "_blank" : string.Empty)"> 100 @if (!string.IsNullOrEmpty(button.GetString("Icon"))) 101 { 102 <span class="icon-2" aria-hidden="true"> 103 @ReadFile(button.GetString("Icon")) 104 </span> 105 } 106 107 @button.GetString("ButtonText") 108 </a> 109 </p> 110 } 111 } 112 </div> 113 } 114 } 115 116 @using System.Collections.Generic 117 @using System.Linq 118 @using Dynamicweb.Content.Items 119 120 @functions 121 { 122 123 public string GetContainerClassList(Dynamicweb.Frontend.GridRowViewModel model) 124 { 125 List<string> returnValues = new List<string>(); 126 string container = "container-xl"; 127 128 if (model.Item.GetString("Width") == "bleed") 129 { 130 if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-end") 131 { 132 container = "container-xl me-lg-0 pe-lg-0"; 133 } 134 else if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-start") 135 { 136 container = "container-xl ms-lg-0 ps-lg-0"; 137 } 138 else 139 { 140 container = "container-fluid mx-0 px-0"; 141 } 142 } 143 144 returnValues.Add(container); 145 return string.Join(" ", returnValues); 146 } 147 148 149 150 public string GetColumnWidthClassList(Dynamicweb.Frontend.ItemViewModel model, bool isVisualEditor = false) 151 { 152 153 string columnWidth = isVisualEditor ? "col" : ""; 154 string mobileWidth = string.Empty; 155 string tabletWidth = string.Empty; 156 string desktopWidth = string.Empty; 157 string XLWidth = string.Empty; 158 159 if (model != null) 160 { 161 162 if (model.GetField("Mobile").GetRawValue() != null && model.GetField("Mobile").GetRawValue().ToString() != "auto") 163 { 164 165 mobileWidth = "col-" + model.GetField("Mobile").GetRawValue(); 166 if (model.GetField("Tablet").GetRawValue() == null) 167 { 168 mobileWidth = mobileWidth + " col-sm"; 169 } 170 } 171 if (model.GetField("Width").GetRawValue() != null && model.GetField("Width").GetRawValue().ToString() != "auto") 172 { 173 desktopWidth = "col-md-" + model.GetField("Width").GetRawValue(); 174 } 175 if (model.GetField("Tablet").GetRawValue() != null && model.GetField("Tablet").GetRawValue().ToString() != "auto") 176 { 177 178 desktopWidth = " col-lg-" + model.GetField("Width").GetRawValue(); 179 tabletWidth = "col-md-" + model.GetField("Tablet").GetRawValue(); 180 if (model.GetField("XL").GetRawValue() == null) 181 { 182 tabletWidth = tabletWidth + " col-lg-" + model.GetField("Width").GetRawValue(); 183 } 184 } 185 if (model.GetField("XL").GetRawValue() != null && model.GetField("XL").GetRawValue().ToString() != "auto") 186 { 187 XLWidth = "col-xxxl-" + model.GetField("XL").GetRawValue(); 188 } 189 190 columnWidth = $"col {mobileWidth} {tabletWidth} {desktopWidth} {XLWidth}"; 191 192 } 193 return string.Join(" ", columnWidth); 194 } 195 196 public string GetRowWidthClassList(Dynamicweb.Frontend.GridRowViewModel model) 197 { 198 List<string> returnValues = new List<string>(); 199 200 string rowWidth = model.Item.GetRawValueString("Width", string.Empty).ToLower(); 201 202 if (rowWidth == "6") 203 { 204 returnValues.Add("col-12 col-lg-6"); 205 } 206 if (rowWidth == "8") 207 { 208 returnValues.Add("col-12 col-lg-8"); 209 } 210 if (rowWidth == "9") 211 { 212 returnValues.Add("col-12 col-lg-9"); 213 } 214 if (rowWidth == "10") 215 { 216 returnValues.Add("col-12 col-lg-10"); 217 } 218 if (rowWidth == "12") 219 { 220 returnValues.Add("col-12 col-lg-12"); 221 } 222 if (rowWidth == "bleed") 223 { 224 returnValues.Add("col-12"); 225 } 226 227 return string.Join(" ", returnValues); 228 } 229 230 public string GetSectionContentAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 231 { 232 List<string> returnValues = new List<string>(); 233 234 returnValues.Add(model.Item.GetRawValueString("OverallAlignment", string.Empty).ToLower()); 235 236 return string.Join(" ", returnValues); 237 } 238 239 public string GetRowHorizontalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 240 { 241 242 List<string> returnValues = new List<string>(); 243 244 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 245 246 return string.Join(" ", returnValues); 247 } 248 249 public string GetRowVerticalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 250 { 251 252 List<string> returnValues = new List<string>(); 253 254 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 255 256 return string.Join(" ", returnValues); 257 } 258 259 public string GetRowSpacing(Dynamicweb.Frontend.GridRowViewModel model) 260 { 261 List<string> returnValues = new List<string>(); 262 263 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 264 265 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 266 267 return string.Join(" ", returnValues); 268 } 269 270 public string GetRowClassList(Dynamicweb.Frontend.GridRowViewModel model) 271 { 272 273 List<string> returnValues = new List<string>(); 274 275 string mobileOrderFirst = string.Empty; 276 if (model.Item.GetBoolean("MobileOrderReverse")) 277 { 278 mobileOrderFirst = "flex-column-reverse flex-md-row"; 279 } 280 returnValues.Add(mobileOrderFirst); 281 282 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 283 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 284 285 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 286 287 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 288 289 return string.Join(" ", returnValues); 290 } 291 292 public string GetSectionClassList(Dynamicweb.Frontend.GridRowViewModel model) 293 { 294 List<string> returnValues = new List<string>(); 295 returnValues.Add($"item_{model.Item.SystemName.ToLower()}"); 296 returnValues.Add(!string.IsNullOrWhiteSpace(model.Item.GetRawValueString("Theme")) ? " theme " + model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""); 297 string paddingTop = model.Item.GetRawValueString("PaddingTop", "large"); 298 string paddingBottom = model.Item.GetRawValueString("PaddingBottom", "large"); 299 300 if (paddingTop == "none") 301 { 302 returnValues.Add("pt-0"); 303 } 304 if (paddingTop == "small") 305 { 306 returnValues.Add("pt-4"); 307 } 308 if (paddingTop == "medium") 309 { 310 returnValues.Add("pt-5"); 311 } 312 if (paddingTop == "large") { 313 returnValues.Add("pt-7"); 314 } 315 316 if (paddingBottom == "none") 317 { 318 returnValues.Add("pb-0"); 319 } 320 if (paddingBottom == "small") 321 { 322 returnValues.Add("pb-4"); 323 } 324 if (paddingBottom == "medium") 325 { 326 returnValues.Add("pb-5"); 327 } 328 if (paddingBottom == "large") { 329 returnValues.Add("pb-7"); 330 } 331 332 var decorations = model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 333 var cssClasses = new List<string> { }; 334 335 foreach (var itemId in decorations) 336 { 337 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 338 339 if (item != null) 340 { 341 item.TryGetValue("Class", out object classes); 342 343 if (classes is null) 344 { 345 continue; 346 } 347 348 var cssString = (string)classes; 349 if (cssString.StartsWith("[")) 350 { 351 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 352 cssClasses.AddRange(cssArray); 353 } 354 else 355 { 356 cssClasses.Add(cssString.Replace(",", " ")); 357 } 358 } 359 } 360 returnValues.Add(string.Join(" ", cssClasses).Trim()); 361 362 return string.Join(" ", returnValues); 363 } 364 365 } 366 367 368 @helper RenderImage() 369 { 370 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("Image"))) 371 { 372 string ratioCssClass = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "ratio" : string.Empty; 373 string ratioVariable = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "style=\"--bs-aspect-ratio: " + Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") + "\"" : string.Empty; 374 string ImageObjectFit = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageObjectFit", string.Empty); 375 ImageObjectFit = ImageObjectFit == "cover" ? string.Empty : ImageObjectFit; 376 ImageObjectFit = ImageObjectFit == "contain" ? "object-fit:contain" : ImageObjectFit; 377 378 var parms = new Dictionary<string, object>(); 379 parms.Add("loading", "lazy"); 380 parms.Add("style", ImageObjectFit); 381 parms.Add("alt", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageAltText")); 382 parms.Add("columns", Model.GridRowColumnCount); 383 384 parms.Add("fullwidth", true); 385 parms.Add("cssClass", "img-fluid w-100 " + Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageCustomClasses")); 386 387 388 <figure class="mb-0 @ratioCssClass" @ratioVariable> 389 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 390 </figure> 391 } 392 } 393 394 @{ 395 var colSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("ColumnWidth")); 396 397 string imgPosition = string.Empty; 398 string imgPlacement = string.Empty; 399 string imgFloat = string.Empty; 400 401 if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 402 { 403 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement"); 404 } 405 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 406 { 407 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetString("ImagePlacement"); 408 } 409 410 if (imgPosition == "image-top") 411 { 412 imgPlacement = "flex-column"; 413 imgFloat = "top"; 414 } else if (imgPosition == "image-left") 415 { 416 imgPlacement = "flex-column flex-md-row"; 417 imgFloat = "left-right"; 418 } else if (imgPosition == "image-right") 419 { 420 imgPlacement = "flex-column flex-md-row-reverse"; 421 imgFloat = "left-right"; 422 } 423 424 425 426 var parms = new Dictionary<string, object>(); 427 parms.Add("cssClass", "h-100 w-100"); 428 429 } 430 431 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 432 @using Dynamicweb.Ecommerce.ProductCatalog 433 @using System.IO 434 @using Dynamicweb.Frontend 435 436 @{ 437 bool movePageBehind = false; 438 bool isFirstPoster = false; 439 string movePageBehindClass = ""; 440 if (Pageview.Page.PropertyItem != null) 441 { 442 string headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 443 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 444 445 if (movePageBehind) 446 { 447 movePageBehindClass = " poster-behind"; 448 if (!Dynamicweb.Context.Current.Items.Contains("firstPosterIsRendered")) 449 { 450 isFirstPoster = true; 451 Dynamicweb.Context.Current.Items.Add("firstPosterIsRendered", true); 452 } 453 454 } 455 456 } 457 } 458 459 @if (movePageBehind && isFirstPoster) 460 { 461 <script> 462 ['resize', 'load'].forEach(function (e) { 463 window.addEventListener(e, () => swift.Scroll.setContentPosition()); 464 }); 465 </script> 466 } 467 468 @using System.Collections.Generic 469 @using System.Linq 470 471 @{ 472 var headings = Model.Item?.GetItem("Panel_Text")?.GetItems("Headings") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 473 var widths = Model.Item?.GetItem("Panel_Text")?.GetItems("ColumnTest1") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 474 string layout = Model.Item?.GetItem("Panel_Text")?.GetRawValueString("Layout"); 475 var textColSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Text")?.GetItem("ColumnWidth")); 476 477 var textHeight = string.Empty; 478 479 if (layout == "top-left") 480 { 481 layout = "d-flex flex-column align-items-start"; 482 } else if (layout == "top-center") 483 { 484 layout = "d-flex flex-column align-items-center text-center mx-auto"; 485 } 486 else if (layout == "top-right") 487 { 488 layout = "d-flex flex-column align-items-end text-end ms-auto"; 489 } 490 else if (layout == "center-left") 491 { 492 layout = "d-flex flex-column justify-content-center"; 493 } 494 else if (layout == "center") 495 { 496 layout = "d-flex flex-column justify-content-center align-items-center text-center mx-auto"; 497 } 498 else if (layout == "center-right") 499 { 500 layout = "d-flex flex-column justify-content-center align-items-end text-end ms-auto"; 501 } 502 else if (layout == "bottom-left") 503 { 504 layout = "d-flex flex-column justify-content-end"; 505 } 506 else if (layout == "bottom-center") 507 { 508 layout = "d-flex flex-column justify-content-end align-items-center text-center mx-auto"; 509 } 510 else if (layout == "bottom-right") 511 { 512 layout = "d-flex flex-column justify-content-end align-items-end text-end ms-auto"; 513 } 514 } 515 516 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 517 @using System.Collections.Generic 518 @using Dynamicweb.Ecommerce.ProductCatalog 519 520 @{ 521 string linkType = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") != string.Empty ? Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") : string.Empty; 522 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 523 524 if (linkType == "page" && Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink") != null) 525 { 526 link = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink"); 527 } 528 529 if (linkType == "product-group") 530 { 531 IList<ProductGroupViewModel> selectedGroups = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 532 IList<string> groupIds = new List<string> {}; 533 534 if (selectedGroups != null) 535 { 536 foreach (var fromGroup in selectedGroups) 537 { 538 groupIds.Add(fromGroup.Id); 539 } 540 } 541 542 link = new Dynamicweb.Frontend.LinkViewModel() 543 { 544 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds) 545 }; 546 } 547 548 if (linkType == "product") 549 { 550 ProductListViewModel products = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<ProductListViewModel>("ProductLink"); 551 IList<string> productIds = new List<string> {}; 552 553 if (products != null) 554 { 555 foreach (var product in products.Products) 556 { 557 productIds.Add(product.Id); 558 } 559 } 560 561 string productParameter = productIds.Count == 1 ? "ProductID" : "MainProductId"; 562 string pageTag = productIds.Count == 1 ? "ProductDetailPage" : "Shop"; 563 link = new Dynamicweb.Frontend.LinkViewModel() 564 { 565 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + "&" + productParameter + "=" + string.Join(",", productIds) 566 }; 567 } 568 569 } 570 571 572 @{ 573 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 574 bool hasImage = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null; 575 bool hasGraphic = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") != null; 576 bool hasVideo = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Media" )?.GetItem( "Video" ).GetString( "VideoSourceID" ) ); 577 bool hasLead = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Lead" ) ); 578 bool hasText = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Text" ) ); 579 bool hasTheme = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) ); 580 bool hasHeading = headings.Count() > 0; 581 bool hasButton = buttons.Any(); 582 583 var decorations = Model.Item?.GetItem( "Panel_Settings" )?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 584 var cssClasses = new List<string> { }; 585 string cssDecorations = ""; 586 587 foreach (var itemId in decorations) 588 { 589 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 590 591 if (item != null) 592 { 593 item.TryGetValue("Class", out object classes); 594 595 if (classes is null) 596 { 597 continue; 598 } 599 600 var cssString = (string)classes; 601 if (cssString.StartsWith("[")) 602 { 603 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 604 cssClasses.AddRange(cssArray); 605 } 606 else 607 { 608 cssClasses.Add(cssString.Replace(",", " ")); 609 } 610 } 611 } 612 cssDecorations = string.Join(" ", cssClasses).Trim(); 613 614 ProductViewModel promotionalProduct = null; 615 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 616 { 617 promotionalProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 618 } 619 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 620 { 621 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 622 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 623 624 if (productList?.Products is object) 625 { 626 promotionalProduct = productList.Products[0]; 627 } 628 } 629 630 CategoryFieldViewModel categoryFieldViewModel = null; 631 FieldValueViewModel headerFieldValueViewModel = null; 632 FieldValueViewModel imageFieldValueViewModel = null; 633 FieldValueViewModel textFieldValueViewModel = null; 634 635 if (promotionalProduct != null ) 636 { 637 promotionalProduct.ProductCategories.TryGetValue("Promotional", out categoryFieldViewModel); 638 } 639 } 640 641 @if (Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement") == "image-poster" || Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") == "video-poster") 642 { 643 644 <div class="p-poster-container poster-overlay theme h-100 @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 645 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 646 647 @{ 648 string theme = string.Empty; 649 string posterHeight = string.Empty; 650 string mediaType = Model.Item.GetItem("Panel_Media").GetString("Media"); 651 652 if ( mediaType == "video") 653 { 654 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("Height"); 655 656 theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 657 } else if (mediaType == "image") 658 { 659 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Image").GetString("Height"); 660 661 theme = !string.IsNullOrWhiteSpace(Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme")) ? " theme " + Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; 662 663 } 664 665 posterHeight = posterHeight == "auto" ? "h-100" : posterHeight; 666 posterHeight = posterHeight == "small" ? "min-vh-50 min-vh-md-50" : posterHeight; 667 posterHeight = posterHeight == "medium" ? "min-vh-50 min-vh-md-75" : posterHeight; 668 posterHeight = posterHeight == "large" ? "min-vh-100 min-vh-md-100" : posterHeight; 669 posterHeight = posterHeight == "1x1" ? "ratio ratio-1x1 mx-auto" : posterHeight; 670 posterHeight = posterHeight == "4x3" ? "ratio ratio-4x3 mx-auto" : posterHeight; 671 posterHeight = posterHeight == "16x9" ? "ratio ratio-16x9 mx-auto" : posterHeight; 672 posterHeight = posterHeight == "9x16" ? "ratio ratio-9x16 mx-auto" : posterHeight; 673 posterHeight = posterHeight == "3x4" ? "ratio ratio-3x4 mx-auto" : posterHeight; 674 675 676 } 677 678 <div class="position-relative @(hasText || hasHeading ? "row" : "") @posterHeight @theme @(movePageBehindClass)"> 679 680 @if (Model.Item.GetItem("Panel_Media").GetString("Media") == "video") 681 { 682 <div class="p-poster-video-container position-absolute top-0 bottom-0 end-0 start-0 px-0"> 683 <video preload="auto" loop autoplay muted playsinline class="h-100 w-100" style="object-fit: cover;"> 684 <source src="@Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")" 685 type="video/@Path.GetExtension(Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")).ToLower().Replace(".", "")"> 686 </video> 687 </div> 688 689 } else if (Model.Item.GetItem("Panel_Media").GetString("Media") == "image") 690 { 691 <div class="position-absolute top-0 bottom-0 end-0 start-0 px-0"> 692 693 @if (link != null && !string.IsNullOrEmpty(link.Url)) 694 { 695 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 696 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 697 <a class="bottom-0 position-absolute top-0 w-100" href="@link.Url" @target @rel style="z-index: 2"> 698 </a> 699 } 700 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media").GetItem("Image").GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 701 </div> 702 703 } 704 705 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 706 @using System.Linq 707 708 @if(hasText || hasHeading){ 709 <div class="d-flex @(posterHeight == "none" ? string.Empty : "position-absolute top-0 bottom-0")"> 710 <div class="container-xl mx-auto px-0 py-5 row"> 711 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 712 @using System.Linq 713 714 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 715 { 716 717 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 718 { 719 string headerKey = ""; 720 string headerMarkup = ""; 721 string headingStart = ""; 722 string headingEnd = ""; 723 int headerCount = 0; 724 725 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 726 <div class="p-txt-container-wrap w-100"> 727 @foreach (var heading in headings) 728 { 729 string headningSize = heading.GetString("Size"); 730 string headingDisplaySize = heading.GetString("DisplaySize"); 731 bool headingAccentColor = heading.GetBoolean("AccentColor"); 732 bool headingAccentLine = heading.GetBoolean("AccentLine"); 733 734 if (headerKey != headningSize) 735 { 736 if (headerCount > 0) 737 { 738 headingEnd = $"</{headningSize}>"; 739 headerMarkup += headingEnd; 740 } 741 headerKey = headningSize; 742 headingStart = $"<{headningSize}>"; 743 headerMarkup += headingStart; 744 } 745 else if (headerCount > 0 && headerKey == headningSize) 746 { 747 headerMarkup += "<br>"; 748 } 749 750 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 751 headerMarkup += heading.GetString("Heading"); 752 headerMarkup += "</span>"; 753 754 headerCount++; 755 756 if (headerCount == headings.Count()) 757 { 758 headingEnd = $"</{headningSize}>"; 759 headerMarkup += headingEnd; 760 } 761 } 762 763 @if (headerMarkup != "") 764 { 765 @headerMarkup 766 } 767 768 769 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 770 { 771 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 772 } 773 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 774 { 775 @Model.Item.GetItem("Panel_Text").GetString("Text") 776 } 777 778 @RenderButtons() 779 </div> 780 </div> 781 } 782 } 783 784 </div> 785 </div> 786 } 787 788 </div> 789 790 </div> 791 } 792 else 793 { 794 795 if( hasImage || hasGraphic || hasVideo || hasLead || hasText || hasHeading || hasButton || promotionalProduct != null) 796 { 797 798 <div class="p-panel-container row @textHeight @imgPlacement @(hasTheme ? "theme " + Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 799 800 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Header", out headerFieldValueViewModel)) 801 { 802 if (headerFieldValueViewModel.Value != null) 803 { 804 string promotionalHeaderText = headerFieldValueViewModel.Value.ToString(); 805 promotionalHeaderText = promotionalHeaderText.Replace("{{D1}}", "<span class=\"display-1\">"); 806 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1}}", "</span>"); 807 promotionalHeaderText = promotionalHeaderText.Replace("{{D1:AccentColor}}", "<span class=\"display-1 text-accent\">"); 808 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1:AccentColor}}", "</span>"); 809 promotionalHeaderText = promotionalHeaderText.Replace("{{D2}}", "<span class=\"display-2\">"); 810 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2}}", "</span>"); 811 promotionalHeaderText = promotionalHeaderText.Replace("{{D2:AccentColor}}", "<span class=\"display-2 text-accent\">"); 812 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2:AccentColor}}", "</span>"); 813 promotionalHeaderText = promotionalHeaderText.Replace("{{D3}}", "<span class=\"display-3\">"); 814 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3}}", "</span>"); 815 promotionalHeaderText = promotionalHeaderText.Replace("{{D3:AccentColor}}", "<span class=\"display-3 text-accent\">"); 816 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3:AccentColor}}", "</span>"); 817 promotionalHeaderText = promotionalHeaderText.Replace("®", "<sup>®</sup>"); 818 promotionalHeaderText = promotionalHeaderText.Replace("{{BR}}", "<br>"); 819 820 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 821 <div class="p-txt-container-wrap"> 822 <h2> 823 @promotionalHeaderText 824 </h2> 825 </div> 826 </div> 827 } 828 } 829 830 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Image", out imageFieldValueViewModel)) 831 { 832 if (imageFieldValueViewModel.Value != null) 833 { 834 string imagePath = imageFieldValueViewModel.Value.ToString(); 835 var promotionalImageParms = new Dictionary<string, object>(); 836 promotionalImageParms.Add("loading", "lazy"); 837 promotionalImageParms.Add("columns", Model.GridRowColumnCount); 838 839 promotionalImageParms.Add("fullwidth", true); 840 promotionalImageParms.Add("cssClass", "img-fluid w-100"); 841 promotionalImageParms.Add("style", "max-width: 60rem;transform: translateY(-6rem);margin-bottom: -6rem;"); 842 843 <div class="p-img-container d-flex justify-content-center"> 844 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, promotionalImageParms) 845 </div> 846 } 847 } 848 849 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Text", out textFieldValueViewModel)) 850 { 851 if (textFieldValueViewModel.Value != null) 852 { 853 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 854 <div class="p-txt-container-wrap" style="max-width: 70rem;"> 855 @textFieldValueViewModel.Value 856 </div> 857 </div> 858 } 859 } 860 861 @if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 862 { 863 if (Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null) 864 { 865 866 string imgPadding = string.Empty; 867 868 if (headings.Count() > 0 && imgFloat == "top") 869 { 870 imgPadding = "mb-4"; 871 } 872 873 else if (buttons.Any() && imgFloat == "top") 874 { 875 imgPadding = "mb-4"; 876 } 877 878 else if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text")) && imgFloat == "top") 879 { 880 imgPadding = "mb-4"; 881 } 882 883 else 884 { 885 imgPadding = "mb-4 mb-sm-0"; 886 } 887 888 string imgAlignment = string.Empty; 889 890 if(imgPosition == "image-left") 891 { 892 imgAlignment = "me-auto"; 893 } 894 else if(imgPosition == "image-right") 895 { 896 imgAlignment = "ms-auto"; 897 } 898 else 899 { 900 imgAlignment = "mx-auto"; 901 } 902 903 var offsets = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Offsets"); 904 905 string desktopOffset = string.Empty; 906 string mobileOffset = string.Empty; 907 string tabletOffset = string.Empty; 908 string XLOffset = string.Empty; 909 910 if(offsets != null) 911 { 912 if(!string.IsNullOrEmpty(offsets.GetString("Offset"))) 913 { 914 desktopOffset = $"transform: translate({offsets.GetString("Offset")});"; 915 } 916 if(!string.IsNullOrEmpty(offsets.GetString("Mobile"))) 917 { 918 mobileOffset = $"transform: translate({offsets.GetString("Mobile")});"; 919 } 920 if(!string.IsNullOrEmpty(offsets.GetString("Tablet"))) 921 { 922 tabletOffset = $"transform: translate({offsets.GetString("Tablet")});"; 923 } 924 if(!string.IsNullOrEmpty(offsets.GetString("XL"))) 925 { 926 XLOffset = $"transform: translate({offsets.GetString("XL")});"; 927 } 928 } 929 930 if (!string.IsNullOrEmpty(mobileOffset) || !string.IsNullOrEmpty(tabletOffset) || !string.IsNullOrEmpty(desktopOffset) || !string.IsNullOrEmpty(XLOffset)) 931 { 932 <style> 933 @if (!string.IsNullOrEmpty(mobileOffset)) 934 { 935 <text> 936 @@media (min-width: 300px) { 937 [id='@(Model.ID)'] .p-img-container { 938 @mobileOffset 939 } 940 } 941 </text> 942 } 943 @if (!string.IsNullOrEmpty(tabletOffset)) 944 { 945 <text> 946 @@media (min-width: 768px) { 947 [id='@(Model.ID)'] .p-img-container { 948 @tabletOffset 949 } 950 } 951 </text> 952 } 953 954 @if (!string.IsNullOrEmpty(desktopOffset)) 955 { 956 <text> 957 @@media(min-width: 992px) 958 { 959 [id='@(Model.ID)'] .p-img-container { 960 @desktopOffset 961 } 962 } 963 </text> 964 } 965 966 @if (!string.IsNullOrEmpty(XLOffset)) 967 { 968 <text> 969 @@media(min-width: 1920px) 970 { 971 [id='@(Model.ID)'] .p-img-container { 972 @XLOffset 973 } 974 } 975 </text> 976 } 977 978 [id='@(Model.ID)'] .p-img-container { 979 z-index: 2; 980 position: relative; 981 } 982 </style> 983 } 984 985 <div class="@imgPadding p-img-container @colSizeClasslist @imgAlignment"> 986 987 @if (link != null && !string.IsNullOrEmpty(link.Url)) 988 { 989 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 990 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 991 <a href="@link.Url" @target @rel> 992 @RenderImage() 993 </a> 994 } 995 else 996 { 997 @RenderImage() 998 } 999 1000 </div> 1001 } 1002 1003 } 1004 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 1005 { 1006 <div class="p-graphic-container mb-3 col flex-grow-0 pe-0"> 1007 <div class="@(layout) [email protected]("Panel_Media").GetItem("Graphic").GetString("GraphicSize")"> 1008 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel()) 1009 </div> 1010 </div> 1011 1012 } 1013 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Video") 1014 { 1015 if (Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") != "video-poster") 1016 { 1017 <div class="p-video-container"> 1018 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1019 @using Dynamicweb.Ecommerce.ProductCatalog 1020 1021 @{ 1022 1023 1024 string visual = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Visual", "inline"); 1025 1026 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1027 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1028 1029 Dynamicweb.Frontend.FileViewModel video = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPath"); 1030 string videoPath = video?.Path ?? ""; 1031 1032 string posterPath = "/Admin/Public/GetImage.ashx?image=" + @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster") + "&width=1000&format=webp"; 1033 1034 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/play.svg"; 1035 string theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 1036 } 1037 1038 1039 @switch(visual) { 1040 case "inline" : 1041 <div class="h-100 position-relative grid grid-1"> 1042 1043 @switch (provider) 1044 { 1045 case "youtube" : 1046 case "vimeo" : 1047 1048 <div 1049 id="[email protected]" 1050 class="player plyr__video-embed @(theme) h-100 w-100" 1051 data-plyr-provider="@provider" 1052 data-plyr-embed-id="@videoId" 1053 style="--plyr-color-main: var(--swift-foreground-color); " 1054 > 1055 </div> 1056 1057 break; 1058 1059 case "self-hosted" : 1060 1061 <video 1062 id="[email protected]" 1063 class="player plyr__video-embed @(theme) h-100 w-100" 1064 src="@videoPath" 1065 style="--plyr-color-main: var(--swift-foreground-color);" 1066 preload="metadata" 1067 poster="@posterPath"> 1068 </video> 1069 1070 break; 1071 } 1072 <script type="module" defer src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1073 <script type="module" defer> 1074 1075 const player = new Plyr('#[email protected]', { 1076 type: 'video', 1077 youtube: { 1078 noCookie: true, 1079 showinfo: 0 1080 }, 1081 fullscreen: { 1082 enabled: true, 1083 iosNative: true, 1084 } 1085 }); 1086 </script> 1087 1088 </div> 1089 1090 break; 1091 1092 case "poster-modal" : 1093 <div class="h-100 position-relative@(theme) grid grid-1"> 1094 <div class="player position-relative" data-player="[email protected]"> 1095 1096 @RenderVideo() 1097 1098 <div class="position-absolute top-0 bottom-0 end-0 start-0 h-100 d-flex align-items-center justify-content-center gradient-overlay"> 1099 <button type="button" class="btn btn-primary rounded-circle lh-1 p-3" data-bs-toggle="modal" data-bs-target="#[email protected]"> 1100 <span class="icon-3"> 1101 @ReadFile(iconPath) 1102 </span> 1103 <span class="visually-hidden">@Translate("Play video")</span> 1104 </button> 1105 </div> 1106 </div> 1107 </div> 1108 1109 <div class="modal fade" id="[email protected]" tabindex="-1" aria-hidden="true"> 1110 <div class="modal-dialog modal-xl modal-dialog-centered"> 1111 <div class="modal-content"> 1112 <div class="modal-body p-0"> 1113 1114 @switch (provider) 1115 { 1116 case "youtube" : 1117 case "vimeo" : 1118 1119 <div 1120 id="[email protected]" 1121 class="player plyr__video-embed @(theme) h-100 w-100" 1122 data-plyr-provider="@provider" 1123 data-plyr-embed-id="@videoId" 1124 style="--plyr-color-main: var(--swift-foreground-color); " 1125 > 1126 </div> 1127 1128 break; 1129 1130 case "self-hosted" : 1131 1132 <video 1133 id="[email protected]" 1134 class="player plyr__video-embed @(theme) h-100 w-100" 1135 src="@videoPath" 1136 style="--plyr-color-main: var(--swift-foreground-color);" 1137 preload="metadata" 1138 > 1139 </video> 1140 1141 break; 1142 } 1143 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1144 <script type="module"> 1145 1146 var player = new Plyr('#[email protected]', { 1147 youtube: { 1148 noCookie: true, 1149 showinfo: 0 1150 }, 1151 fullscreen: { 1152 enabled: true, 1153 iosNative: true, 1154 } 1155 }); 1156 1157 document.querySelector('#[email protected]').addEventListener('show.bs.modal', function (event) { 1158 player.togglePlay(); 1159 1160 player.on('ready', event => { 1161 player.play(); 1162 }); 1163 }); 1164 1165 document.querySelector('#[email protected]').addEventListener('hide.bs.modal', function (event) { 1166 player.pause(); 1167 }); 1168 </script> 1169 1170 </div> 1171 </div> 1172 </div> 1173 </div> 1174 1175 break; 1176 } 1177 1178 @helper RenderVideo() 1179 { 1180 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1181 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1182 string ratio = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("AspectRatio", ""); 1183 ratio = ratio != "0" ? ratio : ""; 1184 string ratioCssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 1185 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : ""; 1186 string fillClass = ratio == "fill" ? " h-100" : ""; 1187 1188 var parms = new Dictionary<string, object>(); 1189 parms.Add("loading", "lazy"); 1190 if (ratio == "fill") { 1191 parms.Add("cssClass", "w-100 h-100"); 1192 } 1193 else 1194 { 1195 parms.Add("cssClass", "mw-100 mh-100"); 1196 } 1197 parms.Add("style",""); 1198 parms.Add("alt", @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("ImageAltText")); 1199 parms.Add("columns", Model.GridRowColumnCount); 1200 1201 <figure class="m-0@(ratioCssClass)@(fillClass)" @ratioVariable> 1202 1203 @if (string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster"))) 1204 { 1205 switch (provider) 1206 { 1207 case "youtube" : 1208 @RenderYouTubePoster(videoId) 1209 break; 1210 1211 case "vimeo" : 1212 @RenderVimeoPoster(videoId) 1213 break; 1214 } 1215 } 1216 else 1217 { 1218 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPoster") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 1219 } 1220 1221 </figure> 1222 } 1223 1224 @helper RenderYouTubePoster(string videoId) 1225 { 1226 <script type="module"> 1227 function setVideoThumbnail(source) { 1228 var figure = document.querySelector("[data-player='[email protected]'] figure"); 1229 var thumbnail = document.createElement("img"); 1230 thumbnail.style = "object-fit: cover;"; 1231 thumbnail.classList.add('mw-100','mh-100'); 1232 thumbnail.src = source; 1233 figure.appendChild(thumbnail); 1234 }; 1235 setVideoThumbnail('https://i.ytimg.com/vi/@(videoId)/hqdefault.jpg'); 1236 </script> 1237 } 1238 1239 @helper RenderVimeoPoster(string videoId) 1240 { 1241 <script type="module"> 1242 function setVideoThumbnail(source) { 1243 let figure = document.querySelector("[data-player='[email protected]'] figure"); 1244 let thumbnail = document.createElement("img"); 1245 thumbnail.style = "object-fit: cover;"; 1246 thumbnail.classList.add('mw-100','mh-100'); 1247 thumbnail.src = source; 1248 figure.appendChild(thumbnail); 1249 }; 1250 function getVimeoThumbnail() { 1251 fetch('https://vimeo.com/api/v2/video/@(videoId).json') 1252 .then(function(response) { 1253 return response.text(); 1254 }) 1255 .then(function(data) { 1256 let { thumbnail_large } = JSON.parse(data)[0]; 1257 let thumbnail = `${thumbnail_large}`; 1258 thumbnail = thumbnail.replace("_640", "_1920"); 1259 setVideoThumbnail(thumbnail); 1260 }) 1261 .catch(error => { 1262 console.log(error); 1263 }); 1264 } 1265 1266 getVimeoThumbnail(); 1267 </script> 1268 } 1269 1270 </div> 1271 } 1272 } 1273 1274 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1275 @using System.Linq 1276 1277 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 1278 { 1279 1280 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1281 { 1282 string headerKey = ""; 1283 string headerMarkup = ""; 1284 string headingStart = ""; 1285 string headingEnd = ""; 1286 int headerCount = 0; 1287 1288 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 1289 <div class="p-txt-container-wrap w-100"> 1290 @foreach (var heading in headings) 1291 { 1292 string headningSize = heading.GetString("Size"); 1293 string headingDisplaySize = heading.GetString("DisplaySize"); 1294 bool headingAccentColor = heading.GetBoolean("AccentColor"); 1295 bool headingAccentLine = heading.GetBoolean("AccentLine"); 1296 1297 if (headerKey != headningSize) 1298 { 1299 if (headerCount > 0) 1300 { 1301 headingEnd = $"</{headningSize}>"; 1302 headerMarkup += headingEnd; 1303 } 1304 headerKey = headningSize; 1305 headingStart = $"<{headningSize}>"; 1306 headerMarkup += headingStart; 1307 } 1308 else if (headerCount > 0 && headerKey == headningSize) 1309 { 1310 headerMarkup += "<br>"; 1311 } 1312 1313 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 1314 headerMarkup += heading.GetString("Heading"); 1315 headerMarkup += "</span>"; 1316 1317 headerCount++; 1318 1319 if (headerCount == headings.Count()) 1320 { 1321 headingEnd = $"</{headningSize}>"; 1322 headerMarkup += headingEnd; 1323 } 1324 } 1325 1326 @if (headerMarkup != "") 1327 { 1328 @headerMarkup 1329 } 1330 1331 1332 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 1333 { 1334 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 1335 } 1336 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1337 { 1338 @Model.Item.GetItem("Panel_Text").GetString("Text") 1339 } 1340 1341 @RenderButtons() 1342 </div> 1343 </div> 1344 } 1345 } 1346 1347 1348 </div> 1349 } 1350 else 1351 { 1352 if(Pageview.IsVisualEditorMode) { 1353 <div class="alert alert-warning" role="alert"> 1354 This paragraph is empty 1355 </div> 1356 } 1357 } 1358 } 1359 @Model.GetModuleOutput() 1360

    Værd at vide

    • Vælg det rigtige fodtøj
    • Værd at vide
    • Hvad er ESD?
    • BOA® Fit System
    • Certificeringer og symboler
    • Reklamationsformular

    Services

    • Find forhandler
    • Messeoversigt
    • Sponsorater
    • Downloads
    • Karriere
    • Log ind
    Error executing template "Designs/Swift/Paragraph/Base_Panel.cshtml"
    System.NullReferenceException: Object reference not set to an instance of an object.
       at CompiledRazorTemplates.Dynamic.RazorEngine_9ae15ff2a1324c908ed02e4e2f8692ec.Execute() in D:\Dynamicweb.NET\Solutions\Sika\Files\Templates\Designs\Swift\Paragraph\Base_Panel.cshtml:line 619
       at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
       at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
       at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
       at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
       at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
       at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
       at Dynamicweb.Rendering.Template.RenderRazorTemplate()
    
    1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using System.Collections.Generic 4 @using System.Linq 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @helper RenderButtons() 8 { 9 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 10 int loopCounter = 0; 11 12 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 13 14 string linkType = string.Empty; 15 16 foreach (var button in buttons) 17 { 18 loopCounter++; 19 } 20 21 if (buttons.Any()) 22 { 23 <div class="d-flex flex-wrap grid"> 24 @foreach (var button in buttons) 25 { 26 27 linkType = button.GetItem("Link").GetString("LinkType"); 28 29 if (linkType == "page" && button.GetItem("Link").GetLink("ButtonLink") != null) 30 { 31 link = button.GetItem("Link").GetLink("ButtonLink"); 32 } 33 34 if (linkType == "product-group") 35 { 36 37 IList<ProductGroupViewModel> selectedGroups = button.GetItem("Link").GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 38 39 IList<string> groupIds = new List<string> { }; 40 41 if (selectedGroups != null) 42 { 43 foreach (var fromGroup in selectedGroups) 44 { 45 groupIds.Add(fromGroup.Id); 46 } 47 } 48 link = new Dynamicweb.Frontend.LinkViewModel() 49 { 50 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds).Trim(), 51 IsExternal = false 52 }; 53 } 54 55 if (linkType == "product") 56 { 57 ProductListViewModel products = button.GetItem("Link").GetValue<ProductListViewModel>("ProductLink"); 58 IList<string> productIds = new List<string> { }; 59 string productPrimaryOrDefaultGroupID = string.Empty; 60 string pageTag = "Shop"; 61 62 if (products != null) 63 { 64 foreach (ProductViewModel product in products.Products) 65 { 66 productIds.Add(product.Id); 67 productPrimaryOrDefaultGroupID = product.PrimaryOrDefaultGroup.Id; 68 } 69 } 70 71 string productParameter = "MainProductId"; 72 string productGroupParameter = string.Empty; 73 if (productIds.Count == 1) 74 { 75 productParameter = "ProductID"; 76 if (!string.IsNullOrEmpty(productPrimaryOrDefaultGroupID)) 77 { 78 productGroupParameter = $"&GroupID={productPrimaryOrDefaultGroupID}"; 79 } 80 } 81 82 link = new Dynamicweb.Frontend.LinkViewModel() 83 { 84 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + productGroupParameter + "&" + productParameter + "=" + string.Join(",", productIds).Trim(), 85 IsExternal = false 86 }; 87 } 88 89 if (!string.IsNullOrEmpty(button.GetItem("Link").GetString("ButtonLink")) || !string.IsNullOrEmpty(button.GetItem("Link").GetString("ProductLink"))) 90 { 91 string classes = ""; 92 93 if (button.GetString("ButtonStyling") != "none") 94 { 95 classes = $"btn btn-{button.GetString("ButtonStyling")}"; 96 } 97 98 <p class="@(button.GetBoolean("NoWrap") ? "w-100" : "")"> 99 <a class="@classes" href="@link" target="@(link.Url.Contains("http") == true || link.Url.Contains("/Files/Files/") ? "_blank" : string.Empty)"> 100 @if (!string.IsNullOrEmpty(button.GetString("Icon"))) 101 { 102 <span class="icon-2" aria-hidden="true"> 103 @ReadFile(button.GetString("Icon")) 104 </span> 105 } 106 107 @button.GetString("ButtonText") 108 </a> 109 </p> 110 } 111 } 112 </div> 113 } 114 } 115 116 @using System.Collections.Generic 117 @using System.Linq 118 @using Dynamicweb.Content.Items 119 120 @functions 121 { 122 123 public string GetContainerClassList(Dynamicweb.Frontend.GridRowViewModel model) 124 { 125 List<string> returnValues = new List<string>(); 126 string container = "container-xl"; 127 128 if (model.Item.GetString("Width") == "bleed") 129 { 130 if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-end") 131 { 132 container = "container-xl me-lg-0 pe-lg-0"; 133 } 134 else if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-start") 135 { 136 container = "container-xl ms-lg-0 ps-lg-0"; 137 } 138 else 139 { 140 container = "container-fluid mx-0 px-0"; 141 } 142 } 143 144 returnValues.Add(container); 145 return string.Join(" ", returnValues); 146 } 147 148 149 150 public string GetColumnWidthClassList(Dynamicweb.Frontend.ItemViewModel model, bool isVisualEditor = false) 151 { 152 153 string columnWidth = isVisualEditor ? "col" : ""; 154 string mobileWidth = string.Empty; 155 string tabletWidth = string.Empty; 156 string desktopWidth = string.Empty; 157 string XLWidth = string.Empty; 158 159 if (model != null) 160 { 161 162 if (model.GetField("Mobile").GetRawValue() != null && model.GetField("Mobile").GetRawValue().ToString() != "auto") 163 { 164 165 mobileWidth = "col-" + model.GetField("Mobile").GetRawValue(); 166 if (model.GetField("Tablet").GetRawValue() == null) 167 { 168 mobileWidth = mobileWidth + " col-sm"; 169 } 170 } 171 if (model.GetField("Width").GetRawValue() != null && model.GetField("Width").GetRawValue().ToString() != "auto") 172 { 173 desktopWidth = "col-md-" + model.GetField("Width").GetRawValue(); 174 } 175 if (model.GetField("Tablet").GetRawValue() != null && model.GetField("Tablet").GetRawValue().ToString() != "auto") 176 { 177 178 desktopWidth = " col-lg-" + model.GetField("Width").GetRawValue(); 179 tabletWidth = "col-md-" + model.GetField("Tablet").GetRawValue(); 180 if (model.GetField("XL").GetRawValue() == null) 181 { 182 tabletWidth = tabletWidth + " col-lg-" + model.GetField("Width").GetRawValue(); 183 } 184 } 185 if (model.GetField("XL").GetRawValue() != null && model.GetField("XL").GetRawValue().ToString() != "auto") 186 { 187 XLWidth = "col-xxxl-" + model.GetField("XL").GetRawValue(); 188 } 189 190 columnWidth = $"col {mobileWidth} {tabletWidth} {desktopWidth} {XLWidth}"; 191 192 } 193 return string.Join(" ", columnWidth); 194 } 195 196 public string GetRowWidthClassList(Dynamicweb.Frontend.GridRowViewModel model) 197 { 198 List<string> returnValues = new List<string>(); 199 200 string rowWidth = model.Item.GetRawValueString("Width", string.Empty).ToLower(); 201 202 if (rowWidth == "6") 203 { 204 returnValues.Add("col-12 col-lg-6"); 205 } 206 if (rowWidth == "8") 207 { 208 returnValues.Add("col-12 col-lg-8"); 209 } 210 if (rowWidth == "9") 211 { 212 returnValues.Add("col-12 col-lg-9"); 213 } 214 if (rowWidth == "10") 215 { 216 returnValues.Add("col-12 col-lg-10"); 217 } 218 if (rowWidth == "12") 219 { 220 returnValues.Add("col-12 col-lg-12"); 221 } 222 if (rowWidth == "bleed") 223 { 224 returnValues.Add("col-12"); 225 } 226 227 return string.Join(" ", returnValues); 228 } 229 230 public string GetSectionContentAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 231 { 232 List<string> returnValues = new List<string>(); 233 234 returnValues.Add(model.Item.GetRawValueString("OverallAlignment", string.Empty).ToLower()); 235 236 return string.Join(" ", returnValues); 237 } 238 239 public string GetRowHorizontalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 240 { 241 242 List<string> returnValues = new List<string>(); 243 244 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 245 246 return string.Join(" ", returnValues); 247 } 248 249 public string GetRowVerticalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 250 { 251 252 List<string> returnValues = new List<string>(); 253 254 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 255 256 return string.Join(" ", returnValues); 257 } 258 259 public string GetRowSpacing(Dynamicweb.Frontend.GridRowViewModel model) 260 { 261 List<string> returnValues = new List<string>(); 262 263 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 264 265 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 266 267 return string.Join(" ", returnValues); 268 } 269 270 public string GetRowClassList(Dynamicweb.Frontend.GridRowViewModel model) 271 { 272 273 List<string> returnValues = new List<string>(); 274 275 string mobileOrderFirst = string.Empty; 276 if (model.Item.GetBoolean("MobileOrderReverse")) 277 { 278 mobileOrderFirst = "flex-column-reverse flex-md-row"; 279 } 280 returnValues.Add(mobileOrderFirst); 281 282 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 283 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 284 285 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 286 287 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 288 289 return string.Join(" ", returnValues); 290 } 291 292 public string GetSectionClassList(Dynamicweb.Frontend.GridRowViewModel model) 293 { 294 List<string> returnValues = new List<string>(); 295 returnValues.Add($"item_{model.Item.SystemName.ToLower()}"); 296 returnValues.Add(!string.IsNullOrWhiteSpace(model.Item.GetRawValueString("Theme")) ? " theme " + model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""); 297 string paddingTop = model.Item.GetRawValueString("PaddingTop", "large"); 298 string paddingBottom = model.Item.GetRawValueString("PaddingBottom", "large"); 299 300 if (paddingTop == "none") 301 { 302 returnValues.Add("pt-0"); 303 } 304 if (paddingTop == "small") 305 { 306 returnValues.Add("pt-4"); 307 } 308 if (paddingTop == "medium") 309 { 310 returnValues.Add("pt-5"); 311 } 312 if (paddingTop == "large") { 313 returnValues.Add("pt-7"); 314 } 315 316 if (paddingBottom == "none") 317 { 318 returnValues.Add("pb-0"); 319 } 320 if (paddingBottom == "small") 321 { 322 returnValues.Add("pb-4"); 323 } 324 if (paddingBottom == "medium") 325 { 326 returnValues.Add("pb-5"); 327 } 328 if (paddingBottom == "large") { 329 returnValues.Add("pb-7"); 330 } 331 332 var decorations = model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 333 var cssClasses = new List<string> { }; 334 335 foreach (var itemId in decorations) 336 { 337 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 338 339 if (item != null) 340 { 341 item.TryGetValue("Class", out object classes); 342 343 if (classes is null) 344 { 345 continue; 346 } 347 348 var cssString = (string)classes; 349 if (cssString.StartsWith("[")) 350 { 351 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 352 cssClasses.AddRange(cssArray); 353 } 354 else 355 { 356 cssClasses.Add(cssString.Replace(",", " ")); 357 } 358 } 359 } 360 returnValues.Add(string.Join(" ", cssClasses).Trim()); 361 362 return string.Join(" ", returnValues); 363 } 364 365 } 366 367 368 @helper RenderImage() 369 { 370 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("Image"))) 371 { 372 string ratioCssClass = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "ratio" : string.Empty; 373 string ratioVariable = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "style=\"--bs-aspect-ratio: " + Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") + "\"" : string.Empty; 374 string ImageObjectFit = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageObjectFit", string.Empty); 375 ImageObjectFit = ImageObjectFit == "cover" ? string.Empty : ImageObjectFit; 376 ImageObjectFit = ImageObjectFit == "contain" ? "object-fit:contain" : ImageObjectFit; 377 378 var parms = new Dictionary<string, object>(); 379 parms.Add("loading", "lazy"); 380 parms.Add("style", ImageObjectFit); 381 parms.Add("alt", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageAltText")); 382 parms.Add("columns", Model.GridRowColumnCount); 383 384 parms.Add("fullwidth", true); 385 parms.Add("cssClass", "img-fluid w-100 " + Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageCustomClasses")); 386 387 388 <figure class="mb-0 @ratioCssClass" @ratioVariable> 389 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 390 </figure> 391 } 392 } 393 394 @{ 395 var colSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("ColumnWidth")); 396 397 string imgPosition = string.Empty; 398 string imgPlacement = string.Empty; 399 string imgFloat = string.Empty; 400 401 if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 402 { 403 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement"); 404 } 405 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 406 { 407 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetString("ImagePlacement"); 408 } 409 410 if (imgPosition == "image-top") 411 { 412 imgPlacement = "flex-column"; 413 imgFloat = "top"; 414 } else if (imgPosition == "image-left") 415 { 416 imgPlacement = "flex-column flex-md-row"; 417 imgFloat = "left-right"; 418 } else if (imgPosition == "image-right") 419 { 420 imgPlacement = "flex-column flex-md-row-reverse"; 421 imgFloat = "left-right"; 422 } 423 424 425 426 var parms = new Dictionary<string, object>(); 427 parms.Add("cssClass", "h-100 w-100"); 428 429 } 430 431 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 432 @using Dynamicweb.Ecommerce.ProductCatalog 433 @using System.IO 434 @using Dynamicweb.Frontend 435 436 @{ 437 bool movePageBehind = false; 438 bool isFirstPoster = false; 439 string movePageBehindClass = ""; 440 if (Pageview.Page.PropertyItem != null) 441 { 442 string headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 443 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 444 445 if (movePageBehind) 446 { 447 movePageBehindClass = " poster-behind"; 448 if (!Dynamicweb.Context.Current.Items.Contains("firstPosterIsRendered")) 449 { 450 isFirstPoster = true; 451 Dynamicweb.Context.Current.Items.Add("firstPosterIsRendered", true); 452 } 453 454 } 455 456 } 457 } 458 459 @if (movePageBehind && isFirstPoster) 460 { 461 <script> 462 ['resize', 'load'].forEach(function (e) { 463 window.addEventListener(e, () => swift.Scroll.setContentPosition()); 464 }); 465 </script> 466 } 467 468 @using System.Collections.Generic 469 @using System.Linq 470 471 @{ 472 var headings = Model.Item?.GetItem("Panel_Text")?.GetItems("Headings") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 473 var widths = Model.Item?.GetItem("Panel_Text")?.GetItems("ColumnTest1") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 474 string layout = Model.Item?.GetItem("Panel_Text")?.GetRawValueString("Layout"); 475 var textColSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Text")?.GetItem("ColumnWidth")); 476 477 var textHeight = string.Empty; 478 479 if (layout == "top-left") 480 { 481 layout = "d-flex flex-column align-items-start"; 482 } else if (layout == "top-center") 483 { 484 layout = "d-flex flex-column align-items-center text-center mx-auto"; 485 } 486 else if (layout == "top-right") 487 { 488 layout = "d-flex flex-column align-items-end text-end ms-auto"; 489 } 490 else if (layout == "center-left") 491 { 492 layout = "d-flex flex-column justify-content-center"; 493 } 494 else if (layout == "center") 495 { 496 layout = "d-flex flex-column justify-content-center align-items-center text-center mx-auto"; 497 } 498 else if (layout == "center-right") 499 { 500 layout = "d-flex flex-column justify-content-center align-items-end text-end ms-auto"; 501 } 502 else if (layout == "bottom-left") 503 { 504 layout = "d-flex flex-column justify-content-end"; 505 } 506 else if (layout == "bottom-center") 507 { 508 layout = "d-flex flex-column justify-content-end align-items-center text-center mx-auto"; 509 } 510 else if (layout == "bottom-right") 511 { 512 layout = "d-flex flex-column justify-content-end align-items-end text-end ms-auto"; 513 } 514 } 515 516 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 517 @using System.Collections.Generic 518 @using Dynamicweb.Ecommerce.ProductCatalog 519 520 @{ 521 string linkType = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") != string.Empty ? Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") : string.Empty; 522 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 523 524 if (linkType == "page" && Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink") != null) 525 { 526 link = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink"); 527 } 528 529 if (linkType == "product-group") 530 { 531 IList<ProductGroupViewModel> selectedGroups = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 532 IList<string> groupIds = new List<string> {}; 533 534 if (selectedGroups != null) 535 { 536 foreach (var fromGroup in selectedGroups) 537 { 538 groupIds.Add(fromGroup.Id); 539 } 540 } 541 542 link = new Dynamicweb.Frontend.LinkViewModel() 543 { 544 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds) 545 }; 546 } 547 548 if (linkType == "product") 549 { 550 ProductListViewModel products = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<ProductListViewModel>("ProductLink"); 551 IList<string> productIds = new List<string> {}; 552 553 if (products != null) 554 { 555 foreach (var product in products.Products) 556 { 557 productIds.Add(product.Id); 558 } 559 } 560 561 string productParameter = productIds.Count == 1 ? "ProductID" : "MainProductId"; 562 string pageTag = productIds.Count == 1 ? "ProductDetailPage" : "Shop"; 563 link = new Dynamicweb.Frontend.LinkViewModel() 564 { 565 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + "&" + productParameter + "=" + string.Join(",", productIds) 566 }; 567 } 568 569 } 570 571 572 @{ 573 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 574 bool hasImage = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null; 575 bool hasGraphic = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") != null; 576 bool hasVideo = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Media" )?.GetItem( "Video" ).GetString( "VideoSourceID" ) ); 577 bool hasLead = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Lead" ) ); 578 bool hasText = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Text" ) ); 579 bool hasTheme = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) ); 580 bool hasHeading = headings.Count() > 0; 581 bool hasButton = buttons.Any(); 582 583 var decorations = Model.Item?.GetItem( "Panel_Settings" )?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 584 var cssClasses = new List<string> { }; 585 string cssDecorations = ""; 586 587 foreach (var itemId in decorations) 588 { 589 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 590 591 if (item != null) 592 { 593 item.TryGetValue("Class", out object classes); 594 595 if (classes is null) 596 { 597 continue; 598 } 599 600 var cssString = (string)classes; 601 if (cssString.StartsWith("[")) 602 { 603 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 604 cssClasses.AddRange(cssArray); 605 } 606 else 607 { 608 cssClasses.Add(cssString.Replace(",", " ")); 609 } 610 } 611 } 612 cssDecorations = string.Join(" ", cssClasses).Trim(); 613 614 ProductViewModel promotionalProduct = null; 615 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 616 { 617 promotionalProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 618 } 619 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 620 { 621 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 622 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 623 624 if (productList?.Products is object) 625 { 626 promotionalProduct = productList.Products[0]; 627 } 628 } 629 630 CategoryFieldViewModel categoryFieldViewModel = null; 631 FieldValueViewModel headerFieldValueViewModel = null; 632 FieldValueViewModel imageFieldValueViewModel = null; 633 FieldValueViewModel textFieldValueViewModel = null; 634 635 if (promotionalProduct != null ) 636 { 637 promotionalProduct.ProductCategories.TryGetValue("Promotional", out categoryFieldViewModel); 638 } 639 } 640 641 @if (Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement") == "image-poster" || Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") == "video-poster") 642 { 643 644 <div class="p-poster-container poster-overlay theme h-100 @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 645 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 646 647 @{ 648 string theme = string.Empty; 649 string posterHeight = string.Empty; 650 string mediaType = Model.Item.GetItem("Panel_Media").GetString("Media"); 651 652 if ( mediaType == "video") 653 { 654 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("Height"); 655 656 theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 657 } else if (mediaType == "image") 658 { 659 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Image").GetString("Height"); 660 661 theme = !string.IsNullOrWhiteSpace(Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme")) ? " theme " + Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; 662 663 } 664 665 posterHeight = posterHeight == "auto" ? "h-100" : posterHeight; 666 posterHeight = posterHeight == "small" ? "min-vh-50 min-vh-md-50" : posterHeight; 667 posterHeight = posterHeight == "medium" ? "min-vh-50 min-vh-md-75" : posterHeight; 668 posterHeight = posterHeight == "large" ? "min-vh-100 min-vh-md-100" : posterHeight; 669 posterHeight = posterHeight == "1x1" ? "ratio ratio-1x1 mx-auto" : posterHeight; 670 posterHeight = posterHeight == "4x3" ? "ratio ratio-4x3 mx-auto" : posterHeight; 671 posterHeight = posterHeight == "16x9" ? "ratio ratio-16x9 mx-auto" : posterHeight; 672 posterHeight = posterHeight == "9x16" ? "ratio ratio-9x16 mx-auto" : posterHeight; 673 posterHeight = posterHeight == "3x4" ? "ratio ratio-3x4 mx-auto" : posterHeight; 674 675 676 } 677 678 <div class="position-relative @(hasText || hasHeading ? "row" : "") @posterHeight @theme @(movePageBehindClass)"> 679 680 @if (Model.Item.GetItem("Panel_Media").GetString("Media") == "video") 681 { 682 <div class="p-poster-video-container position-absolute top-0 bottom-0 end-0 start-0 px-0"> 683 <video preload="auto" loop autoplay muted playsinline class="h-100 w-100" style="object-fit: cover;"> 684 <source src="@Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")" 685 type="video/@Path.GetExtension(Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")).ToLower().Replace(".", "")"> 686 </video> 687 </div> 688 689 } else if (Model.Item.GetItem("Panel_Media").GetString("Media") == "image") 690 { 691 <div class="position-absolute top-0 bottom-0 end-0 start-0 px-0"> 692 693 @if (link != null && !string.IsNullOrEmpty(link.Url)) 694 { 695 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 696 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 697 <a class="bottom-0 position-absolute top-0 w-100" href="@link.Url" @target @rel style="z-index: 2"> 698 </a> 699 } 700 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media").GetItem("Image").GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 701 </div> 702 703 } 704 705 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 706 @using System.Linq 707 708 @if(hasText || hasHeading){ 709 <div class="d-flex @(posterHeight == "none" ? string.Empty : "position-absolute top-0 bottom-0")"> 710 <div class="container-xl mx-auto px-0 py-5 row"> 711 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 712 @using System.Linq 713 714 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 715 { 716 717 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 718 { 719 string headerKey = ""; 720 string headerMarkup = ""; 721 string headingStart = ""; 722 string headingEnd = ""; 723 int headerCount = 0; 724 725 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 726 <div class="p-txt-container-wrap w-100"> 727 @foreach (var heading in headings) 728 { 729 string headningSize = heading.GetString("Size"); 730 string headingDisplaySize = heading.GetString("DisplaySize"); 731 bool headingAccentColor = heading.GetBoolean("AccentColor"); 732 bool headingAccentLine = heading.GetBoolean("AccentLine"); 733 734 if (headerKey != headningSize) 735 { 736 if (headerCount > 0) 737 { 738 headingEnd = $"</{headningSize}>"; 739 headerMarkup += headingEnd; 740 } 741 headerKey = headningSize; 742 headingStart = $"<{headningSize}>"; 743 headerMarkup += headingStart; 744 } 745 else if (headerCount > 0 && headerKey == headningSize) 746 { 747 headerMarkup += "<br>"; 748 } 749 750 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 751 headerMarkup += heading.GetString("Heading"); 752 headerMarkup += "</span>"; 753 754 headerCount++; 755 756 if (headerCount == headings.Count()) 757 { 758 headingEnd = $"</{headningSize}>"; 759 headerMarkup += headingEnd; 760 } 761 } 762 763 @if (headerMarkup != "") 764 { 765 @headerMarkup 766 } 767 768 769 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 770 { 771 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 772 } 773 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 774 { 775 @Model.Item.GetItem("Panel_Text").GetString("Text") 776 } 777 778 @RenderButtons() 779 </div> 780 </div> 781 } 782 } 783 784 </div> 785 </div> 786 } 787 788 </div> 789 790 </div> 791 } 792 else 793 { 794 795 if( hasImage || hasGraphic || hasVideo || hasLead || hasText || hasHeading || hasButton || promotionalProduct != null) 796 { 797 798 <div class="p-panel-container row @textHeight @imgPlacement @(hasTheme ? "theme " + Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 799 800 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Header", out headerFieldValueViewModel)) 801 { 802 if (headerFieldValueViewModel.Value != null) 803 { 804 string promotionalHeaderText = headerFieldValueViewModel.Value.ToString(); 805 promotionalHeaderText = promotionalHeaderText.Replace("{{D1}}", "<span class=\"display-1\">"); 806 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1}}", "</span>"); 807 promotionalHeaderText = promotionalHeaderText.Replace("{{D1:AccentColor}}", "<span class=\"display-1 text-accent\">"); 808 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1:AccentColor}}", "</span>"); 809 promotionalHeaderText = promotionalHeaderText.Replace("{{D2}}", "<span class=\"display-2\">"); 810 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2}}", "</span>"); 811 promotionalHeaderText = promotionalHeaderText.Replace("{{D2:AccentColor}}", "<span class=\"display-2 text-accent\">"); 812 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2:AccentColor}}", "</span>"); 813 promotionalHeaderText = promotionalHeaderText.Replace("{{D3}}", "<span class=\"display-3\">"); 814 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3}}", "</span>"); 815 promotionalHeaderText = promotionalHeaderText.Replace("{{D3:AccentColor}}", "<span class=\"display-3 text-accent\">"); 816 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3:AccentColor}}", "</span>"); 817 promotionalHeaderText = promotionalHeaderText.Replace("®", "<sup>®</sup>"); 818 promotionalHeaderText = promotionalHeaderText.Replace("{{BR}}", "<br>"); 819 820 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 821 <div class="p-txt-container-wrap"> 822 <h2> 823 @promotionalHeaderText 824 </h2> 825 </div> 826 </div> 827 } 828 } 829 830 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Image", out imageFieldValueViewModel)) 831 { 832 if (imageFieldValueViewModel.Value != null) 833 { 834 string imagePath = imageFieldValueViewModel.Value.ToString(); 835 var promotionalImageParms = new Dictionary<string, object>(); 836 promotionalImageParms.Add("loading", "lazy"); 837 promotionalImageParms.Add("columns", Model.GridRowColumnCount); 838 839 promotionalImageParms.Add("fullwidth", true); 840 promotionalImageParms.Add("cssClass", "img-fluid w-100"); 841 promotionalImageParms.Add("style", "max-width: 60rem;transform: translateY(-6rem);margin-bottom: -6rem;"); 842 843 <div class="p-img-container d-flex justify-content-center"> 844 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, promotionalImageParms) 845 </div> 846 } 847 } 848 849 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Text", out textFieldValueViewModel)) 850 { 851 if (textFieldValueViewModel.Value != null) 852 { 853 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 854 <div class="p-txt-container-wrap" style="max-width: 70rem;"> 855 @textFieldValueViewModel.Value 856 </div> 857 </div> 858 } 859 } 860 861 @if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 862 { 863 if (Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null) 864 { 865 866 string imgPadding = string.Empty; 867 868 if (headings.Count() > 0 && imgFloat == "top") 869 { 870 imgPadding = "mb-4"; 871 } 872 873 else if (buttons.Any() && imgFloat == "top") 874 { 875 imgPadding = "mb-4"; 876 } 877 878 else if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text")) && imgFloat == "top") 879 { 880 imgPadding = "mb-4"; 881 } 882 883 else 884 { 885 imgPadding = "mb-4 mb-sm-0"; 886 } 887 888 string imgAlignment = string.Empty; 889 890 if(imgPosition == "image-left") 891 { 892 imgAlignment = "me-auto"; 893 } 894 else if(imgPosition == "image-right") 895 { 896 imgAlignment = "ms-auto"; 897 } 898 else 899 { 900 imgAlignment = "mx-auto"; 901 } 902 903 var offsets = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Offsets"); 904 905 string desktopOffset = string.Empty; 906 string mobileOffset = string.Empty; 907 string tabletOffset = string.Empty; 908 string XLOffset = string.Empty; 909 910 if(offsets != null) 911 { 912 if(!string.IsNullOrEmpty(offsets.GetString("Offset"))) 913 { 914 desktopOffset = $"transform: translate({offsets.GetString("Offset")});"; 915 } 916 if(!string.IsNullOrEmpty(offsets.GetString("Mobile"))) 917 { 918 mobileOffset = $"transform: translate({offsets.GetString("Mobile")});"; 919 } 920 if(!string.IsNullOrEmpty(offsets.GetString("Tablet"))) 921 { 922 tabletOffset = $"transform: translate({offsets.GetString("Tablet")});"; 923 } 924 if(!string.IsNullOrEmpty(offsets.GetString("XL"))) 925 { 926 XLOffset = $"transform: translate({offsets.GetString("XL")});"; 927 } 928 } 929 930 if (!string.IsNullOrEmpty(mobileOffset) || !string.IsNullOrEmpty(tabletOffset) || !string.IsNullOrEmpty(desktopOffset) || !string.IsNullOrEmpty(XLOffset)) 931 { 932 <style> 933 @if (!string.IsNullOrEmpty(mobileOffset)) 934 { 935 <text> 936 @@media (min-width: 300px) { 937 [id='@(Model.ID)'] .p-img-container { 938 @mobileOffset 939 } 940 } 941 </text> 942 } 943 @if (!string.IsNullOrEmpty(tabletOffset)) 944 { 945 <text> 946 @@media (min-width: 768px) { 947 [id='@(Model.ID)'] .p-img-container { 948 @tabletOffset 949 } 950 } 951 </text> 952 } 953 954 @if (!string.IsNullOrEmpty(desktopOffset)) 955 { 956 <text> 957 @@media(min-width: 992px) 958 { 959 [id='@(Model.ID)'] .p-img-container { 960 @desktopOffset 961 } 962 } 963 </text> 964 } 965 966 @if (!string.IsNullOrEmpty(XLOffset)) 967 { 968 <text> 969 @@media(min-width: 1920px) 970 { 971 [id='@(Model.ID)'] .p-img-container { 972 @XLOffset 973 } 974 } 975 </text> 976 } 977 978 [id='@(Model.ID)'] .p-img-container { 979 z-index: 2; 980 position: relative; 981 } 982 </style> 983 } 984 985 <div class="@imgPadding p-img-container @colSizeClasslist @imgAlignment"> 986 987 @if (link != null && !string.IsNullOrEmpty(link.Url)) 988 { 989 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 990 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 991 <a href="@link.Url" @target @rel> 992 @RenderImage() 993 </a> 994 } 995 else 996 { 997 @RenderImage() 998 } 999 1000 </div> 1001 } 1002 1003 } 1004 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 1005 { 1006 <div class="p-graphic-container mb-3 col flex-grow-0 pe-0"> 1007 <div class="@(layout) [email protected]("Panel_Media").GetItem("Graphic").GetString("GraphicSize")"> 1008 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel()) 1009 </div> 1010 </div> 1011 1012 } 1013 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Video") 1014 { 1015 if (Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") != "video-poster") 1016 { 1017 <div class="p-video-container"> 1018 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1019 @using Dynamicweb.Ecommerce.ProductCatalog 1020 1021 @{ 1022 1023 1024 string visual = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Visual", "inline"); 1025 1026 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1027 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1028 1029 Dynamicweb.Frontend.FileViewModel video = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPath"); 1030 string videoPath = video?.Path ?? ""; 1031 1032 string posterPath = "/Admin/Public/GetImage.ashx?image=" + @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster") + "&width=1000&format=webp"; 1033 1034 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/play.svg"; 1035 string theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 1036 } 1037 1038 1039 @switch(visual) { 1040 case "inline" : 1041 <div class="h-100 position-relative grid grid-1"> 1042 1043 @switch (provider) 1044 { 1045 case "youtube" : 1046 case "vimeo" : 1047 1048 <div 1049 id="[email protected]" 1050 class="player plyr__video-embed @(theme) h-100 w-100" 1051 data-plyr-provider="@provider" 1052 data-plyr-embed-id="@videoId" 1053 style="--plyr-color-main: var(--swift-foreground-color); " 1054 > 1055 </div> 1056 1057 break; 1058 1059 case "self-hosted" : 1060 1061 <video 1062 id="[email protected]" 1063 class="player plyr__video-embed @(theme) h-100 w-100" 1064 src="@videoPath" 1065 style="--plyr-color-main: var(--swift-foreground-color);" 1066 preload="metadata" 1067 poster="@posterPath"> 1068 </video> 1069 1070 break; 1071 } 1072 <script type="module" defer src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1073 <script type="module" defer> 1074 1075 const player = new Plyr('#[email protected]', { 1076 type: 'video', 1077 youtube: { 1078 noCookie: true, 1079 showinfo: 0 1080 }, 1081 fullscreen: { 1082 enabled: true, 1083 iosNative: true, 1084 } 1085 }); 1086 </script> 1087 1088 </div> 1089 1090 break; 1091 1092 case "poster-modal" : 1093 <div class="h-100 position-relative@(theme) grid grid-1"> 1094 <div class="player position-relative" data-player="[email protected]"> 1095 1096 @RenderVideo() 1097 1098 <div class="position-absolute top-0 bottom-0 end-0 start-0 h-100 d-flex align-items-center justify-content-center gradient-overlay"> 1099 <button type="button" class="btn btn-primary rounded-circle lh-1 p-3" data-bs-toggle="modal" data-bs-target="#[email protected]"> 1100 <span class="icon-3"> 1101 @ReadFile(iconPath) 1102 </span> 1103 <span class="visually-hidden">@Translate("Play video")</span> 1104 </button> 1105 </div> 1106 </div> 1107 </div> 1108 1109 <div class="modal fade" id="[email protected]" tabindex="-1" aria-hidden="true"> 1110 <div class="modal-dialog modal-xl modal-dialog-centered"> 1111 <div class="modal-content"> 1112 <div class="modal-body p-0"> 1113 1114 @switch (provider) 1115 { 1116 case "youtube" : 1117 case "vimeo" : 1118 1119 <div 1120 id="[email protected]" 1121 class="player plyr__video-embed @(theme) h-100 w-100" 1122 data-plyr-provider="@provider" 1123 data-plyr-embed-id="@videoId" 1124 style="--plyr-color-main: var(--swift-foreground-color); " 1125 > 1126 </div> 1127 1128 break; 1129 1130 case "self-hosted" : 1131 1132 <video 1133 id="[email protected]" 1134 class="player plyr__video-embed @(theme) h-100 w-100" 1135 src="@videoPath" 1136 style="--plyr-color-main: var(--swift-foreground-color);" 1137 preload="metadata" 1138 > 1139 </video> 1140 1141 break; 1142 } 1143 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1144 <script type="module"> 1145 1146 var player = new Plyr('#[email protected]', { 1147 youtube: { 1148 noCookie: true, 1149 showinfo: 0 1150 }, 1151 fullscreen: { 1152 enabled: true, 1153 iosNative: true, 1154 } 1155 }); 1156 1157 document.querySelector('#[email protected]').addEventListener('show.bs.modal', function (event) { 1158 player.togglePlay(); 1159 1160 player.on('ready', event => { 1161 player.play(); 1162 }); 1163 }); 1164 1165 document.querySelector('#[email protected]').addEventListener('hide.bs.modal', function (event) { 1166 player.pause(); 1167 }); 1168 </script> 1169 1170 </div> 1171 </div> 1172 </div> 1173 </div> 1174 1175 break; 1176 } 1177 1178 @helper RenderVideo() 1179 { 1180 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1181 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1182 string ratio = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("AspectRatio", ""); 1183 ratio = ratio != "0" ? ratio : ""; 1184 string ratioCssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 1185 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : ""; 1186 string fillClass = ratio == "fill" ? " h-100" : ""; 1187 1188 var parms = new Dictionary<string, object>(); 1189 parms.Add("loading", "lazy"); 1190 if (ratio == "fill") { 1191 parms.Add("cssClass", "w-100 h-100"); 1192 } 1193 else 1194 { 1195 parms.Add("cssClass", "mw-100 mh-100"); 1196 } 1197 parms.Add("style",""); 1198 parms.Add("alt", @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("ImageAltText")); 1199 parms.Add("columns", Model.GridRowColumnCount); 1200 1201 <figure class="m-0@(ratioCssClass)@(fillClass)" @ratioVariable> 1202 1203 @if (string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster"))) 1204 { 1205 switch (provider) 1206 { 1207 case "youtube" : 1208 @RenderYouTubePoster(videoId) 1209 break; 1210 1211 case "vimeo" : 1212 @RenderVimeoPoster(videoId) 1213 break; 1214 } 1215 } 1216 else 1217 { 1218 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPoster") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 1219 } 1220 1221 </figure> 1222 } 1223 1224 @helper RenderYouTubePoster(string videoId) 1225 { 1226 <script type="module"> 1227 function setVideoThumbnail(source) { 1228 var figure = document.querySelector("[data-player='[email protected]'] figure"); 1229 var thumbnail = document.createElement("img"); 1230 thumbnail.style = "object-fit: cover;"; 1231 thumbnail.classList.add('mw-100','mh-100'); 1232 thumbnail.src = source; 1233 figure.appendChild(thumbnail); 1234 }; 1235 setVideoThumbnail('https://i.ytimg.com/vi/@(videoId)/hqdefault.jpg'); 1236 </script> 1237 } 1238 1239 @helper RenderVimeoPoster(string videoId) 1240 { 1241 <script type="module"> 1242 function setVideoThumbnail(source) { 1243 let figure = document.querySelector("[data-player='[email protected]'] figure"); 1244 let thumbnail = document.createElement("img"); 1245 thumbnail.style = "object-fit: cover;"; 1246 thumbnail.classList.add('mw-100','mh-100'); 1247 thumbnail.src = source; 1248 figure.appendChild(thumbnail); 1249 }; 1250 function getVimeoThumbnail() { 1251 fetch('https://vimeo.com/api/v2/video/@(videoId).json') 1252 .then(function(response) { 1253 return response.text(); 1254 }) 1255 .then(function(data) { 1256 let { thumbnail_large } = JSON.parse(data)[0]; 1257 let thumbnail = `${thumbnail_large}`; 1258 thumbnail = thumbnail.replace("_640", "_1920"); 1259 setVideoThumbnail(thumbnail); 1260 }) 1261 .catch(error => { 1262 console.log(error); 1263 }); 1264 } 1265 1266 getVimeoThumbnail(); 1267 </script> 1268 } 1269 1270 </div> 1271 } 1272 } 1273 1274 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1275 @using System.Linq 1276 1277 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 1278 { 1279 1280 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1281 { 1282 string headerKey = ""; 1283 string headerMarkup = ""; 1284 string headingStart = ""; 1285 string headingEnd = ""; 1286 int headerCount = 0; 1287 1288 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 1289 <div class="p-txt-container-wrap w-100"> 1290 @foreach (var heading in headings) 1291 { 1292 string headningSize = heading.GetString("Size"); 1293 string headingDisplaySize = heading.GetString("DisplaySize"); 1294 bool headingAccentColor = heading.GetBoolean("AccentColor"); 1295 bool headingAccentLine = heading.GetBoolean("AccentLine"); 1296 1297 if (headerKey != headningSize) 1298 { 1299 if (headerCount > 0) 1300 { 1301 headingEnd = $"</{headningSize}>"; 1302 headerMarkup += headingEnd; 1303 } 1304 headerKey = headningSize; 1305 headingStart = $"<{headningSize}>"; 1306 headerMarkup += headingStart; 1307 } 1308 else if (headerCount > 0 && headerKey == headningSize) 1309 { 1310 headerMarkup += "<br>"; 1311 } 1312 1313 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 1314 headerMarkup += heading.GetString("Heading"); 1315 headerMarkup += "</span>"; 1316 1317 headerCount++; 1318 1319 if (headerCount == headings.Count()) 1320 { 1321 headingEnd = $"</{headningSize}>"; 1322 headerMarkup += headingEnd; 1323 } 1324 } 1325 1326 @if (headerMarkup != "") 1327 { 1328 @headerMarkup 1329 } 1330 1331 1332 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 1333 { 1334 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 1335 } 1336 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1337 { 1338 @Model.Item.GetItem("Panel_Text").GetString("Text") 1339 } 1340 1341 @RenderButtons() 1342 </div> 1343 </div> 1344 } 1345 } 1346 1347 1348 </div> 1349 } 1350 else 1351 { 1352 if(Pageview.IsVisualEditorMode) { 1353 <div class="alert alert-warning" role="alert"> 1354 This paragraph is empty 1355 </div> 1356 } 1357 } 1358 } 1359 @Model.GetModuleOutput() 1360
    Error executing template "Designs/Swift/Paragraph/Base_Panel.cshtml"
    System.NullReferenceException: Object reference not set to an instance of an object.
       at CompiledRazorTemplates.Dynamic.RazorEngine_9ae15ff2a1324c908ed02e4e2f8692ec.Execute() in D:\Dynamicweb.NET\Solutions\Sika\Files\Templates\Designs\Swift\Paragraph\Base_Panel.cshtml:line 619
       at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
       at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
       at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
       at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
       at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
       at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
       at Dynamicweb.Rendering.Template.RenderRazorTemplate()
    
    1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using System.Collections.Generic 4 @using System.Linq 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @helper RenderButtons() 8 { 9 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 10 int loopCounter = 0; 11 12 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 13 14 string linkType = string.Empty; 15 16 foreach (var button in buttons) 17 { 18 loopCounter++; 19 } 20 21 if (buttons.Any()) 22 { 23 <div class="d-flex flex-wrap grid"> 24 @foreach (var button in buttons) 25 { 26 27 linkType = button.GetItem("Link").GetString("LinkType"); 28 29 if (linkType == "page" && button.GetItem("Link").GetLink("ButtonLink") != null) 30 { 31 link = button.GetItem("Link").GetLink("ButtonLink"); 32 } 33 34 if (linkType == "product-group") 35 { 36 37 IList<ProductGroupViewModel> selectedGroups = button.GetItem("Link").GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 38 39 IList<string> groupIds = new List<string> { }; 40 41 if (selectedGroups != null) 42 { 43 foreach (var fromGroup in selectedGroups) 44 { 45 groupIds.Add(fromGroup.Id); 46 } 47 } 48 link = new Dynamicweb.Frontend.LinkViewModel() 49 { 50 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds).Trim(), 51 IsExternal = false 52 }; 53 } 54 55 if (linkType == "product") 56 { 57 ProductListViewModel products = button.GetItem("Link").GetValue<ProductListViewModel>("ProductLink"); 58 IList<string> productIds = new List<string> { }; 59 string productPrimaryOrDefaultGroupID = string.Empty; 60 string pageTag = "Shop"; 61 62 if (products != null) 63 { 64 foreach (ProductViewModel product in products.Products) 65 { 66 productIds.Add(product.Id); 67 productPrimaryOrDefaultGroupID = product.PrimaryOrDefaultGroup.Id; 68 } 69 } 70 71 string productParameter = "MainProductId"; 72 string productGroupParameter = string.Empty; 73 if (productIds.Count == 1) 74 { 75 productParameter = "ProductID"; 76 if (!string.IsNullOrEmpty(productPrimaryOrDefaultGroupID)) 77 { 78 productGroupParameter = $"&GroupID={productPrimaryOrDefaultGroupID}"; 79 } 80 } 81 82 link = new Dynamicweb.Frontend.LinkViewModel() 83 { 84 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + productGroupParameter + "&" + productParameter + "=" + string.Join(",", productIds).Trim(), 85 IsExternal = false 86 }; 87 } 88 89 if (!string.IsNullOrEmpty(button.GetItem("Link").GetString("ButtonLink")) || !string.IsNullOrEmpty(button.GetItem("Link").GetString("ProductLink"))) 90 { 91 string classes = ""; 92 93 if (button.GetString("ButtonStyling") != "none") 94 { 95 classes = $"btn btn-{button.GetString("ButtonStyling")}"; 96 } 97 98 <p class="@(button.GetBoolean("NoWrap") ? "w-100" : "")"> 99 <a class="@classes" href="@link" target="@(link.Url.Contains("http") == true || link.Url.Contains("/Files/Files/") ? "_blank" : string.Empty)"> 100 @if (!string.IsNullOrEmpty(button.GetString("Icon"))) 101 { 102 <span class="icon-2" aria-hidden="true"> 103 @ReadFile(button.GetString("Icon")) 104 </span> 105 } 106 107 @button.GetString("ButtonText") 108 </a> 109 </p> 110 } 111 } 112 </div> 113 } 114 } 115 116 @using System.Collections.Generic 117 @using System.Linq 118 @using Dynamicweb.Content.Items 119 120 @functions 121 { 122 123 public string GetContainerClassList(Dynamicweb.Frontend.GridRowViewModel model) 124 { 125 List<string> returnValues = new List<string>(); 126 string container = "container-xl"; 127 128 if (model.Item.GetString("Width") == "bleed") 129 { 130 if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-end") 131 { 132 container = "container-xl me-lg-0 pe-lg-0"; 133 } 134 else if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-start") 135 { 136 container = "container-xl ms-lg-0 ps-lg-0"; 137 } 138 else 139 { 140 container = "container-fluid mx-0 px-0"; 141 } 142 } 143 144 returnValues.Add(container); 145 return string.Join(" ", returnValues); 146 } 147 148 149 150 public string GetColumnWidthClassList(Dynamicweb.Frontend.ItemViewModel model, bool isVisualEditor = false) 151 { 152 153 string columnWidth = isVisualEditor ? "col" : ""; 154 string mobileWidth = string.Empty; 155 string tabletWidth = string.Empty; 156 string desktopWidth = string.Empty; 157 string XLWidth = string.Empty; 158 159 if (model != null) 160 { 161 162 if (model.GetField("Mobile").GetRawValue() != null && model.GetField("Mobile").GetRawValue().ToString() != "auto") 163 { 164 165 mobileWidth = "col-" + model.GetField("Mobile").GetRawValue(); 166 if (model.GetField("Tablet").GetRawValue() == null) 167 { 168 mobileWidth = mobileWidth + " col-sm"; 169 } 170 } 171 if (model.GetField("Width").GetRawValue() != null && model.GetField("Width").GetRawValue().ToString() != "auto") 172 { 173 desktopWidth = "col-md-" + model.GetField("Width").GetRawValue(); 174 } 175 if (model.GetField("Tablet").GetRawValue() != null && model.GetField("Tablet").GetRawValue().ToString() != "auto") 176 { 177 178 desktopWidth = " col-lg-" + model.GetField("Width").GetRawValue(); 179 tabletWidth = "col-md-" + model.GetField("Tablet").GetRawValue(); 180 if (model.GetField("XL").GetRawValue() == null) 181 { 182 tabletWidth = tabletWidth + " col-lg-" + model.GetField("Width").GetRawValue(); 183 } 184 } 185 if (model.GetField("XL").GetRawValue() != null && model.GetField("XL").GetRawValue().ToString() != "auto") 186 { 187 XLWidth = "col-xxxl-" + model.GetField("XL").GetRawValue(); 188 } 189 190 columnWidth = $"col {mobileWidth} {tabletWidth} {desktopWidth} {XLWidth}"; 191 192 } 193 return string.Join(" ", columnWidth); 194 } 195 196 public string GetRowWidthClassList(Dynamicweb.Frontend.GridRowViewModel model) 197 { 198 List<string> returnValues = new List<string>(); 199 200 string rowWidth = model.Item.GetRawValueString("Width", string.Empty).ToLower(); 201 202 if (rowWidth == "6") 203 { 204 returnValues.Add("col-12 col-lg-6"); 205 } 206 if (rowWidth == "8") 207 { 208 returnValues.Add("col-12 col-lg-8"); 209 } 210 if (rowWidth == "9") 211 { 212 returnValues.Add("col-12 col-lg-9"); 213 } 214 if (rowWidth == "10") 215 { 216 returnValues.Add("col-12 col-lg-10"); 217 } 218 if (rowWidth == "12") 219 { 220 returnValues.Add("col-12 col-lg-12"); 221 } 222 if (rowWidth == "bleed") 223 { 224 returnValues.Add("col-12"); 225 } 226 227 return string.Join(" ", returnValues); 228 } 229 230 public string GetSectionContentAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 231 { 232 List<string> returnValues = new List<string>(); 233 234 returnValues.Add(model.Item.GetRawValueString("OverallAlignment", string.Empty).ToLower()); 235 236 return string.Join(" ", returnValues); 237 } 238 239 public string GetRowHorizontalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 240 { 241 242 List<string> returnValues = new List<string>(); 243 244 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 245 246 return string.Join(" ", returnValues); 247 } 248 249 public string GetRowVerticalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 250 { 251 252 List<string> returnValues = new List<string>(); 253 254 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 255 256 return string.Join(" ", returnValues); 257 } 258 259 public string GetRowSpacing(Dynamicweb.Frontend.GridRowViewModel model) 260 { 261 List<string> returnValues = new List<string>(); 262 263 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 264 265 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 266 267 return string.Join(" ", returnValues); 268 } 269 270 public string GetRowClassList(Dynamicweb.Frontend.GridRowViewModel model) 271 { 272 273 List<string> returnValues = new List<string>(); 274 275 string mobileOrderFirst = string.Empty; 276 if (model.Item.GetBoolean("MobileOrderReverse")) 277 { 278 mobileOrderFirst = "flex-column-reverse flex-md-row"; 279 } 280 returnValues.Add(mobileOrderFirst); 281 282 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 283 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 284 285 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 286 287 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 288 289 return string.Join(" ", returnValues); 290 } 291 292 public string GetSectionClassList(Dynamicweb.Frontend.GridRowViewModel model) 293 { 294 List<string> returnValues = new List<string>(); 295 returnValues.Add($"item_{model.Item.SystemName.ToLower()}"); 296 returnValues.Add(!string.IsNullOrWhiteSpace(model.Item.GetRawValueString("Theme")) ? " theme " + model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""); 297 string paddingTop = model.Item.GetRawValueString("PaddingTop", "large"); 298 string paddingBottom = model.Item.GetRawValueString("PaddingBottom", "large"); 299 300 if (paddingTop == "none") 301 { 302 returnValues.Add("pt-0"); 303 } 304 if (paddingTop == "small") 305 { 306 returnValues.Add("pt-4"); 307 } 308 if (paddingTop == "medium") 309 { 310 returnValues.Add("pt-5"); 311 } 312 if (paddingTop == "large") { 313 returnValues.Add("pt-7"); 314 } 315 316 if (paddingBottom == "none") 317 { 318 returnValues.Add("pb-0"); 319 } 320 if (paddingBottom == "small") 321 { 322 returnValues.Add("pb-4"); 323 } 324 if (paddingBottom == "medium") 325 { 326 returnValues.Add("pb-5"); 327 } 328 if (paddingBottom == "large") { 329 returnValues.Add("pb-7"); 330 } 331 332 var decorations = model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 333 var cssClasses = new List<string> { }; 334 335 foreach (var itemId in decorations) 336 { 337 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 338 339 if (item != null) 340 { 341 item.TryGetValue("Class", out object classes); 342 343 if (classes is null) 344 { 345 continue; 346 } 347 348 var cssString = (string)classes; 349 if (cssString.StartsWith("[")) 350 { 351 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 352 cssClasses.AddRange(cssArray); 353 } 354 else 355 { 356 cssClasses.Add(cssString.Replace(",", " ")); 357 } 358 } 359 } 360 returnValues.Add(string.Join(" ", cssClasses).Trim()); 361 362 return string.Join(" ", returnValues); 363 } 364 365 } 366 367 368 @helper RenderImage() 369 { 370 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("Image"))) 371 { 372 string ratioCssClass = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "ratio" : string.Empty; 373 string ratioVariable = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "style=\"--bs-aspect-ratio: " + Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") + "\"" : string.Empty; 374 string ImageObjectFit = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageObjectFit", string.Empty); 375 ImageObjectFit = ImageObjectFit == "cover" ? string.Empty : ImageObjectFit; 376 ImageObjectFit = ImageObjectFit == "contain" ? "object-fit:contain" : ImageObjectFit; 377 378 var parms = new Dictionary<string, object>(); 379 parms.Add("loading", "lazy"); 380 parms.Add("style", ImageObjectFit); 381 parms.Add("alt", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageAltText")); 382 parms.Add("columns", Model.GridRowColumnCount); 383 384 parms.Add("fullwidth", true); 385 parms.Add("cssClass", "img-fluid w-100 " + Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageCustomClasses")); 386 387 388 <figure class="mb-0 @ratioCssClass" @ratioVariable> 389 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 390 </figure> 391 } 392 } 393 394 @{ 395 var colSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("ColumnWidth")); 396 397 string imgPosition = string.Empty; 398 string imgPlacement = string.Empty; 399 string imgFloat = string.Empty; 400 401 if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 402 { 403 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement"); 404 } 405 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 406 { 407 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetString("ImagePlacement"); 408 } 409 410 if (imgPosition == "image-top") 411 { 412 imgPlacement = "flex-column"; 413 imgFloat = "top"; 414 } else if (imgPosition == "image-left") 415 { 416 imgPlacement = "flex-column flex-md-row"; 417 imgFloat = "left-right"; 418 } else if (imgPosition == "image-right") 419 { 420 imgPlacement = "flex-column flex-md-row-reverse"; 421 imgFloat = "left-right"; 422 } 423 424 425 426 var parms = new Dictionary<string, object>(); 427 parms.Add("cssClass", "h-100 w-100"); 428 429 } 430 431 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 432 @using Dynamicweb.Ecommerce.ProductCatalog 433 @using System.IO 434 @using Dynamicweb.Frontend 435 436 @{ 437 bool movePageBehind = false; 438 bool isFirstPoster = false; 439 string movePageBehindClass = ""; 440 if (Pageview.Page.PropertyItem != null) 441 { 442 string headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 443 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 444 445 if (movePageBehind) 446 { 447 movePageBehindClass = " poster-behind"; 448 if (!Dynamicweb.Context.Current.Items.Contains("firstPosterIsRendered")) 449 { 450 isFirstPoster = true; 451 Dynamicweb.Context.Current.Items.Add("firstPosterIsRendered", true); 452 } 453 454 } 455 456 } 457 } 458 459 @if (movePageBehind && isFirstPoster) 460 { 461 <script> 462 ['resize', 'load'].forEach(function (e) { 463 window.addEventListener(e, () => swift.Scroll.setContentPosition()); 464 }); 465 </script> 466 } 467 468 @using System.Collections.Generic 469 @using System.Linq 470 471 @{ 472 var headings = Model.Item?.GetItem("Panel_Text")?.GetItems("Headings") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 473 var widths = Model.Item?.GetItem("Panel_Text")?.GetItems("ColumnTest1") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 474 string layout = Model.Item?.GetItem("Panel_Text")?.GetRawValueString("Layout"); 475 var textColSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Text")?.GetItem("ColumnWidth")); 476 477 var textHeight = string.Empty; 478 479 if (layout == "top-left") 480 { 481 layout = "d-flex flex-column align-items-start"; 482 } else if (layout == "top-center") 483 { 484 layout = "d-flex flex-column align-items-center text-center mx-auto"; 485 } 486 else if (layout == "top-right") 487 { 488 layout = "d-flex flex-column align-items-end text-end ms-auto"; 489 } 490 else if (layout == "center-left") 491 { 492 layout = "d-flex flex-column justify-content-center"; 493 } 494 else if (layout == "center") 495 { 496 layout = "d-flex flex-column justify-content-center align-items-center text-center mx-auto"; 497 } 498 else if (layout == "center-right") 499 { 500 layout = "d-flex flex-column justify-content-center align-items-end text-end ms-auto"; 501 } 502 else if (layout == "bottom-left") 503 { 504 layout = "d-flex flex-column justify-content-end"; 505 } 506 else if (layout == "bottom-center") 507 { 508 layout = "d-flex flex-column justify-content-end align-items-center text-center mx-auto"; 509 } 510 else if (layout == "bottom-right") 511 { 512 layout = "d-flex flex-column justify-content-end align-items-end text-end ms-auto"; 513 } 514 } 515 516 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 517 @using System.Collections.Generic 518 @using Dynamicweb.Ecommerce.ProductCatalog 519 520 @{ 521 string linkType = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") != string.Empty ? Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") : string.Empty; 522 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 523 524 if (linkType == "page" && Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink") != null) 525 { 526 link = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink"); 527 } 528 529 if (linkType == "product-group") 530 { 531 IList<ProductGroupViewModel> selectedGroups = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 532 IList<string> groupIds = new List<string> {}; 533 534 if (selectedGroups != null) 535 { 536 foreach (var fromGroup in selectedGroups) 537 { 538 groupIds.Add(fromGroup.Id); 539 } 540 } 541 542 link = new Dynamicweb.Frontend.LinkViewModel() 543 { 544 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds) 545 }; 546 } 547 548 if (linkType == "product") 549 { 550 ProductListViewModel products = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<ProductListViewModel>("ProductLink"); 551 IList<string> productIds = new List<string> {}; 552 553 if (products != null) 554 { 555 foreach (var product in products.Products) 556 { 557 productIds.Add(product.Id); 558 } 559 } 560 561 string productParameter = productIds.Count == 1 ? "ProductID" : "MainProductId"; 562 string pageTag = productIds.Count == 1 ? "ProductDetailPage" : "Shop"; 563 link = new Dynamicweb.Frontend.LinkViewModel() 564 { 565 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + "&" + productParameter + "=" + string.Join(",", productIds) 566 }; 567 } 568 569 } 570 571 572 @{ 573 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 574 bool hasImage = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null; 575 bool hasGraphic = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") != null; 576 bool hasVideo = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Media" )?.GetItem( "Video" ).GetString( "VideoSourceID" ) ); 577 bool hasLead = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Lead" ) ); 578 bool hasText = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Text" ) ); 579 bool hasTheme = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) ); 580 bool hasHeading = headings.Count() > 0; 581 bool hasButton = buttons.Any(); 582 583 var decorations = Model.Item?.GetItem( "Panel_Settings" )?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 584 var cssClasses = new List<string> { }; 585 string cssDecorations = ""; 586 587 foreach (var itemId in decorations) 588 { 589 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 590 591 if (item != null) 592 { 593 item.TryGetValue("Class", out object classes); 594 595 if (classes is null) 596 { 597 continue; 598 } 599 600 var cssString = (string)classes; 601 if (cssString.StartsWith("[")) 602 { 603 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 604 cssClasses.AddRange(cssArray); 605 } 606 else 607 { 608 cssClasses.Add(cssString.Replace(",", " ")); 609 } 610 } 611 } 612 cssDecorations = string.Join(" ", cssClasses).Trim(); 613 614 ProductViewModel promotionalProduct = null; 615 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 616 { 617 promotionalProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 618 } 619 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 620 { 621 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 622 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 623 624 if (productList?.Products is object) 625 { 626 promotionalProduct = productList.Products[0]; 627 } 628 } 629 630 CategoryFieldViewModel categoryFieldViewModel = null; 631 FieldValueViewModel headerFieldValueViewModel = null; 632 FieldValueViewModel imageFieldValueViewModel = null; 633 FieldValueViewModel textFieldValueViewModel = null; 634 635 if (promotionalProduct != null ) 636 { 637 promotionalProduct.ProductCategories.TryGetValue("Promotional", out categoryFieldViewModel); 638 } 639 } 640 641 @if (Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement") == "image-poster" || Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") == "video-poster") 642 { 643 644 <div class="p-poster-container poster-overlay theme h-100 @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 645 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 646 647 @{ 648 string theme = string.Empty; 649 string posterHeight = string.Empty; 650 string mediaType = Model.Item.GetItem("Panel_Media").GetString("Media"); 651 652 if ( mediaType == "video") 653 { 654 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("Height"); 655 656 theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 657 } else if (mediaType == "image") 658 { 659 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Image").GetString("Height"); 660 661 theme = !string.IsNullOrWhiteSpace(Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme")) ? " theme " + Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; 662 663 } 664 665 posterHeight = posterHeight == "auto" ? "h-100" : posterHeight; 666 posterHeight = posterHeight == "small" ? "min-vh-50 min-vh-md-50" : posterHeight; 667 posterHeight = posterHeight == "medium" ? "min-vh-50 min-vh-md-75" : posterHeight; 668 posterHeight = posterHeight == "large" ? "min-vh-100 min-vh-md-100" : posterHeight; 669 posterHeight = posterHeight == "1x1" ? "ratio ratio-1x1 mx-auto" : posterHeight; 670 posterHeight = posterHeight == "4x3" ? "ratio ratio-4x3 mx-auto" : posterHeight; 671 posterHeight = posterHeight == "16x9" ? "ratio ratio-16x9 mx-auto" : posterHeight; 672 posterHeight = posterHeight == "9x16" ? "ratio ratio-9x16 mx-auto" : posterHeight; 673 posterHeight = posterHeight == "3x4" ? "ratio ratio-3x4 mx-auto" : posterHeight; 674 675 676 } 677 678 <div class="position-relative @(hasText || hasHeading ? "row" : "") @posterHeight @theme @(movePageBehindClass)"> 679 680 @if (Model.Item.GetItem("Panel_Media").GetString("Media") == "video") 681 { 682 <div class="p-poster-video-container position-absolute top-0 bottom-0 end-0 start-0 px-0"> 683 <video preload="auto" loop autoplay muted playsinline class="h-100 w-100" style="object-fit: cover;"> 684 <source src="@Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")" 685 type="video/@Path.GetExtension(Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")).ToLower().Replace(".", "")"> 686 </video> 687 </div> 688 689 } else if (Model.Item.GetItem("Panel_Media").GetString("Media") == "image") 690 { 691 <div class="position-absolute top-0 bottom-0 end-0 start-0 px-0"> 692 693 @if (link != null && !string.IsNullOrEmpty(link.Url)) 694 { 695 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 696 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 697 <a class="bottom-0 position-absolute top-0 w-100" href="@link.Url" @target @rel style="z-index: 2"> 698 </a> 699 } 700 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media").GetItem("Image").GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 701 </div> 702 703 } 704 705 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 706 @using System.Linq 707 708 @if(hasText || hasHeading){ 709 <div class="d-flex @(posterHeight == "none" ? string.Empty : "position-absolute top-0 bottom-0")"> 710 <div class="container-xl mx-auto px-0 py-5 row"> 711 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 712 @using System.Linq 713 714 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 715 { 716 717 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 718 { 719 string headerKey = ""; 720 string headerMarkup = ""; 721 string headingStart = ""; 722 string headingEnd = ""; 723 int headerCount = 0; 724 725 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 726 <div class="p-txt-container-wrap w-100"> 727 @foreach (var heading in headings) 728 { 729 string headningSize = heading.GetString("Size"); 730 string headingDisplaySize = heading.GetString("DisplaySize"); 731 bool headingAccentColor = heading.GetBoolean("AccentColor"); 732 bool headingAccentLine = heading.GetBoolean("AccentLine"); 733 734 if (headerKey != headningSize) 735 { 736 if (headerCount > 0) 737 { 738 headingEnd = $"</{headningSize}>"; 739 headerMarkup += headingEnd; 740 } 741 headerKey = headningSize; 742 headingStart = $"<{headningSize}>"; 743 headerMarkup += headingStart; 744 } 745 else if (headerCount > 0 && headerKey == headningSize) 746 { 747 headerMarkup += "<br>"; 748 } 749 750 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 751 headerMarkup += heading.GetString("Heading"); 752 headerMarkup += "</span>"; 753 754 headerCount++; 755 756 if (headerCount == headings.Count()) 757 { 758 headingEnd = $"</{headningSize}>"; 759 headerMarkup += headingEnd; 760 } 761 } 762 763 @if (headerMarkup != "") 764 { 765 @headerMarkup 766 } 767 768 769 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 770 { 771 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 772 } 773 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 774 { 775 @Model.Item.GetItem("Panel_Text").GetString("Text") 776 } 777 778 @RenderButtons() 779 </div> 780 </div> 781 } 782 } 783 784 </div> 785 </div> 786 } 787 788 </div> 789 790 </div> 791 } 792 else 793 { 794 795 if( hasImage || hasGraphic || hasVideo || hasLead || hasText || hasHeading || hasButton || promotionalProduct != null) 796 { 797 798 <div class="p-panel-container row @textHeight @imgPlacement @(hasTheme ? "theme " + Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 799 800 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Header", out headerFieldValueViewModel)) 801 { 802 if (headerFieldValueViewModel.Value != null) 803 { 804 string promotionalHeaderText = headerFieldValueViewModel.Value.ToString(); 805 promotionalHeaderText = promotionalHeaderText.Replace("{{D1}}", "<span class=\"display-1\">"); 806 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1}}", "</span>"); 807 promotionalHeaderText = promotionalHeaderText.Replace("{{D1:AccentColor}}", "<span class=\"display-1 text-accent\">"); 808 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1:AccentColor}}", "</span>"); 809 promotionalHeaderText = promotionalHeaderText.Replace("{{D2}}", "<span class=\"display-2\">"); 810 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2}}", "</span>"); 811 promotionalHeaderText = promotionalHeaderText.Replace("{{D2:AccentColor}}", "<span class=\"display-2 text-accent\">"); 812 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2:AccentColor}}", "</span>"); 813 promotionalHeaderText = promotionalHeaderText.Replace("{{D3}}", "<span class=\"display-3\">"); 814 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3}}", "</span>"); 815 promotionalHeaderText = promotionalHeaderText.Replace("{{D3:AccentColor}}", "<span class=\"display-3 text-accent\">"); 816 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3:AccentColor}}", "</span>"); 817 promotionalHeaderText = promotionalHeaderText.Replace("®", "<sup>®</sup>"); 818 promotionalHeaderText = promotionalHeaderText.Replace("{{BR}}", "<br>"); 819 820 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 821 <div class="p-txt-container-wrap"> 822 <h2> 823 @promotionalHeaderText 824 </h2> 825 </div> 826 </div> 827 } 828 } 829 830 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Image", out imageFieldValueViewModel)) 831 { 832 if (imageFieldValueViewModel.Value != null) 833 { 834 string imagePath = imageFieldValueViewModel.Value.ToString(); 835 var promotionalImageParms = new Dictionary<string, object>(); 836 promotionalImageParms.Add("loading", "lazy"); 837 promotionalImageParms.Add("columns", Model.GridRowColumnCount); 838 839 promotionalImageParms.Add("fullwidth", true); 840 promotionalImageParms.Add("cssClass", "img-fluid w-100"); 841 promotionalImageParms.Add("style", "max-width: 60rem;transform: translateY(-6rem);margin-bottom: -6rem;"); 842 843 <div class="p-img-container d-flex justify-content-center"> 844 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, promotionalImageParms) 845 </div> 846 } 847 } 848 849 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Text", out textFieldValueViewModel)) 850 { 851 if (textFieldValueViewModel.Value != null) 852 { 853 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 854 <div class="p-txt-container-wrap" style="max-width: 70rem;"> 855 @textFieldValueViewModel.Value 856 </div> 857 </div> 858 } 859 } 860 861 @if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 862 { 863 if (Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null) 864 { 865 866 string imgPadding = string.Empty; 867 868 if (headings.Count() > 0 && imgFloat == "top") 869 { 870 imgPadding = "mb-4"; 871 } 872 873 else if (buttons.Any() && imgFloat == "top") 874 { 875 imgPadding = "mb-4"; 876 } 877 878 else if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text")) && imgFloat == "top") 879 { 880 imgPadding = "mb-4"; 881 } 882 883 else 884 { 885 imgPadding = "mb-4 mb-sm-0"; 886 } 887 888 string imgAlignment = string.Empty; 889 890 if(imgPosition == "image-left") 891 { 892 imgAlignment = "me-auto"; 893 } 894 else if(imgPosition == "image-right") 895 { 896 imgAlignment = "ms-auto"; 897 } 898 else 899 { 900 imgAlignment = "mx-auto"; 901 } 902 903 var offsets = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Offsets"); 904 905 string desktopOffset = string.Empty; 906 string mobileOffset = string.Empty; 907 string tabletOffset = string.Empty; 908 string XLOffset = string.Empty; 909 910 if(offsets != null) 911 { 912 if(!string.IsNullOrEmpty(offsets.GetString("Offset"))) 913 { 914 desktopOffset = $"transform: translate({offsets.GetString("Offset")});"; 915 } 916 if(!string.IsNullOrEmpty(offsets.GetString("Mobile"))) 917 { 918 mobileOffset = $"transform: translate({offsets.GetString("Mobile")});"; 919 } 920 if(!string.IsNullOrEmpty(offsets.GetString("Tablet"))) 921 { 922 tabletOffset = $"transform: translate({offsets.GetString("Tablet")});"; 923 } 924 if(!string.IsNullOrEmpty(offsets.GetString("XL"))) 925 { 926 XLOffset = $"transform: translate({offsets.GetString("XL")});"; 927 } 928 } 929 930 if (!string.IsNullOrEmpty(mobileOffset) || !string.IsNullOrEmpty(tabletOffset) || !string.IsNullOrEmpty(desktopOffset) || !string.IsNullOrEmpty(XLOffset)) 931 { 932 <style> 933 @if (!string.IsNullOrEmpty(mobileOffset)) 934 { 935 <text> 936 @@media (min-width: 300px) { 937 [id='@(Model.ID)'] .p-img-container { 938 @mobileOffset 939 } 940 } 941 </text> 942 } 943 @if (!string.IsNullOrEmpty(tabletOffset)) 944 { 945 <text> 946 @@media (min-width: 768px) { 947 [id='@(Model.ID)'] .p-img-container { 948 @tabletOffset 949 } 950 } 951 </text> 952 } 953 954 @if (!string.IsNullOrEmpty(desktopOffset)) 955 { 956 <text> 957 @@media(min-width: 992px) 958 { 959 [id='@(Model.ID)'] .p-img-container { 960 @desktopOffset 961 } 962 } 963 </text> 964 } 965 966 @if (!string.IsNullOrEmpty(XLOffset)) 967 { 968 <text> 969 @@media(min-width: 1920px) 970 { 971 [id='@(Model.ID)'] .p-img-container { 972 @XLOffset 973 } 974 } 975 </text> 976 } 977 978 [id='@(Model.ID)'] .p-img-container { 979 z-index: 2; 980 position: relative; 981 } 982 </style> 983 } 984 985 <div class="@imgPadding p-img-container @colSizeClasslist @imgAlignment"> 986 987 @if (link != null && !string.IsNullOrEmpty(link.Url)) 988 { 989 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 990 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 991 <a href="@link.Url" @target @rel> 992 @RenderImage() 993 </a> 994 } 995 else 996 { 997 @RenderImage() 998 } 999 1000 </div> 1001 } 1002 1003 } 1004 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 1005 { 1006 <div class="p-graphic-container mb-3 col flex-grow-0 pe-0"> 1007 <div class="@(layout) [email protected]("Panel_Media").GetItem("Graphic").GetString("GraphicSize")"> 1008 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel()) 1009 </div> 1010 </div> 1011 1012 } 1013 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Video") 1014 { 1015 if (Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") != "video-poster") 1016 { 1017 <div class="p-video-container"> 1018 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1019 @using Dynamicweb.Ecommerce.ProductCatalog 1020 1021 @{ 1022 1023 1024 string visual = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Visual", "inline"); 1025 1026 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1027 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1028 1029 Dynamicweb.Frontend.FileViewModel video = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPath"); 1030 string videoPath = video?.Path ?? ""; 1031 1032 string posterPath = "/Admin/Public/GetImage.ashx?image=" + @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster") + "&width=1000&format=webp"; 1033 1034 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/play.svg"; 1035 string theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 1036 } 1037 1038 1039 @switch(visual) { 1040 case "inline" : 1041 <div class="h-100 position-relative grid grid-1"> 1042 1043 @switch (provider) 1044 { 1045 case "youtube" : 1046 case "vimeo" : 1047 1048 <div 1049 id="[email protected]" 1050 class="player plyr__video-embed @(theme) h-100 w-100" 1051 data-plyr-provider="@provider" 1052 data-plyr-embed-id="@videoId" 1053 style="--plyr-color-main: var(--swift-foreground-color); " 1054 > 1055 </div> 1056 1057 break; 1058 1059 case "self-hosted" : 1060 1061 <video 1062 id="[email protected]" 1063 class="player plyr__video-embed @(theme) h-100 w-100" 1064 src="@videoPath" 1065 style="--plyr-color-main: var(--swift-foreground-color);" 1066 preload="metadata" 1067 poster="@posterPath"> 1068 </video> 1069 1070 break; 1071 } 1072 <script type="module" defer src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1073 <script type="module" defer> 1074 1075 const player = new Plyr('#[email protected]', { 1076 type: 'video', 1077 youtube: { 1078 noCookie: true, 1079 showinfo: 0 1080 }, 1081 fullscreen: { 1082 enabled: true, 1083 iosNative: true, 1084 } 1085 }); 1086 </script> 1087 1088 </div> 1089 1090 break; 1091 1092 case "poster-modal" : 1093 <div class="h-100 position-relative@(theme) grid grid-1"> 1094 <div class="player position-relative" data-player="[email protected]"> 1095 1096 @RenderVideo() 1097 1098 <div class="position-absolute top-0 bottom-0 end-0 start-0 h-100 d-flex align-items-center justify-content-center gradient-overlay"> 1099 <button type="button" class="btn btn-primary rounded-circle lh-1 p-3" data-bs-toggle="modal" data-bs-target="#[email protected]"> 1100 <span class="icon-3"> 1101 @ReadFile(iconPath) 1102 </span> 1103 <span class="visually-hidden">@Translate("Play video")</span> 1104 </button> 1105 </div> 1106 </div> 1107 </div> 1108 1109 <div class="modal fade" id="[email protected]" tabindex="-1" aria-hidden="true"> 1110 <div class="modal-dialog modal-xl modal-dialog-centered"> 1111 <div class="modal-content"> 1112 <div class="modal-body p-0"> 1113 1114 @switch (provider) 1115 { 1116 case "youtube" : 1117 case "vimeo" : 1118 1119 <div 1120 id="[email protected]" 1121 class="player plyr__video-embed @(theme) h-100 w-100" 1122 data-plyr-provider="@provider" 1123 data-plyr-embed-id="@videoId" 1124 style="--plyr-color-main: var(--swift-foreground-color); " 1125 > 1126 </div> 1127 1128 break; 1129 1130 case "self-hosted" : 1131 1132 <video 1133 id="[email protected]" 1134 class="player plyr__video-embed @(theme) h-100 w-100" 1135 src="@videoPath" 1136 style="--plyr-color-main: var(--swift-foreground-color);" 1137 preload="metadata" 1138 > 1139 </video> 1140 1141 break; 1142 } 1143 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1144 <script type="module"> 1145 1146 var player = new Plyr('#[email protected]', { 1147 youtube: { 1148 noCookie: true, 1149 showinfo: 0 1150 }, 1151 fullscreen: { 1152 enabled: true, 1153 iosNative: true, 1154 } 1155 }); 1156 1157 document.querySelector('#[email protected]').addEventListener('show.bs.modal', function (event) { 1158 player.togglePlay(); 1159 1160 player.on('ready', event => { 1161 player.play(); 1162 }); 1163 }); 1164 1165 document.querySelector('#[email protected]').addEventListener('hide.bs.modal', function (event) { 1166 player.pause(); 1167 }); 1168 </script> 1169 1170 </div> 1171 </div> 1172 </div> 1173 </div> 1174 1175 break; 1176 } 1177 1178 @helper RenderVideo() 1179 { 1180 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1181 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1182 string ratio = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("AspectRatio", ""); 1183 ratio = ratio != "0" ? ratio : ""; 1184 string ratioCssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 1185 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : ""; 1186 string fillClass = ratio == "fill" ? " h-100" : ""; 1187 1188 var parms = new Dictionary<string, object>(); 1189 parms.Add("loading", "lazy"); 1190 if (ratio == "fill") { 1191 parms.Add("cssClass", "w-100 h-100"); 1192 } 1193 else 1194 { 1195 parms.Add("cssClass", "mw-100 mh-100"); 1196 } 1197 parms.Add("style",""); 1198 parms.Add("alt", @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("ImageAltText")); 1199 parms.Add("columns", Model.GridRowColumnCount); 1200 1201 <figure class="m-0@(ratioCssClass)@(fillClass)" @ratioVariable> 1202 1203 @if (string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster"))) 1204 { 1205 switch (provider) 1206 { 1207 case "youtube" : 1208 @RenderYouTubePoster(videoId) 1209 break; 1210 1211 case "vimeo" : 1212 @RenderVimeoPoster(videoId) 1213 break; 1214 } 1215 } 1216 else 1217 { 1218 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPoster") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 1219 } 1220 1221 </figure> 1222 } 1223 1224 @helper RenderYouTubePoster(string videoId) 1225 { 1226 <script type="module"> 1227 function setVideoThumbnail(source) { 1228 var figure = document.querySelector("[data-player='[email protected]'] figure"); 1229 var thumbnail = document.createElement("img"); 1230 thumbnail.style = "object-fit: cover;"; 1231 thumbnail.classList.add('mw-100','mh-100'); 1232 thumbnail.src = source; 1233 figure.appendChild(thumbnail); 1234 }; 1235 setVideoThumbnail('https://i.ytimg.com/vi/@(videoId)/hqdefault.jpg'); 1236 </script> 1237 } 1238 1239 @helper RenderVimeoPoster(string videoId) 1240 { 1241 <script type="module"> 1242 function setVideoThumbnail(source) { 1243 let figure = document.querySelector("[data-player='[email protected]'] figure"); 1244 let thumbnail = document.createElement("img"); 1245 thumbnail.style = "object-fit: cover;"; 1246 thumbnail.classList.add('mw-100','mh-100'); 1247 thumbnail.src = source; 1248 figure.appendChild(thumbnail); 1249 }; 1250 function getVimeoThumbnail() { 1251 fetch('https://vimeo.com/api/v2/video/@(videoId).json') 1252 .then(function(response) { 1253 return response.text(); 1254 }) 1255 .then(function(data) { 1256 let { thumbnail_large } = JSON.parse(data)[0]; 1257 let thumbnail = `${thumbnail_large}`; 1258 thumbnail = thumbnail.replace("_640", "_1920"); 1259 setVideoThumbnail(thumbnail); 1260 }) 1261 .catch(error => { 1262 console.log(error); 1263 }); 1264 } 1265 1266 getVimeoThumbnail(); 1267 </script> 1268 } 1269 1270 </div> 1271 } 1272 } 1273 1274 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1275 @using System.Linq 1276 1277 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 1278 { 1279 1280 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1281 { 1282 string headerKey = ""; 1283 string headerMarkup = ""; 1284 string headingStart = ""; 1285 string headingEnd = ""; 1286 int headerCount = 0; 1287 1288 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 1289 <div class="p-txt-container-wrap w-100"> 1290 @foreach (var heading in headings) 1291 { 1292 string headningSize = heading.GetString("Size"); 1293 string headingDisplaySize = heading.GetString("DisplaySize"); 1294 bool headingAccentColor = heading.GetBoolean("AccentColor"); 1295 bool headingAccentLine = heading.GetBoolean("AccentLine"); 1296 1297 if (headerKey != headningSize) 1298 { 1299 if (headerCount > 0) 1300 { 1301 headingEnd = $"</{headningSize}>"; 1302 headerMarkup += headingEnd; 1303 } 1304 headerKey = headningSize; 1305 headingStart = $"<{headningSize}>"; 1306 headerMarkup += headingStart; 1307 } 1308 else if (headerCount > 0 && headerKey == headningSize) 1309 { 1310 headerMarkup += "<br>"; 1311 } 1312 1313 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 1314 headerMarkup += heading.GetString("Heading"); 1315 headerMarkup += "</span>"; 1316 1317 headerCount++; 1318 1319 if (headerCount == headings.Count()) 1320 { 1321 headingEnd = $"</{headningSize}>"; 1322 headerMarkup += headingEnd; 1323 } 1324 } 1325 1326 @if (headerMarkup != "") 1327 { 1328 @headerMarkup 1329 } 1330 1331 1332 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 1333 { 1334 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 1335 } 1336 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1337 { 1338 @Model.Item.GetItem("Panel_Text").GetString("Text") 1339 } 1340 1341 @RenderButtons() 1342 </div> 1343 </div> 1344 } 1345 } 1346 1347 1348 </div> 1349 } 1350 else 1351 { 1352 if(Pageview.IsVisualEditorMode) { 1353 <div class="alert alert-warning" role="alert"> 1354 This paragraph is empty 1355 </div> 1356 } 1357 } 1358 } 1359 @Model.GetModuleOutput() 1360
    Error executing template "Designs/Swift/Paragraph/Base_Panel.cshtml"
    System.NullReferenceException: Object reference not set to an instance of an object.
       at CompiledRazorTemplates.Dynamic.RazorEngine_9ae15ff2a1324c908ed02e4e2f8692ec.Execute() in D:\Dynamicweb.NET\Solutions\Sika\Files\Templates\Designs\Swift\Paragraph\Base_Panel.cshtml:line 619
       at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
       at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
       at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
       at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
       at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
       at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
       at Dynamicweb.Rendering.Template.RenderRazorTemplate()
    
    1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using System.Collections.Generic 4 @using System.Linq 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @helper RenderButtons() 8 { 9 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 10 int loopCounter = 0; 11 12 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 13 14 string linkType = string.Empty; 15 16 foreach (var button in buttons) 17 { 18 loopCounter++; 19 } 20 21 if (buttons.Any()) 22 { 23 <div class="d-flex flex-wrap grid"> 24 @foreach (var button in buttons) 25 { 26 27 linkType = button.GetItem("Link").GetString("LinkType"); 28 29 if (linkType == "page" && button.GetItem("Link").GetLink("ButtonLink") != null) 30 { 31 link = button.GetItem("Link").GetLink("ButtonLink"); 32 } 33 34 if (linkType == "product-group") 35 { 36 37 IList<ProductGroupViewModel> selectedGroups = button.GetItem("Link").GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 38 39 IList<string> groupIds = new List<string> { }; 40 41 if (selectedGroups != null) 42 { 43 foreach (var fromGroup in selectedGroups) 44 { 45 groupIds.Add(fromGroup.Id); 46 } 47 } 48 link = new Dynamicweb.Frontend.LinkViewModel() 49 { 50 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds).Trim(), 51 IsExternal = false 52 }; 53 } 54 55 if (linkType == "product") 56 { 57 ProductListViewModel products = button.GetItem("Link").GetValue<ProductListViewModel>("ProductLink"); 58 IList<string> productIds = new List<string> { }; 59 string productPrimaryOrDefaultGroupID = string.Empty; 60 string pageTag = "Shop"; 61 62 if (products != null) 63 { 64 foreach (ProductViewModel product in products.Products) 65 { 66 productIds.Add(product.Id); 67 productPrimaryOrDefaultGroupID = product.PrimaryOrDefaultGroup.Id; 68 } 69 } 70 71 string productParameter = "MainProductId"; 72 string productGroupParameter = string.Empty; 73 if (productIds.Count == 1) 74 { 75 productParameter = "ProductID"; 76 if (!string.IsNullOrEmpty(productPrimaryOrDefaultGroupID)) 77 { 78 productGroupParameter = $"&GroupID={productPrimaryOrDefaultGroupID}"; 79 } 80 } 81 82 link = new Dynamicweb.Frontend.LinkViewModel() 83 { 84 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + productGroupParameter + "&" + productParameter + "=" + string.Join(",", productIds).Trim(), 85 IsExternal = false 86 }; 87 } 88 89 if (!string.IsNullOrEmpty(button.GetItem("Link").GetString("ButtonLink")) || !string.IsNullOrEmpty(button.GetItem("Link").GetString("ProductLink"))) 90 { 91 string classes = ""; 92 93 if (button.GetString("ButtonStyling") != "none") 94 { 95 classes = $"btn btn-{button.GetString("ButtonStyling")}"; 96 } 97 98 <p class="@(button.GetBoolean("NoWrap") ? "w-100" : "")"> 99 <a class="@classes" href="@link" target="@(link.Url.Contains("http") == true || link.Url.Contains("/Files/Files/") ? "_blank" : string.Empty)"> 100 @if (!string.IsNullOrEmpty(button.GetString("Icon"))) 101 { 102 <span class="icon-2" aria-hidden="true"> 103 @ReadFile(button.GetString("Icon")) 104 </span> 105 } 106 107 @button.GetString("ButtonText") 108 </a> 109 </p> 110 } 111 } 112 </div> 113 } 114 } 115 116 @using System.Collections.Generic 117 @using System.Linq 118 @using Dynamicweb.Content.Items 119 120 @functions 121 { 122 123 public string GetContainerClassList(Dynamicweb.Frontend.GridRowViewModel model) 124 { 125 List<string> returnValues = new List<string>(); 126 string container = "container-xl"; 127 128 if (model.Item.GetString("Width") == "bleed") 129 { 130 if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-end") 131 { 132 container = "container-xl me-lg-0 pe-lg-0"; 133 } 134 else if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-start") 135 { 136 container = "container-xl ms-lg-0 ps-lg-0"; 137 } 138 else 139 { 140 container = "container-fluid mx-0 px-0"; 141 } 142 } 143 144 returnValues.Add(container); 145 return string.Join(" ", returnValues); 146 } 147 148 149 150 public string GetColumnWidthClassList(Dynamicweb.Frontend.ItemViewModel model, bool isVisualEditor = false) 151 { 152 153 string columnWidth = isVisualEditor ? "col" : ""; 154 string mobileWidth = string.Empty; 155 string tabletWidth = string.Empty; 156 string desktopWidth = string.Empty; 157 string XLWidth = string.Empty; 158 159 if (model != null) 160 { 161 162 if (model.GetField("Mobile").GetRawValue() != null && model.GetField("Mobile").GetRawValue().ToString() != "auto") 163 { 164 165 mobileWidth = "col-" + model.GetField("Mobile").GetRawValue(); 166 if (model.GetField("Tablet").GetRawValue() == null) 167 { 168 mobileWidth = mobileWidth + " col-sm"; 169 } 170 } 171 if (model.GetField("Width").GetRawValue() != null && model.GetField("Width").GetRawValue().ToString() != "auto") 172 { 173 desktopWidth = "col-md-" + model.GetField("Width").GetRawValue(); 174 } 175 if (model.GetField("Tablet").GetRawValue() != null && model.GetField("Tablet").GetRawValue().ToString() != "auto") 176 { 177 178 desktopWidth = " col-lg-" + model.GetField("Width").GetRawValue(); 179 tabletWidth = "col-md-" + model.GetField("Tablet").GetRawValue(); 180 if (model.GetField("XL").GetRawValue() == null) 181 { 182 tabletWidth = tabletWidth + " col-lg-" + model.GetField("Width").GetRawValue(); 183 } 184 } 185 if (model.GetField("XL").GetRawValue() != null && model.GetField("XL").GetRawValue().ToString() != "auto") 186 { 187 XLWidth = "col-xxxl-" + model.GetField("XL").GetRawValue(); 188 } 189 190 columnWidth = $"col {mobileWidth} {tabletWidth} {desktopWidth} {XLWidth}"; 191 192 } 193 return string.Join(" ", columnWidth); 194 } 195 196 public string GetRowWidthClassList(Dynamicweb.Frontend.GridRowViewModel model) 197 { 198 List<string> returnValues = new List<string>(); 199 200 string rowWidth = model.Item.GetRawValueString("Width", string.Empty).ToLower(); 201 202 if (rowWidth == "6") 203 { 204 returnValues.Add("col-12 col-lg-6"); 205 } 206 if (rowWidth == "8") 207 { 208 returnValues.Add("col-12 col-lg-8"); 209 } 210 if (rowWidth == "9") 211 { 212 returnValues.Add("col-12 col-lg-9"); 213 } 214 if (rowWidth == "10") 215 { 216 returnValues.Add("col-12 col-lg-10"); 217 } 218 if (rowWidth == "12") 219 { 220 returnValues.Add("col-12 col-lg-12"); 221 } 222 if (rowWidth == "bleed") 223 { 224 returnValues.Add("col-12"); 225 } 226 227 return string.Join(" ", returnValues); 228 } 229 230 public string GetSectionContentAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 231 { 232 List<string> returnValues = new List<string>(); 233 234 returnValues.Add(model.Item.GetRawValueString("OverallAlignment", string.Empty).ToLower()); 235 236 return string.Join(" ", returnValues); 237 } 238 239 public string GetRowHorizontalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 240 { 241 242 List<string> returnValues = new List<string>(); 243 244 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 245 246 return string.Join(" ", returnValues); 247 } 248 249 public string GetRowVerticalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 250 { 251 252 List<string> returnValues = new List<string>(); 253 254 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 255 256 return string.Join(" ", returnValues); 257 } 258 259 public string GetRowSpacing(Dynamicweb.Frontend.GridRowViewModel model) 260 { 261 List<string> returnValues = new List<string>(); 262 263 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 264 265 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 266 267 return string.Join(" ", returnValues); 268 } 269 270 public string GetRowClassList(Dynamicweb.Frontend.GridRowViewModel model) 271 { 272 273 List<string> returnValues = new List<string>(); 274 275 string mobileOrderFirst = string.Empty; 276 if (model.Item.GetBoolean("MobileOrderReverse")) 277 { 278 mobileOrderFirst = "flex-column-reverse flex-md-row"; 279 } 280 returnValues.Add(mobileOrderFirst); 281 282 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 283 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 284 285 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 286 287 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 288 289 return string.Join(" ", returnValues); 290 } 291 292 public string GetSectionClassList(Dynamicweb.Frontend.GridRowViewModel model) 293 { 294 List<string> returnValues = new List<string>(); 295 returnValues.Add($"item_{model.Item.SystemName.ToLower()}"); 296 returnValues.Add(!string.IsNullOrWhiteSpace(model.Item.GetRawValueString("Theme")) ? " theme " + model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""); 297 string paddingTop = model.Item.GetRawValueString("PaddingTop", "large"); 298 string paddingBottom = model.Item.GetRawValueString("PaddingBottom", "large"); 299 300 if (paddingTop == "none") 301 { 302 returnValues.Add("pt-0"); 303 } 304 if (paddingTop == "small") 305 { 306 returnValues.Add("pt-4"); 307 } 308 if (paddingTop == "medium") 309 { 310 returnValues.Add("pt-5"); 311 } 312 if (paddingTop == "large") { 313 returnValues.Add("pt-7"); 314 } 315 316 if (paddingBottom == "none") 317 { 318 returnValues.Add("pb-0"); 319 } 320 if (paddingBottom == "small") 321 { 322 returnValues.Add("pb-4"); 323 } 324 if (paddingBottom == "medium") 325 { 326 returnValues.Add("pb-5"); 327 } 328 if (paddingBottom == "large") { 329 returnValues.Add("pb-7"); 330 } 331 332 var decorations = model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 333 var cssClasses = new List<string> { }; 334 335 foreach (var itemId in decorations) 336 { 337 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 338 339 if (item != null) 340 { 341 item.TryGetValue("Class", out object classes); 342 343 if (classes is null) 344 { 345 continue; 346 } 347 348 var cssString = (string)classes; 349 if (cssString.StartsWith("[")) 350 { 351 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 352 cssClasses.AddRange(cssArray); 353 } 354 else 355 { 356 cssClasses.Add(cssString.Replace(",", " ")); 357 } 358 } 359 } 360 returnValues.Add(string.Join(" ", cssClasses).Trim()); 361 362 return string.Join(" ", returnValues); 363 } 364 365 } 366 367 368 @helper RenderImage() 369 { 370 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("Image"))) 371 { 372 string ratioCssClass = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "ratio" : string.Empty; 373 string ratioVariable = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "style=\"--bs-aspect-ratio: " + Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") + "\"" : string.Empty; 374 string ImageObjectFit = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageObjectFit", string.Empty); 375 ImageObjectFit = ImageObjectFit == "cover" ? string.Empty : ImageObjectFit; 376 ImageObjectFit = ImageObjectFit == "contain" ? "object-fit:contain" : ImageObjectFit; 377 378 var parms = new Dictionary<string, object>(); 379 parms.Add("loading", "lazy"); 380 parms.Add("style", ImageObjectFit); 381 parms.Add("alt", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageAltText")); 382 parms.Add("columns", Model.GridRowColumnCount); 383 384 parms.Add("fullwidth", true); 385 parms.Add("cssClass", "img-fluid w-100 " + Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageCustomClasses")); 386 387 388 <figure class="mb-0 @ratioCssClass" @ratioVariable> 389 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 390 </figure> 391 } 392 } 393 394 @{ 395 var colSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("ColumnWidth")); 396 397 string imgPosition = string.Empty; 398 string imgPlacement = string.Empty; 399 string imgFloat = string.Empty; 400 401 if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 402 { 403 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement"); 404 } 405 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 406 { 407 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetString("ImagePlacement"); 408 } 409 410 if (imgPosition == "image-top") 411 { 412 imgPlacement = "flex-column"; 413 imgFloat = "top"; 414 } else if (imgPosition == "image-left") 415 { 416 imgPlacement = "flex-column flex-md-row"; 417 imgFloat = "left-right"; 418 } else if (imgPosition == "image-right") 419 { 420 imgPlacement = "flex-column flex-md-row-reverse"; 421 imgFloat = "left-right"; 422 } 423 424 425 426 var parms = new Dictionary<string, object>(); 427 parms.Add("cssClass", "h-100 w-100"); 428 429 } 430 431 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 432 @using Dynamicweb.Ecommerce.ProductCatalog 433 @using System.IO 434 @using Dynamicweb.Frontend 435 436 @{ 437 bool movePageBehind = false; 438 bool isFirstPoster = false; 439 string movePageBehindClass = ""; 440 if (Pageview.Page.PropertyItem != null) 441 { 442 string headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 443 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 444 445 if (movePageBehind) 446 { 447 movePageBehindClass = " poster-behind"; 448 if (!Dynamicweb.Context.Current.Items.Contains("firstPosterIsRendered")) 449 { 450 isFirstPoster = true; 451 Dynamicweb.Context.Current.Items.Add("firstPosterIsRendered", true); 452 } 453 454 } 455 456 } 457 } 458 459 @if (movePageBehind && isFirstPoster) 460 { 461 <script> 462 ['resize', 'load'].forEach(function (e) { 463 window.addEventListener(e, () => swift.Scroll.setContentPosition()); 464 }); 465 </script> 466 } 467 468 @using System.Collections.Generic 469 @using System.Linq 470 471 @{ 472 var headings = Model.Item?.GetItem("Panel_Text")?.GetItems("Headings") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 473 var widths = Model.Item?.GetItem("Panel_Text")?.GetItems("ColumnTest1") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 474 string layout = Model.Item?.GetItem("Panel_Text")?.GetRawValueString("Layout"); 475 var textColSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Text")?.GetItem("ColumnWidth")); 476 477 var textHeight = string.Empty; 478 479 if (layout == "top-left") 480 { 481 layout = "d-flex flex-column align-items-start"; 482 } else if (layout == "top-center") 483 { 484 layout = "d-flex flex-column align-items-center text-center mx-auto"; 485 } 486 else if (layout == "top-right") 487 { 488 layout = "d-flex flex-column align-items-end text-end ms-auto"; 489 } 490 else if (layout == "center-left") 491 { 492 layout = "d-flex flex-column justify-content-center"; 493 } 494 else if (layout == "center") 495 { 496 layout = "d-flex flex-column justify-content-center align-items-center text-center mx-auto"; 497 } 498 else if (layout == "center-right") 499 { 500 layout = "d-flex flex-column justify-content-center align-items-end text-end ms-auto"; 501 } 502 else if (layout == "bottom-left") 503 { 504 layout = "d-flex flex-column justify-content-end"; 505 } 506 else if (layout == "bottom-center") 507 { 508 layout = "d-flex flex-column justify-content-end align-items-center text-center mx-auto"; 509 } 510 else if (layout == "bottom-right") 511 { 512 layout = "d-flex flex-column justify-content-end align-items-end text-end ms-auto"; 513 } 514 } 515 516 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 517 @using System.Collections.Generic 518 @using Dynamicweb.Ecommerce.ProductCatalog 519 520 @{ 521 string linkType = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") != string.Empty ? Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") : string.Empty; 522 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 523 524 if (linkType == "page" && Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink") != null) 525 { 526 link = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink"); 527 } 528 529 if (linkType == "product-group") 530 { 531 IList<ProductGroupViewModel> selectedGroups = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 532 IList<string> groupIds = new List<string> {}; 533 534 if (selectedGroups != null) 535 { 536 foreach (var fromGroup in selectedGroups) 537 { 538 groupIds.Add(fromGroup.Id); 539 } 540 } 541 542 link = new Dynamicweb.Frontend.LinkViewModel() 543 { 544 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds) 545 }; 546 } 547 548 if (linkType == "product") 549 { 550 ProductListViewModel products = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<ProductListViewModel>("ProductLink"); 551 IList<string> productIds = new List<string> {}; 552 553 if (products != null) 554 { 555 foreach (var product in products.Products) 556 { 557 productIds.Add(product.Id); 558 } 559 } 560 561 string productParameter = productIds.Count == 1 ? "ProductID" : "MainProductId"; 562 string pageTag = productIds.Count == 1 ? "ProductDetailPage" : "Shop"; 563 link = new Dynamicweb.Frontend.LinkViewModel() 564 { 565 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + "&" + productParameter + "=" + string.Join(",", productIds) 566 }; 567 } 568 569 } 570 571 572 @{ 573 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 574 bool hasImage = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null; 575 bool hasGraphic = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") != null; 576 bool hasVideo = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Media" )?.GetItem( "Video" ).GetString( "VideoSourceID" ) ); 577 bool hasLead = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Lead" ) ); 578 bool hasText = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Text" ) ); 579 bool hasTheme = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) ); 580 bool hasHeading = headings.Count() > 0; 581 bool hasButton = buttons.Any(); 582 583 var decorations = Model.Item?.GetItem( "Panel_Settings" )?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 584 var cssClasses = new List<string> { }; 585 string cssDecorations = ""; 586 587 foreach (var itemId in decorations) 588 { 589 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 590 591 if (item != null) 592 { 593 item.TryGetValue("Class", out object classes); 594 595 if (classes is null) 596 { 597 continue; 598 } 599 600 var cssString = (string)classes; 601 if (cssString.StartsWith("[")) 602 { 603 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 604 cssClasses.AddRange(cssArray); 605 } 606 else 607 { 608 cssClasses.Add(cssString.Replace(",", " ")); 609 } 610 } 611 } 612 cssDecorations = string.Join(" ", cssClasses).Trim(); 613 614 ProductViewModel promotionalProduct = null; 615 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 616 { 617 promotionalProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 618 } 619 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 620 { 621 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 622 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 623 624 if (productList?.Products is object) 625 { 626 promotionalProduct = productList.Products[0]; 627 } 628 } 629 630 CategoryFieldViewModel categoryFieldViewModel = null; 631 FieldValueViewModel headerFieldValueViewModel = null; 632 FieldValueViewModel imageFieldValueViewModel = null; 633 FieldValueViewModel textFieldValueViewModel = null; 634 635 if (promotionalProduct != null ) 636 { 637 promotionalProduct.ProductCategories.TryGetValue("Promotional", out categoryFieldViewModel); 638 } 639 } 640 641 @if (Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement") == "image-poster" || Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") == "video-poster") 642 { 643 644 <div class="p-poster-container poster-overlay theme h-100 @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 645 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 646 647 @{ 648 string theme = string.Empty; 649 string posterHeight = string.Empty; 650 string mediaType = Model.Item.GetItem("Panel_Media").GetString("Media"); 651 652 if ( mediaType == "video") 653 { 654 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("Height"); 655 656 theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 657 } else if (mediaType == "image") 658 { 659 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Image").GetString("Height"); 660 661 theme = !string.IsNullOrWhiteSpace(Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme")) ? " theme " + Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; 662 663 } 664 665 posterHeight = posterHeight == "auto" ? "h-100" : posterHeight; 666 posterHeight = posterHeight == "small" ? "min-vh-50 min-vh-md-50" : posterHeight; 667 posterHeight = posterHeight == "medium" ? "min-vh-50 min-vh-md-75" : posterHeight; 668 posterHeight = posterHeight == "large" ? "min-vh-100 min-vh-md-100" : posterHeight; 669 posterHeight = posterHeight == "1x1" ? "ratio ratio-1x1 mx-auto" : posterHeight; 670 posterHeight = posterHeight == "4x3" ? "ratio ratio-4x3 mx-auto" : posterHeight; 671 posterHeight = posterHeight == "16x9" ? "ratio ratio-16x9 mx-auto" : posterHeight; 672 posterHeight = posterHeight == "9x16" ? "ratio ratio-9x16 mx-auto" : posterHeight; 673 posterHeight = posterHeight == "3x4" ? "ratio ratio-3x4 mx-auto" : posterHeight; 674 675 676 } 677 678 <div class="position-relative @(hasText || hasHeading ? "row" : "") @posterHeight @theme @(movePageBehindClass)"> 679 680 @if (Model.Item.GetItem("Panel_Media").GetString("Media") == "video") 681 { 682 <div class="p-poster-video-container position-absolute top-0 bottom-0 end-0 start-0 px-0"> 683 <video preload="auto" loop autoplay muted playsinline class="h-100 w-100" style="object-fit: cover;"> 684 <source src="@Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")" 685 type="video/@Path.GetExtension(Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")).ToLower().Replace(".", "")"> 686 </video> 687 </div> 688 689 } else if (Model.Item.GetItem("Panel_Media").GetString("Media") == "image") 690 { 691 <div class="position-absolute top-0 bottom-0 end-0 start-0 px-0"> 692 693 @if (link != null && !string.IsNullOrEmpty(link.Url)) 694 { 695 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 696 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 697 <a class="bottom-0 position-absolute top-0 w-100" href="@link.Url" @target @rel style="z-index: 2"> 698 </a> 699 } 700 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media").GetItem("Image").GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 701 </div> 702 703 } 704 705 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 706 @using System.Linq 707 708 @if(hasText || hasHeading){ 709 <div class="d-flex @(posterHeight == "none" ? string.Empty : "position-absolute top-0 bottom-0")"> 710 <div class="container-xl mx-auto px-0 py-5 row"> 711 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 712 @using System.Linq 713 714 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 715 { 716 717 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 718 { 719 string headerKey = ""; 720 string headerMarkup = ""; 721 string headingStart = ""; 722 string headingEnd = ""; 723 int headerCount = 0; 724 725 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 726 <div class="p-txt-container-wrap w-100"> 727 @foreach (var heading in headings) 728 { 729 string headningSize = heading.GetString("Size"); 730 string headingDisplaySize = heading.GetString("DisplaySize"); 731 bool headingAccentColor = heading.GetBoolean("AccentColor"); 732 bool headingAccentLine = heading.GetBoolean("AccentLine"); 733 734 if (headerKey != headningSize) 735 { 736 if (headerCount > 0) 737 { 738 headingEnd = $"</{headningSize}>"; 739 headerMarkup += headingEnd; 740 } 741 headerKey = headningSize; 742 headingStart = $"<{headningSize}>"; 743 headerMarkup += headingStart; 744 } 745 else if (headerCount > 0 && headerKey == headningSize) 746 { 747 headerMarkup += "<br>"; 748 } 749 750 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 751 headerMarkup += heading.GetString("Heading"); 752 headerMarkup += "</span>"; 753 754 headerCount++; 755 756 if (headerCount == headings.Count()) 757 { 758 headingEnd = $"</{headningSize}>"; 759 headerMarkup += headingEnd; 760 } 761 } 762 763 @if (headerMarkup != "") 764 { 765 @headerMarkup 766 } 767 768 769 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 770 { 771 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 772 } 773 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 774 { 775 @Model.Item.GetItem("Panel_Text").GetString("Text") 776 } 777 778 @RenderButtons() 779 </div> 780 </div> 781 } 782 } 783 784 </div> 785 </div> 786 } 787 788 </div> 789 790 </div> 791 } 792 else 793 { 794 795 if( hasImage || hasGraphic || hasVideo || hasLead || hasText || hasHeading || hasButton || promotionalProduct != null) 796 { 797 798 <div class="p-panel-container row @textHeight @imgPlacement @(hasTheme ? "theme " + Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 799 800 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Header", out headerFieldValueViewModel)) 801 { 802 if (headerFieldValueViewModel.Value != null) 803 { 804 string promotionalHeaderText = headerFieldValueViewModel.Value.ToString(); 805 promotionalHeaderText = promotionalHeaderText.Replace("{{D1}}", "<span class=\"display-1\">"); 806 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1}}", "</span>"); 807 promotionalHeaderText = promotionalHeaderText.Replace("{{D1:AccentColor}}", "<span class=\"display-1 text-accent\">"); 808 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1:AccentColor}}", "</span>"); 809 promotionalHeaderText = promotionalHeaderText.Replace("{{D2}}", "<span class=\"display-2\">"); 810 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2}}", "</span>"); 811 promotionalHeaderText = promotionalHeaderText.Replace("{{D2:AccentColor}}", "<span class=\"display-2 text-accent\">"); 812 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2:AccentColor}}", "</span>"); 813 promotionalHeaderText = promotionalHeaderText.Replace("{{D3}}", "<span class=\"display-3\">"); 814 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3}}", "</span>"); 815 promotionalHeaderText = promotionalHeaderText.Replace("{{D3:AccentColor}}", "<span class=\"display-3 text-accent\">"); 816 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3:AccentColor}}", "</span>"); 817 promotionalHeaderText = promotionalHeaderText.Replace("®", "<sup>®</sup>"); 818 promotionalHeaderText = promotionalHeaderText.Replace("{{BR}}", "<br>"); 819 820 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 821 <div class="p-txt-container-wrap"> 822 <h2> 823 @promotionalHeaderText 824 </h2> 825 </div> 826 </div> 827 } 828 } 829 830 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Image", out imageFieldValueViewModel)) 831 { 832 if (imageFieldValueViewModel.Value != null) 833 { 834 string imagePath = imageFieldValueViewModel.Value.ToString(); 835 var promotionalImageParms = new Dictionary<string, object>(); 836 promotionalImageParms.Add("loading", "lazy"); 837 promotionalImageParms.Add("columns", Model.GridRowColumnCount); 838 839 promotionalImageParms.Add("fullwidth", true); 840 promotionalImageParms.Add("cssClass", "img-fluid w-100"); 841 promotionalImageParms.Add("style", "max-width: 60rem;transform: translateY(-6rem);margin-bottom: -6rem;"); 842 843 <div class="p-img-container d-flex justify-content-center"> 844 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, promotionalImageParms) 845 </div> 846 } 847 } 848 849 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Text", out textFieldValueViewModel)) 850 { 851 if (textFieldValueViewModel.Value != null) 852 { 853 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 854 <div class="p-txt-container-wrap" style="max-width: 70rem;"> 855 @textFieldValueViewModel.Value 856 </div> 857 </div> 858 } 859 } 860 861 @if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 862 { 863 if (Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null) 864 { 865 866 string imgPadding = string.Empty; 867 868 if (headings.Count() > 0 && imgFloat == "top") 869 { 870 imgPadding = "mb-4"; 871 } 872 873 else if (buttons.Any() && imgFloat == "top") 874 { 875 imgPadding = "mb-4"; 876 } 877 878 else if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text")) && imgFloat == "top") 879 { 880 imgPadding = "mb-4"; 881 } 882 883 else 884 { 885 imgPadding = "mb-4 mb-sm-0"; 886 } 887 888 string imgAlignment = string.Empty; 889 890 if(imgPosition == "image-left") 891 { 892 imgAlignment = "me-auto"; 893 } 894 else if(imgPosition == "image-right") 895 { 896 imgAlignment = "ms-auto"; 897 } 898 else 899 { 900 imgAlignment = "mx-auto"; 901 } 902 903 var offsets = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Offsets"); 904 905 string desktopOffset = string.Empty; 906 string mobileOffset = string.Empty; 907 string tabletOffset = string.Empty; 908 string XLOffset = string.Empty; 909 910 if(offsets != null) 911 { 912 if(!string.IsNullOrEmpty(offsets.GetString("Offset"))) 913 { 914 desktopOffset = $"transform: translate({offsets.GetString("Offset")});"; 915 } 916 if(!string.IsNullOrEmpty(offsets.GetString("Mobile"))) 917 { 918 mobileOffset = $"transform: translate({offsets.GetString("Mobile")});"; 919 } 920 if(!string.IsNullOrEmpty(offsets.GetString("Tablet"))) 921 { 922 tabletOffset = $"transform: translate({offsets.GetString("Tablet")});"; 923 } 924 if(!string.IsNullOrEmpty(offsets.GetString("XL"))) 925 { 926 XLOffset = $"transform: translate({offsets.GetString("XL")});"; 927 } 928 } 929 930 if (!string.IsNullOrEmpty(mobileOffset) || !string.IsNullOrEmpty(tabletOffset) || !string.IsNullOrEmpty(desktopOffset) || !string.IsNullOrEmpty(XLOffset)) 931 { 932 <style> 933 @if (!string.IsNullOrEmpty(mobileOffset)) 934 { 935 <text> 936 @@media (min-width: 300px) { 937 [id='@(Model.ID)'] .p-img-container { 938 @mobileOffset 939 } 940 } 941 </text> 942 } 943 @if (!string.IsNullOrEmpty(tabletOffset)) 944 { 945 <text> 946 @@media (min-width: 768px) { 947 [id='@(Model.ID)'] .p-img-container { 948 @tabletOffset 949 } 950 } 951 </text> 952 } 953 954 @if (!string.IsNullOrEmpty(desktopOffset)) 955 { 956 <text> 957 @@media(min-width: 992px) 958 { 959 [id='@(Model.ID)'] .p-img-container { 960 @desktopOffset 961 } 962 } 963 </text> 964 } 965 966 @if (!string.IsNullOrEmpty(XLOffset)) 967 { 968 <text> 969 @@media(min-width: 1920px) 970 { 971 [id='@(Model.ID)'] .p-img-container { 972 @XLOffset 973 } 974 } 975 </text> 976 } 977 978 [id='@(Model.ID)'] .p-img-container { 979 z-index: 2; 980 position: relative; 981 } 982 </style> 983 } 984 985 <div class="@imgPadding p-img-container @colSizeClasslist @imgAlignment"> 986 987 @if (link != null && !string.IsNullOrEmpty(link.Url)) 988 { 989 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 990 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 991 <a href="@link.Url" @target @rel> 992 @RenderImage() 993 </a> 994 } 995 else 996 { 997 @RenderImage() 998 } 999 1000 </div> 1001 } 1002 1003 } 1004 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 1005 { 1006 <div class="p-graphic-container mb-3 col flex-grow-0 pe-0"> 1007 <div class="@(layout) [email protected]("Panel_Media").GetItem("Graphic").GetString("GraphicSize")"> 1008 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel()) 1009 </div> 1010 </div> 1011 1012 } 1013 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Video") 1014 { 1015 if (Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") != "video-poster") 1016 { 1017 <div class="p-video-container"> 1018 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1019 @using Dynamicweb.Ecommerce.ProductCatalog 1020 1021 @{ 1022 1023 1024 string visual = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Visual", "inline"); 1025 1026 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1027 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1028 1029 Dynamicweb.Frontend.FileViewModel video = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPath"); 1030 string videoPath = video?.Path ?? ""; 1031 1032 string posterPath = "/Admin/Public/GetImage.ashx?image=" + @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster") + "&width=1000&format=webp"; 1033 1034 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/play.svg"; 1035 string theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 1036 } 1037 1038 1039 @switch(visual) { 1040 case "inline" : 1041 <div class="h-100 position-relative grid grid-1"> 1042 1043 @switch (provider) 1044 { 1045 case "youtube" : 1046 case "vimeo" : 1047 1048 <div 1049 id="[email protected]" 1050 class="player plyr__video-embed @(theme) h-100 w-100" 1051 data-plyr-provider="@provider" 1052 data-plyr-embed-id="@videoId" 1053 style="--plyr-color-main: var(--swift-foreground-color); " 1054 > 1055 </div> 1056 1057 break; 1058 1059 case "self-hosted" : 1060 1061 <video 1062 id="[email protected]" 1063 class="player plyr__video-embed @(theme) h-100 w-100" 1064 src="@videoPath" 1065 style="--plyr-color-main: var(--swift-foreground-color);" 1066 preload="metadata" 1067 poster="@posterPath"> 1068 </video> 1069 1070 break; 1071 } 1072 <script type="module" defer src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1073 <script type="module" defer> 1074 1075 const player = new Plyr('#[email protected]', { 1076 type: 'video', 1077 youtube: { 1078 noCookie: true, 1079 showinfo: 0 1080 }, 1081 fullscreen: { 1082 enabled: true, 1083 iosNative: true, 1084 } 1085 }); 1086 </script> 1087 1088 </div> 1089 1090 break; 1091 1092 case "poster-modal" : 1093 <div class="h-100 position-relative@(theme) grid grid-1"> 1094 <div class="player position-relative" data-player="[email protected]"> 1095 1096 @RenderVideo() 1097 1098 <div class="position-absolute top-0 bottom-0 end-0 start-0 h-100 d-flex align-items-center justify-content-center gradient-overlay"> 1099 <button type="button" class="btn btn-primary rounded-circle lh-1 p-3" data-bs-toggle="modal" data-bs-target="#[email protected]"> 1100 <span class="icon-3"> 1101 @ReadFile(iconPath) 1102 </span> 1103 <span class="visually-hidden">@Translate("Play video")</span> 1104 </button> 1105 </div> 1106 </div> 1107 </div> 1108 1109 <div class="modal fade" id="[email protected]" tabindex="-1" aria-hidden="true"> 1110 <div class="modal-dialog modal-xl modal-dialog-centered"> 1111 <div class="modal-content"> 1112 <div class="modal-body p-0"> 1113 1114 @switch (provider) 1115 { 1116 case "youtube" : 1117 case "vimeo" : 1118 1119 <div 1120 id="[email protected]" 1121 class="player plyr__video-embed @(theme) h-100 w-100" 1122 data-plyr-provider="@provider" 1123 data-plyr-embed-id="@videoId" 1124 style="--plyr-color-main: var(--swift-foreground-color); " 1125 > 1126 </div> 1127 1128 break; 1129 1130 case "self-hosted" : 1131 1132 <video 1133 id="[email protected]" 1134 class="player plyr__video-embed @(theme) h-100 w-100" 1135 src="@videoPath" 1136 style="--plyr-color-main: var(--swift-foreground-color);" 1137 preload="metadata" 1138 > 1139 </video> 1140 1141 break; 1142 } 1143 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1144 <script type="module"> 1145 1146 var player = new Plyr('#[email protected]', { 1147 youtube: { 1148 noCookie: true, 1149 showinfo: 0 1150 }, 1151 fullscreen: { 1152 enabled: true, 1153 iosNative: true, 1154 } 1155 }); 1156 1157 document.querySelector('#[email protected]').addEventListener('show.bs.modal', function (event) { 1158 player.togglePlay(); 1159 1160 player.on('ready', event => { 1161 player.play(); 1162 }); 1163 }); 1164 1165 document.querySelector('#[email protected]').addEventListener('hide.bs.modal', function (event) { 1166 player.pause(); 1167 }); 1168 </script> 1169 1170 </div> 1171 </div> 1172 </div> 1173 </div> 1174 1175 break; 1176 } 1177 1178 @helper RenderVideo() 1179 { 1180 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1181 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1182 string ratio = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("AspectRatio", ""); 1183 ratio = ratio != "0" ? ratio : ""; 1184 string ratioCssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 1185 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : ""; 1186 string fillClass = ratio == "fill" ? " h-100" : ""; 1187 1188 var parms = new Dictionary<string, object>(); 1189 parms.Add("loading", "lazy"); 1190 if (ratio == "fill") { 1191 parms.Add("cssClass", "w-100 h-100"); 1192 } 1193 else 1194 { 1195 parms.Add("cssClass", "mw-100 mh-100"); 1196 } 1197 parms.Add("style",""); 1198 parms.Add("alt", @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("ImageAltText")); 1199 parms.Add("columns", Model.GridRowColumnCount); 1200 1201 <figure class="m-0@(ratioCssClass)@(fillClass)" @ratioVariable> 1202 1203 @if (string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster"))) 1204 { 1205 switch (provider) 1206 { 1207 case "youtube" : 1208 @RenderYouTubePoster(videoId) 1209 break; 1210 1211 case "vimeo" : 1212 @RenderVimeoPoster(videoId) 1213 break; 1214 } 1215 } 1216 else 1217 { 1218 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPoster") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 1219 } 1220 1221 </figure> 1222 } 1223 1224 @helper RenderYouTubePoster(string videoId) 1225 { 1226 <script type="module"> 1227 function setVideoThumbnail(source) { 1228 var figure = document.querySelector("[data-player='[email protected]'] figure"); 1229 var thumbnail = document.createElement("img"); 1230 thumbnail.style = "object-fit: cover;"; 1231 thumbnail.classList.add('mw-100','mh-100'); 1232 thumbnail.src = source; 1233 figure.appendChild(thumbnail); 1234 }; 1235 setVideoThumbnail('https://i.ytimg.com/vi/@(videoId)/hqdefault.jpg'); 1236 </script> 1237 } 1238 1239 @helper RenderVimeoPoster(string videoId) 1240 { 1241 <script type="module"> 1242 function setVideoThumbnail(source) { 1243 let figure = document.querySelector("[data-player='[email protected]'] figure"); 1244 let thumbnail = document.createElement("img"); 1245 thumbnail.style = "object-fit: cover;"; 1246 thumbnail.classList.add('mw-100','mh-100'); 1247 thumbnail.src = source; 1248 figure.appendChild(thumbnail); 1249 }; 1250 function getVimeoThumbnail() { 1251 fetch('https://vimeo.com/api/v2/video/@(videoId).json') 1252 .then(function(response) { 1253 return response.text(); 1254 }) 1255 .then(function(data) { 1256 let { thumbnail_large } = JSON.parse(data)[0]; 1257 let thumbnail = `${thumbnail_large}`; 1258 thumbnail = thumbnail.replace("_640", "_1920"); 1259 setVideoThumbnail(thumbnail); 1260 }) 1261 .catch(error => { 1262 console.log(error); 1263 }); 1264 } 1265 1266 getVimeoThumbnail(); 1267 </script> 1268 } 1269 1270 </div> 1271 } 1272 } 1273 1274 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1275 @using System.Linq 1276 1277 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 1278 { 1279 1280 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1281 { 1282 string headerKey = ""; 1283 string headerMarkup = ""; 1284 string headingStart = ""; 1285 string headingEnd = ""; 1286 int headerCount = 0; 1287 1288 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 1289 <div class="p-txt-container-wrap w-100"> 1290 @foreach (var heading in headings) 1291 { 1292 string headningSize = heading.GetString("Size"); 1293 string headingDisplaySize = heading.GetString("DisplaySize"); 1294 bool headingAccentColor = heading.GetBoolean("AccentColor"); 1295 bool headingAccentLine = heading.GetBoolean("AccentLine"); 1296 1297 if (headerKey != headningSize) 1298 { 1299 if (headerCount > 0) 1300 { 1301 headingEnd = $"</{headningSize}>"; 1302 headerMarkup += headingEnd; 1303 } 1304 headerKey = headningSize; 1305 headingStart = $"<{headningSize}>"; 1306 headerMarkup += headingStart; 1307 } 1308 else if (headerCount > 0 && headerKey == headningSize) 1309 { 1310 headerMarkup += "<br>"; 1311 } 1312 1313 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 1314 headerMarkup += heading.GetString("Heading"); 1315 headerMarkup += "</span>"; 1316 1317 headerCount++; 1318 1319 if (headerCount == headings.Count()) 1320 { 1321 headingEnd = $"</{headningSize}>"; 1322 headerMarkup += headingEnd; 1323 } 1324 } 1325 1326 @if (headerMarkup != "") 1327 { 1328 @headerMarkup 1329 } 1330 1331 1332 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 1333 { 1334 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 1335 } 1336 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1337 { 1338 @Model.Item.GetItem("Panel_Text").GetString("Text") 1339 } 1340 1341 @RenderButtons() 1342 </div> 1343 </div> 1344 } 1345 } 1346 1347 1348 </div> 1349 } 1350 else 1351 { 1352 if(Pageview.IsVisualEditorMode) { 1353 <div class="alert alert-warning" role="alert"> 1354 This paragraph is empty 1355 </div> 1356 } 1357 } 1358 } 1359 @Model.GetModuleOutput() 1360
    Error executing template "Designs/Swift/Paragraph/Base_Panel.cshtml"
    System.NullReferenceException: Object reference not set to an instance of an object.
       at CompiledRazorTemplates.Dynamic.RazorEngine_9ae15ff2a1324c908ed02e4e2f8692ec.Execute() in D:\Dynamicweb.NET\Solutions\Sika\Files\Templates\Designs\Swift\Paragraph\Base_Panel.cshtml:line 619
       at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
       at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
       at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
       at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
       at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
       at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
       at Dynamicweb.Rendering.Template.RenderRazorTemplate()
    
    1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 3 @using System.Collections.Generic 4 @using System.Linq 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @helper RenderButtons() 8 { 9 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 10 int loopCounter = 0; 11 12 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 13 14 string linkType = string.Empty; 15 16 foreach (var button in buttons) 17 { 18 loopCounter++; 19 } 20 21 if (buttons.Any()) 22 { 23 <div class="d-flex flex-wrap grid"> 24 @foreach (var button in buttons) 25 { 26 27 linkType = button.GetItem("Link").GetString("LinkType"); 28 29 if (linkType == "page" && button.GetItem("Link").GetLink("ButtonLink") != null) 30 { 31 link = button.GetItem("Link").GetLink("ButtonLink"); 32 } 33 34 if (linkType == "product-group") 35 { 36 37 IList<ProductGroupViewModel> selectedGroups = button.GetItem("Link").GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 38 39 IList<string> groupIds = new List<string> { }; 40 41 if (selectedGroups != null) 42 { 43 foreach (var fromGroup in selectedGroups) 44 { 45 groupIds.Add(fromGroup.Id); 46 } 47 } 48 link = new Dynamicweb.Frontend.LinkViewModel() 49 { 50 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds).Trim(), 51 IsExternal = false 52 }; 53 } 54 55 if (linkType == "product") 56 { 57 ProductListViewModel products = button.GetItem("Link").GetValue<ProductListViewModel>("ProductLink"); 58 IList<string> productIds = new List<string> { }; 59 string productPrimaryOrDefaultGroupID = string.Empty; 60 string pageTag = "Shop"; 61 62 if (products != null) 63 { 64 foreach (ProductViewModel product in products.Products) 65 { 66 productIds.Add(product.Id); 67 productPrimaryOrDefaultGroupID = product.PrimaryOrDefaultGroup.Id; 68 } 69 } 70 71 string productParameter = "MainProductId"; 72 string productGroupParameter = string.Empty; 73 if (productIds.Count == 1) 74 { 75 productParameter = "ProductID"; 76 if (!string.IsNullOrEmpty(productPrimaryOrDefaultGroupID)) 77 { 78 productGroupParameter = $"&GroupID={productPrimaryOrDefaultGroupID}"; 79 } 80 } 81 82 link = new Dynamicweb.Frontend.LinkViewModel() 83 { 84 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + productGroupParameter + "&" + productParameter + "=" + string.Join(",", productIds).Trim(), 85 IsExternal = false 86 }; 87 } 88 89 if (!string.IsNullOrEmpty(button.GetItem("Link").GetString("ButtonLink")) || !string.IsNullOrEmpty(button.GetItem("Link").GetString("ProductLink"))) 90 { 91 string classes = ""; 92 93 if (button.GetString("ButtonStyling") != "none") 94 { 95 classes = $"btn btn-{button.GetString("ButtonStyling")}"; 96 } 97 98 <p class="@(button.GetBoolean("NoWrap") ? "w-100" : "")"> 99 <a class="@classes" href="@link" target="@(link.Url.Contains("http") == true || link.Url.Contains("/Files/Files/") ? "_blank" : string.Empty)"> 100 @if (!string.IsNullOrEmpty(button.GetString("Icon"))) 101 { 102 <span class="icon-2" aria-hidden="true"> 103 @ReadFile(button.GetString("Icon")) 104 </span> 105 } 106 107 @button.GetString("ButtonText") 108 </a> 109 </p> 110 } 111 } 112 </div> 113 } 114 } 115 116 @using System.Collections.Generic 117 @using System.Linq 118 @using Dynamicweb.Content.Items 119 120 @functions 121 { 122 123 public string GetContainerClassList(Dynamicweb.Frontend.GridRowViewModel model) 124 { 125 List<string> returnValues = new List<string>(); 126 string container = "container-xl"; 127 128 if (model.Item.GetString("Width") == "bleed") 129 { 130 if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-end") 131 { 132 container = "container-xl me-lg-0 pe-lg-0"; 133 } 134 else if (model.Item?.GetRawValueString("OverallAlignment") == "justify-content-start") 135 { 136 container = "container-xl ms-lg-0 ps-lg-0"; 137 } 138 else 139 { 140 container = "container-fluid mx-0 px-0"; 141 } 142 } 143 144 returnValues.Add(container); 145 return string.Join(" ", returnValues); 146 } 147 148 149 150 public string GetColumnWidthClassList(Dynamicweb.Frontend.ItemViewModel model, bool isVisualEditor = false) 151 { 152 153 string columnWidth = isVisualEditor ? "col" : ""; 154 string mobileWidth = string.Empty; 155 string tabletWidth = string.Empty; 156 string desktopWidth = string.Empty; 157 string XLWidth = string.Empty; 158 159 if (model != null) 160 { 161 162 if (model.GetField("Mobile").GetRawValue() != null && model.GetField("Mobile").GetRawValue().ToString() != "auto") 163 { 164 165 mobileWidth = "col-" + model.GetField("Mobile").GetRawValue(); 166 if (model.GetField("Tablet").GetRawValue() == null) 167 { 168 mobileWidth = mobileWidth + " col-sm"; 169 } 170 } 171 if (model.GetField("Width").GetRawValue() != null && model.GetField("Width").GetRawValue().ToString() != "auto") 172 { 173 desktopWidth = "col-md-" + model.GetField("Width").GetRawValue(); 174 } 175 if (model.GetField("Tablet").GetRawValue() != null && model.GetField("Tablet").GetRawValue().ToString() != "auto") 176 { 177 178 desktopWidth = " col-lg-" + model.GetField("Width").GetRawValue(); 179 tabletWidth = "col-md-" + model.GetField("Tablet").GetRawValue(); 180 if (model.GetField("XL").GetRawValue() == null) 181 { 182 tabletWidth = tabletWidth + " col-lg-" + model.GetField("Width").GetRawValue(); 183 } 184 } 185 if (model.GetField("XL").GetRawValue() != null && model.GetField("XL").GetRawValue().ToString() != "auto") 186 { 187 XLWidth = "col-xxxl-" + model.GetField("XL").GetRawValue(); 188 } 189 190 columnWidth = $"col {mobileWidth} {tabletWidth} {desktopWidth} {XLWidth}"; 191 192 } 193 return string.Join(" ", columnWidth); 194 } 195 196 public string GetRowWidthClassList(Dynamicweb.Frontend.GridRowViewModel model) 197 { 198 List<string> returnValues = new List<string>(); 199 200 string rowWidth = model.Item.GetRawValueString("Width", string.Empty).ToLower(); 201 202 if (rowWidth == "6") 203 { 204 returnValues.Add("col-12 col-lg-6"); 205 } 206 if (rowWidth == "8") 207 { 208 returnValues.Add("col-12 col-lg-8"); 209 } 210 if (rowWidth == "9") 211 { 212 returnValues.Add("col-12 col-lg-9"); 213 } 214 if (rowWidth == "10") 215 { 216 returnValues.Add("col-12 col-lg-10"); 217 } 218 if (rowWidth == "12") 219 { 220 returnValues.Add("col-12 col-lg-12"); 221 } 222 if (rowWidth == "bleed") 223 { 224 returnValues.Add("col-12"); 225 } 226 227 return string.Join(" ", returnValues); 228 } 229 230 public string GetSectionContentAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 231 { 232 List<string> returnValues = new List<string>(); 233 234 returnValues.Add(model.Item.GetRawValueString("OverallAlignment", string.Empty).ToLower()); 235 236 return string.Join(" ", returnValues); 237 } 238 239 public string GetRowHorizontalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 240 { 241 242 List<string> returnValues = new List<string>(); 243 244 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 245 246 return string.Join(" ", returnValues); 247 } 248 249 public string GetRowVerticalAlignmentClassList(Dynamicweb.Frontend.GridRowViewModel model) 250 { 251 252 List<string> returnValues = new List<string>(); 253 254 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 255 256 return string.Join(" ", returnValues); 257 } 258 259 public string GetRowSpacing(Dynamicweb.Frontend.GridRowViewModel model) 260 { 261 List<string> returnValues = new List<string>(); 262 263 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 264 265 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 266 267 return string.Join(" ", returnValues); 268 } 269 270 public string GetRowClassList(Dynamicweb.Frontend.GridRowViewModel model) 271 { 272 273 List<string> returnValues = new List<string>(); 274 275 string mobileOrderFirst = string.Empty; 276 if (model.Item.GetBoolean("MobileOrderReverse")) 277 { 278 mobileOrderFirst = "flex-column-reverse flex-md-row"; 279 } 280 returnValues.Add(mobileOrderFirst); 281 282 returnValues.Add(model.Item.GetRawValueString("HorizontalAlignment", string.Empty).ToLower()); 283 returnValues.Add(model.Item.GetRawValueString("VerticalAlignment", string.Empty).ToLower()); 284 285 string disableGutters = model.Item.GetRawValueString("ContentSpacing", string.Empty).ToLower(); 286 287 returnValues.Add(disableGutters == "disable-gutters" ? "g-0" : "g-4"); 288 289 return string.Join(" ", returnValues); 290 } 291 292 public string GetSectionClassList(Dynamicweb.Frontend.GridRowViewModel model) 293 { 294 List<string> returnValues = new List<string>(); 295 returnValues.Add($"item_{model.Item.SystemName.ToLower()}"); 296 returnValues.Add(!string.IsNullOrWhiteSpace(model.Item.GetRawValueString("Theme")) ? " theme " + model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""); 297 string paddingTop = model.Item.GetRawValueString("PaddingTop", "large"); 298 string paddingBottom = model.Item.GetRawValueString("PaddingBottom", "large"); 299 300 if (paddingTop == "none") 301 { 302 returnValues.Add("pt-0"); 303 } 304 if (paddingTop == "small") 305 { 306 returnValues.Add("pt-4"); 307 } 308 if (paddingTop == "medium") 309 { 310 returnValues.Add("pt-5"); 311 } 312 if (paddingTop == "large") { 313 returnValues.Add("pt-7"); 314 } 315 316 if (paddingBottom == "none") 317 { 318 returnValues.Add("pb-0"); 319 } 320 if (paddingBottom == "small") 321 { 322 returnValues.Add("pb-4"); 323 } 324 if (paddingBottom == "medium") 325 { 326 returnValues.Add("pb-5"); 327 } 328 if (paddingBottom == "large") { 329 returnValues.Add("pb-7"); 330 } 331 332 var decorations = model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 333 var cssClasses = new List<string> { }; 334 335 foreach (var itemId in decorations) 336 { 337 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 338 339 if (item != null) 340 { 341 item.TryGetValue("Class", out object classes); 342 343 if (classes is null) 344 { 345 continue; 346 } 347 348 var cssString = (string)classes; 349 if (cssString.StartsWith("[")) 350 { 351 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 352 cssClasses.AddRange(cssArray); 353 } 354 else 355 { 356 cssClasses.Add(cssString.Replace(",", " ")); 357 } 358 } 359 } 360 returnValues.Add(string.Join(" ", cssClasses).Trim()); 361 362 return string.Join(" ", returnValues); 363 } 364 365 } 366 367 368 @helper RenderImage() 369 { 370 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("Image"))) 371 { 372 string ratioCssClass = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "ratio" : string.Empty; 373 string ratioVariable = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "0" && Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") != "" ? "style=\"--bs-aspect-ratio: " + Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageAspectRatio") + "\"" : string.Empty; 374 string ImageObjectFit = Model.Item?.GetItem("Panel_Media").GetItem("Image").GetRawValueString("ImageObjectFit", string.Empty); 375 ImageObjectFit = ImageObjectFit == "cover" ? string.Empty : ImageObjectFit; 376 ImageObjectFit = ImageObjectFit == "contain" ? "object-fit:contain" : ImageObjectFit; 377 378 var parms = new Dictionary<string, object>(); 379 parms.Add("loading", "lazy"); 380 parms.Add("style", ImageObjectFit); 381 parms.Add("alt", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageAltText")); 382 parms.Add("columns", Model.GridRowColumnCount); 383 384 parms.Add("fullwidth", true); 385 parms.Add("cssClass", "img-fluid w-100 " + Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImageCustomClasses")); 386 387 388 <figure class="mb-0 @ratioCssClass" @ratioVariable> 389 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 390 </figure> 391 } 392 } 393 394 @{ 395 var colSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("ColumnWidth")); 396 397 string imgPosition = string.Empty; 398 string imgPlacement = string.Empty; 399 string imgFloat = string.Empty; 400 401 if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 402 { 403 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement"); 404 } 405 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 406 { 407 imgPosition = Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetString("ImagePlacement"); 408 } 409 410 if (imgPosition == "image-top") 411 { 412 imgPlacement = "flex-column"; 413 imgFloat = "top"; 414 } else if (imgPosition == "image-left") 415 { 416 imgPlacement = "flex-column flex-md-row"; 417 imgFloat = "left-right"; 418 } else if (imgPosition == "image-right") 419 { 420 imgPlacement = "flex-column flex-md-row-reverse"; 421 imgFloat = "left-right"; 422 } 423 424 425 426 var parms = new Dictionary<string, object>(); 427 parms.Add("cssClass", "h-100 w-100"); 428 429 } 430 431 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 432 @using Dynamicweb.Ecommerce.ProductCatalog 433 @using System.IO 434 @using Dynamicweb.Frontend 435 436 @{ 437 bool movePageBehind = false; 438 bool isFirstPoster = false; 439 string movePageBehindClass = ""; 440 if (Pageview.Page.PropertyItem != null) 441 { 442 string headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 443 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 444 445 if (movePageBehind) 446 { 447 movePageBehindClass = " poster-behind"; 448 if (!Dynamicweb.Context.Current.Items.Contains("firstPosterIsRendered")) 449 { 450 isFirstPoster = true; 451 Dynamicweb.Context.Current.Items.Add("firstPosterIsRendered", true); 452 } 453 454 } 455 456 } 457 } 458 459 @if (movePageBehind && isFirstPoster) 460 { 461 <script> 462 ['resize', 'load'].forEach(function (e) { 463 window.addEventListener(e, () => swift.Scroll.setContentPosition()); 464 }); 465 </script> 466 } 467 468 @using System.Collections.Generic 469 @using System.Linq 470 471 @{ 472 var headings = Model.Item?.GetItem("Panel_Text")?.GetItems("Headings") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 473 var widths = Model.Item?.GetItem("Panel_Text")?.GetItems("ColumnTest1") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 474 string layout = Model.Item?.GetItem("Panel_Text")?.GetRawValueString("Layout"); 475 var textColSizeClasslist = GetColumnWidthClassList(Model.Item?.GetItem("Panel_Text")?.GetItem("ColumnWidth")); 476 477 var textHeight = string.Empty; 478 479 if (layout == "top-left") 480 { 481 layout = "d-flex flex-column align-items-start"; 482 } else if (layout == "top-center") 483 { 484 layout = "d-flex flex-column align-items-center text-center mx-auto"; 485 } 486 else if (layout == "top-right") 487 { 488 layout = "d-flex flex-column align-items-end text-end ms-auto"; 489 } 490 else if (layout == "center-left") 491 { 492 layout = "d-flex flex-column justify-content-center"; 493 } 494 else if (layout == "center") 495 { 496 layout = "d-flex flex-column justify-content-center align-items-center text-center mx-auto"; 497 } 498 else if (layout == "center-right") 499 { 500 layout = "d-flex flex-column justify-content-center align-items-end text-end ms-auto"; 501 } 502 else if (layout == "bottom-left") 503 { 504 layout = "d-flex flex-column justify-content-end"; 505 } 506 else if (layout == "bottom-center") 507 { 508 layout = "d-flex flex-column justify-content-end align-items-center text-center mx-auto"; 509 } 510 else if (layout == "bottom-right") 511 { 512 layout = "d-flex flex-column justify-content-end align-items-end text-end ms-auto"; 513 } 514 } 515 516 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 517 @using System.Collections.Generic 518 @using Dynamicweb.Ecommerce.ProductCatalog 519 520 @{ 521 string linkType = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") != string.Empty ? Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetRawValueString("LinkType", "page") : string.Empty; 522 Dynamicweb.Frontend.LinkViewModel link = new Dynamicweb.Frontend.LinkViewModel(); 523 524 if (linkType == "page" && Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink") != null) 525 { 526 link = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetLink("ButtonLink"); 527 } 528 529 if (linkType == "product-group") 530 { 531 IList<ProductGroupViewModel> selectedGroups = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<IList<ProductGroupViewModel>>("ProductGroupLink"); 532 IList<string> groupIds = new List<string> {}; 533 534 if (selectedGroups != null) 535 { 536 foreach (var fromGroup in selectedGroups) 537 { 538 groupIds.Add(fromGroup.Id); 539 } 540 } 541 542 link = new Dynamicweb.Frontend.LinkViewModel() 543 { 544 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + string.Join(",", groupIds) 545 }; 546 } 547 548 if (linkType == "product") 549 { 550 ProductListViewModel products = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Link")?.GetValue<ProductListViewModel>("ProductLink"); 551 IList<string> productIds = new List<string> {}; 552 553 if (products != null) 554 { 555 foreach (var product in products.Products) 556 { 557 productIds.Add(product.Id); 558 } 559 } 560 561 string productParameter = productIds.Count == 1 ? "ProductID" : "MainProductId"; 562 string pageTag = productIds.Count == 1 ? "ProductDetailPage" : "Shop"; 563 link = new Dynamicweb.Frontend.LinkViewModel() 564 { 565 Url = "/Default.aspx?ID=" + GetPageIdByNavigationTag(pageTag) + "&" + productParameter + "=" + string.Join(",", productIds) 566 }; 567 } 568 569 } 570 571 572 @{ 573 var buttons = Model.Item?.GetItem("Panel_Text")?.GetItems("Buttons") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 574 bool hasImage = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null; 575 bool hasGraphic = Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") != null; 576 bool hasVideo = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Media" )?.GetItem( "Video" ).GetString( "VideoSourceID" ) ); 577 bool hasLead = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Lead" ) ); 578 bool hasText = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Text" )?.GetString( "Text" ) ); 579 bool hasTheme = !string.IsNullOrEmpty( Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) ); 580 bool hasHeading = headings.Count() > 0; 581 bool hasButton = buttons.Any(); 582 583 var decorations = Model.Item?.GetItem( "Panel_Settings" )?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 584 var cssClasses = new List<string> { }; 585 string cssDecorations = ""; 586 587 foreach (var itemId in decorations) 588 { 589 var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); 590 591 if (item != null) 592 { 593 item.TryGetValue("Class", out object classes); 594 595 if (classes is null) 596 { 597 continue; 598 } 599 600 var cssString = (string)classes; 601 if (cssString.StartsWith("[")) 602 { 603 var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); 604 cssClasses.AddRange(cssArray); 605 } 606 else 607 { 608 cssClasses.Add(cssString.Replace(",", " ")); 609 } 610 } 611 } 612 cssDecorations = string.Join(" ", cssClasses).Trim(); 613 614 ProductViewModel promotionalProduct = null; 615 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 616 { 617 promotionalProduct = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 618 } 619 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 620 { 621 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 622 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 623 624 if (productList?.Products is object) 625 { 626 promotionalProduct = productList.Products[0]; 627 } 628 } 629 630 CategoryFieldViewModel categoryFieldViewModel = null; 631 FieldValueViewModel headerFieldValueViewModel = null; 632 FieldValueViewModel imageFieldValueViewModel = null; 633 FieldValueViewModel textFieldValueViewModel = null; 634 635 if (promotionalProduct != null ) 636 { 637 promotionalProduct.ProductCategories.TryGetValue("Promotional", out categoryFieldViewModel); 638 } 639 } 640 641 @if (Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetString("ImagePlacement") == "image-poster" || Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") == "video-poster") 642 { 643 644 <div class="p-poster-container poster-overlay theme h-100 @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 645 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 646 647 @{ 648 string theme = string.Empty; 649 string posterHeight = string.Empty; 650 string mediaType = Model.Item.GetItem("Panel_Media").GetString("Media"); 651 652 if ( mediaType == "video") 653 { 654 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("Height"); 655 656 theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 657 } else if (mediaType == "image") 658 { 659 posterHeight = Model.Item.GetItem("Panel_Media").GetItem("Image").GetString("Height"); 660 661 theme = !string.IsNullOrWhiteSpace(Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme")) ? " theme " + Model.Item.GetItem("Panel_Media").GetItem("Image").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; 662 663 } 664 665 posterHeight = posterHeight == "auto" ? "h-100" : posterHeight; 666 posterHeight = posterHeight == "small" ? "min-vh-50 min-vh-md-50" : posterHeight; 667 posterHeight = posterHeight == "medium" ? "min-vh-50 min-vh-md-75" : posterHeight; 668 posterHeight = posterHeight == "large" ? "min-vh-100 min-vh-md-100" : posterHeight; 669 posterHeight = posterHeight == "1x1" ? "ratio ratio-1x1 mx-auto" : posterHeight; 670 posterHeight = posterHeight == "4x3" ? "ratio ratio-4x3 mx-auto" : posterHeight; 671 posterHeight = posterHeight == "16x9" ? "ratio ratio-16x9 mx-auto" : posterHeight; 672 posterHeight = posterHeight == "9x16" ? "ratio ratio-9x16 mx-auto" : posterHeight; 673 posterHeight = posterHeight == "3x4" ? "ratio ratio-3x4 mx-auto" : posterHeight; 674 675 676 } 677 678 <div class="position-relative @(hasText || hasHeading ? "row" : "") @posterHeight @theme @(movePageBehindClass)"> 679 680 @if (Model.Item.GetItem("Panel_Media").GetString("Media") == "video") 681 { 682 <div class="p-poster-video-container position-absolute top-0 bottom-0 end-0 start-0 px-0"> 683 <video preload="auto" loop autoplay muted playsinline class="h-100 w-100" style="object-fit: cover;"> 684 <source src="@Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")" 685 type="video/@Path.GetExtension(Model.Item.GetItem("Panel_Media").GetItem("Video").GetString("VideoPath")).ToLower().Replace(".", "")"> 686 </video> 687 </div> 688 689 } else if (Model.Item.GetItem("Panel_Media").GetString("Media") == "image") 690 { 691 <div class="position-absolute top-0 bottom-0 end-0 start-0 px-0"> 692 693 @if (link != null && !string.IsNullOrEmpty(link.Url)) 694 { 695 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 696 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 697 <a class="bottom-0 position-absolute top-0 w-100" href="@link.Url" @target @rel style="z-index: 2"> 698 </a> 699 } 700 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media").GetItem("Image").GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 701 </div> 702 703 } 704 705 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 706 @using System.Linq 707 708 @if(hasText || hasHeading){ 709 <div class="d-flex @(posterHeight == "none" ? string.Empty : "position-absolute top-0 bottom-0")"> 710 <div class="container-xl mx-auto px-0 py-5 row"> 711 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 712 @using System.Linq 713 714 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 715 { 716 717 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 718 { 719 string headerKey = ""; 720 string headerMarkup = ""; 721 string headingStart = ""; 722 string headingEnd = ""; 723 int headerCount = 0; 724 725 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 726 <div class="p-txt-container-wrap w-100"> 727 @foreach (var heading in headings) 728 { 729 string headningSize = heading.GetString("Size"); 730 string headingDisplaySize = heading.GetString("DisplaySize"); 731 bool headingAccentColor = heading.GetBoolean("AccentColor"); 732 bool headingAccentLine = heading.GetBoolean("AccentLine"); 733 734 if (headerKey != headningSize) 735 { 736 if (headerCount > 0) 737 { 738 headingEnd = $"</{headningSize}>"; 739 headerMarkup += headingEnd; 740 } 741 headerKey = headningSize; 742 headingStart = $"<{headningSize}>"; 743 headerMarkup += headingStart; 744 } 745 else if (headerCount > 0 && headerKey == headningSize) 746 { 747 headerMarkup += "<br>"; 748 } 749 750 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 751 headerMarkup += heading.GetString("Heading"); 752 headerMarkup += "</span>"; 753 754 headerCount++; 755 756 if (headerCount == headings.Count()) 757 { 758 headingEnd = $"</{headningSize}>"; 759 headerMarkup += headingEnd; 760 } 761 } 762 763 @if (headerMarkup != "") 764 { 765 @headerMarkup 766 } 767 768 769 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 770 { 771 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 772 } 773 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 774 { 775 @Model.Item.GetItem("Panel_Text").GetString("Text") 776 } 777 778 @RenderButtons() 779 </div> 780 </div> 781 } 782 } 783 784 </div> 785 </div> 786 } 787 788 </div> 789 790 </div> 791 } 792 else 793 { 794 795 if( hasImage || hasGraphic || hasVideo || hasLead || hasText || hasHeading || hasButton || promotionalProduct != null) 796 { 797 798 <div class="p-panel-container row @textHeight @imgPlacement @(hasTheme ? "theme " + Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"") @cssDecorations" id="@Model.ID"> 799 800 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Header", out headerFieldValueViewModel)) 801 { 802 if (headerFieldValueViewModel.Value != null) 803 { 804 string promotionalHeaderText = headerFieldValueViewModel.Value.ToString(); 805 promotionalHeaderText = promotionalHeaderText.Replace("{{D1}}", "<span class=\"display-1\">"); 806 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1}}", "</span>"); 807 promotionalHeaderText = promotionalHeaderText.Replace("{{D1:AccentColor}}", "<span class=\"display-1 text-accent\">"); 808 promotionalHeaderText = promotionalHeaderText.Replace("{{/D1:AccentColor}}", "</span>"); 809 promotionalHeaderText = promotionalHeaderText.Replace("{{D2}}", "<span class=\"display-2\">"); 810 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2}}", "</span>"); 811 promotionalHeaderText = promotionalHeaderText.Replace("{{D2:AccentColor}}", "<span class=\"display-2 text-accent\">"); 812 promotionalHeaderText = promotionalHeaderText.Replace("{{/D2:AccentColor}}", "</span>"); 813 promotionalHeaderText = promotionalHeaderText.Replace("{{D3}}", "<span class=\"display-3\">"); 814 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3}}", "</span>"); 815 promotionalHeaderText = promotionalHeaderText.Replace("{{D3:AccentColor}}", "<span class=\"display-3 text-accent\">"); 816 promotionalHeaderText = promotionalHeaderText.Replace("{{/D3:AccentColor}}", "</span>"); 817 promotionalHeaderText = promotionalHeaderText.Replace("®", "<sup>®</sup>"); 818 promotionalHeaderText = promotionalHeaderText.Replace("{{BR}}", "<br>"); 819 820 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 821 <div class="p-txt-container-wrap"> 822 <h2> 823 @promotionalHeaderText 824 </h2> 825 </div> 826 </div> 827 } 828 } 829 830 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Image", out imageFieldValueViewModel)) 831 { 832 if (imageFieldValueViewModel.Value != null) 833 { 834 string imagePath = imageFieldValueViewModel.Value.ToString(); 835 var promotionalImageParms = new Dictionary<string, object>(); 836 promotionalImageParms.Add("loading", "lazy"); 837 promotionalImageParms.Add("columns", Model.GridRowColumnCount); 838 839 promotionalImageParms.Add("fullwidth", true); 840 promotionalImageParms.Add("cssClass", "img-fluid w-100"); 841 promotionalImageParms.Add("style", "max-width: 60rem;transform: translateY(-6rem);margin-bottom: -6rem;"); 842 843 <div class="p-img-container d-flex justify-content-center"> 844 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, promotionalImageParms) 845 </div> 846 } 847 } 848 849 @if (Model.ID == 10804 && categoryFieldViewModel != null && categoryFieldViewModel.Fields.TryGetValue("Text", out textFieldValueViewModel)) 850 { 851 if (textFieldValueViewModel.Value != null) 852 { 853 <div class="p-txt-container d-flex flex-column justify-content-center align-items-center text-center mx-auto col col-12 col-sm theme "> 854 <div class="p-txt-container-wrap" style="max-width: 70rem;"> 855 @textFieldValueViewModel.Value 856 </div> 857 </div> 858 } 859 } 860 861 @if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Image") 862 { 863 if (Model != null && Model.Item != null && Model.Item.GetItem("Panel_Media").GetItem("Image").GetFile("Image") != null) 864 { 865 866 string imgPadding = string.Empty; 867 868 if (headings.Count() > 0 && imgFloat == "top") 869 { 870 imgPadding = "mb-4"; 871 } 872 873 else if (buttons.Any() && imgFloat == "top") 874 { 875 imgPadding = "mb-4"; 876 } 877 878 else if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text")) && imgFloat == "top") 879 { 880 imgPadding = "mb-4"; 881 } 882 883 else 884 { 885 imgPadding = "mb-4 mb-sm-0"; 886 } 887 888 string imgAlignment = string.Empty; 889 890 if(imgPosition == "image-left") 891 { 892 imgAlignment = "me-auto"; 893 } 894 else if(imgPosition == "image-right") 895 { 896 imgAlignment = "ms-auto"; 897 } 898 else 899 { 900 imgAlignment = "mx-auto"; 901 } 902 903 var offsets = Model.Item?.GetItem("Panel_Media")?.GetItem("Image")?.GetItem("Offsets"); 904 905 string desktopOffset = string.Empty; 906 string mobileOffset = string.Empty; 907 string tabletOffset = string.Empty; 908 string XLOffset = string.Empty; 909 910 if(offsets != null) 911 { 912 if(!string.IsNullOrEmpty(offsets.GetString("Offset"))) 913 { 914 desktopOffset = $"transform: translate({offsets.GetString("Offset")});"; 915 } 916 if(!string.IsNullOrEmpty(offsets.GetString("Mobile"))) 917 { 918 mobileOffset = $"transform: translate({offsets.GetString("Mobile")});"; 919 } 920 if(!string.IsNullOrEmpty(offsets.GetString("Tablet"))) 921 { 922 tabletOffset = $"transform: translate({offsets.GetString("Tablet")});"; 923 } 924 if(!string.IsNullOrEmpty(offsets.GetString("XL"))) 925 { 926 XLOffset = $"transform: translate({offsets.GetString("XL")});"; 927 } 928 } 929 930 if (!string.IsNullOrEmpty(mobileOffset) || !string.IsNullOrEmpty(tabletOffset) || !string.IsNullOrEmpty(desktopOffset) || !string.IsNullOrEmpty(XLOffset)) 931 { 932 <style> 933 @if (!string.IsNullOrEmpty(mobileOffset)) 934 { 935 <text> 936 @@media (min-width: 300px) { 937 [id='@(Model.ID)'] .p-img-container { 938 @mobileOffset 939 } 940 } 941 </text> 942 } 943 @if (!string.IsNullOrEmpty(tabletOffset)) 944 { 945 <text> 946 @@media (min-width: 768px) { 947 [id='@(Model.ID)'] .p-img-container { 948 @tabletOffset 949 } 950 } 951 </text> 952 } 953 954 @if (!string.IsNullOrEmpty(desktopOffset)) 955 { 956 <text> 957 @@media(min-width: 992px) 958 { 959 [id='@(Model.ID)'] .p-img-container { 960 @desktopOffset 961 } 962 } 963 </text> 964 } 965 966 @if (!string.IsNullOrEmpty(XLOffset)) 967 { 968 <text> 969 @@media(min-width: 1920px) 970 { 971 [id='@(Model.ID)'] .p-img-container { 972 @XLOffset 973 } 974 } 975 </text> 976 } 977 978 [id='@(Model.ID)'] .p-img-container { 979 z-index: 2; 980 position: relative; 981 } 982 </style> 983 } 984 985 <div class="@imgPadding p-img-container @colSizeClasslist @imgAlignment"> 986 987 @if (link != null && !string.IsNullOrEmpty(link.Url)) 988 { 989 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : ""; 990 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : ""; 991 <a href="@link.Url" @target @rel> 992 @RenderImage() 993 </a> 994 } 995 else 996 { 997 @RenderImage() 998 } 999 1000 </div> 1001 } 1002 1003 } 1004 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Graphic") 1005 { 1006 <div class="p-graphic-container mb-3 col flex-grow-0 pe-0"> 1007 <div class="@(layout) [email protected]("Panel_Media").GetItem("Graphic").GetString("GraphicSize")"> 1008 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new Dynamicweb.Frontend.FileViewModel()) 1009 </div> 1010 </div> 1011 1012 } 1013 else if (Model.Item?.GetItem("Panel_Media")?.GetField("Media").Value.ToString() == "Video") 1014 { 1015 if (Model.Item?.GetItem("Panel_Media")?.GetItem("Video")?.GetString("VideoPlacement") != "video-poster") 1016 { 1017 <div class="p-video-container"> 1018 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1019 @using Dynamicweb.Ecommerce.ProductCatalog 1020 1021 @{ 1022 1023 1024 string visual = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Visual", "inline"); 1025 1026 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1027 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1028 1029 Dynamicweb.Frontend.FileViewModel video = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPath"); 1030 string videoPath = video?.Path ?? ""; 1031 1032 string posterPath = "/Admin/Public/GetImage.ashx?image=" + @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster") + "&width=1000&format=webp"; 1033 1034 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/play.svg"; 1035 string theme = !string.IsNullOrWhiteSpace(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme")) ? " theme " + Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 1036 } 1037 1038 1039 @switch(visual) { 1040 case "inline" : 1041 <div class="h-100 position-relative grid grid-1"> 1042 1043 @switch (provider) 1044 { 1045 case "youtube" : 1046 case "vimeo" : 1047 1048 <div 1049 id="[email protected]" 1050 class="player plyr__video-embed @(theme) h-100 w-100" 1051 data-plyr-provider="@provider" 1052 data-plyr-embed-id="@videoId" 1053 style="--plyr-color-main: var(--swift-foreground-color); " 1054 > 1055 </div> 1056 1057 break; 1058 1059 case "self-hosted" : 1060 1061 <video 1062 id="[email protected]" 1063 class="player plyr__video-embed @(theme) h-100 w-100" 1064 src="@videoPath" 1065 style="--plyr-color-main: var(--swift-foreground-color);" 1066 preload="metadata" 1067 poster="@posterPath"> 1068 </video> 1069 1070 break; 1071 } 1072 <script type="module" defer src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1073 <script type="module" defer> 1074 1075 const player = new Plyr('#[email protected]', { 1076 type: 'video', 1077 youtube: { 1078 noCookie: true, 1079 showinfo: 0 1080 }, 1081 fullscreen: { 1082 enabled: true, 1083 iosNative: true, 1084 } 1085 }); 1086 </script> 1087 1088 </div> 1089 1090 break; 1091 1092 case "poster-modal" : 1093 <div class="h-100 position-relative@(theme) grid grid-1"> 1094 <div class="player position-relative" data-player="[email protected]"> 1095 1096 @RenderVideo() 1097 1098 <div class="position-absolute top-0 bottom-0 end-0 start-0 h-100 d-flex align-items-center justify-content-center gradient-overlay"> 1099 <button type="button" class="btn btn-primary rounded-circle lh-1 p-3" data-bs-toggle="modal" data-bs-target="#[email protected]"> 1100 <span class="icon-3"> 1101 @ReadFile(iconPath) 1102 </span> 1103 <span class="visually-hidden">@Translate("Play video")</span> 1104 </button> 1105 </div> 1106 </div> 1107 </div> 1108 1109 <div class="modal fade" id="[email protected]" tabindex="-1" aria-hidden="true"> 1110 <div class="modal-dialog modal-xl modal-dialog-centered"> 1111 <div class="modal-content"> 1112 <div class="modal-body p-0"> 1113 1114 @switch (provider) 1115 { 1116 case "youtube" : 1117 case "vimeo" : 1118 1119 <div 1120 id="[email protected]" 1121 class="player plyr__video-embed @(theme) h-100 w-100" 1122 data-plyr-provider="@provider" 1123 data-plyr-embed-id="@videoId" 1124 style="--plyr-color-main: var(--swift-foreground-color); " 1125 > 1126 </div> 1127 1128 break; 1129 1130 case "self-hosted" : 1131 1132 <video 1133 id="[email protected]" 1134 class="player plyr__video-embed @(theme) h-100 w-100" 1135 src="@videoPath" 1136 style="--plyr-color-main: var(--swift-foreground-color);" 1137 preload="metadata" 1138 > 1139 </video> 1140 1141 break; 1142 } 1143 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 1144 <script type="module"> 1145 1146 var player = new Plyr('#[email protected]', { 1147 youtube: { 1148 noCookie: true, 1149 showinfo: 0 1150 }, 1151 fullscreen: { 1152 enabled: true, 1153 iosNative: true, 1154 } 1155 }); 1156 1157 document.querySelector('#[email protected]').addEventListener('show.bs.modal', function (event) { 1158 player.togglePlay(); 1159 1160 player.on('ready', event => { 1161 player.play(); 1162 }); 1163 }); 1164 1165 document.querySelector('#[email protected]').addEventListener('hide.bs.modal', function (event) { 1166 player.pause(); 1167 }); 1168 </script> 1169 1170 </div> 1171 </div> 1172 </div> 1173 </div> 1174 1175 break; 1176 } 1177 1178 @helper RenderVideo() 1179 { 1180 string provider = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 1181 string videoId = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoSourceID"); 1182 string ratio = Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetRawValueString("AspectRatio", ""); 1183 ratio = ratio != "0" ? ratio : ""; 1184 string ratioCssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 1185 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : ""; 1186 string fillClass = ratio == "fill" ? " h-100" : ""; 1187 1188 var parms = new Dictionary<string, object>(); 1189 parms.Add("loading", "lazy"); 1190 if (ratio == "fill") { 1191 parms.Add("cssClass", "w-100 h-100"); 1192 } 1193 else 1194 { 1195 parms.Add("cssClass", "mw-100 mh-100"); 1196 } 1197 parms.Add("style",""); 1198 parms.Add("alt", @Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("ImageAltText")); 1199 parms.Add("columns", Model.GridRowColumnCount); 1200 1201 <figure class="m-0@(ratioCssClass)@(fillClass)" @ratioVariable> 1202 1203 @if (string.IsNullOrEmpty(Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetString("VideoPoster"))) 1204 { 1205 switch (provider) 1206 { 1207 case "youtube" : 1208 @RenderYouTubePoster(videoId) 1209 break; 1210 1211 case "vimeo" : 1212 @RenderVimeoPoster(videoId) 1213 break; 1214 } 1215 } 1216 else 1217 { 1218 @RenderPartial("Components/Image.cshtml", Model.Item?.GetItem("Panel_Media")?.GetItem("Video").GetFile("VideoPoster") ?? new Dynamicweb.Frontend.FileViewModel(), parms) 1219 } 1220 1221 </figure> 1222 } 1223 1224 @helper RenderYouTubePoster(string videoId) 1225 { 1226 <script type="module"> 1227 function setVideoThumbnail(source) { 1228 var figure = document.querySelector("[data-player='[email protected]'] figure"); 1229 var thumbnail = document.createElement("img"); 1230 thumbnail.style = "object-fit: cover;"; 1231 thumbnail.classList.add('mw-100','mh-100'); 1232 thumbnail.src = source; 1233 figure.appendChild(thumbnail); 1234 }; 1235 setVideoThumbnail('https://i.ytimg.com/vi/@(videoId)/hqdefault.jpg'); 1236 </script> 1237 } 1238 1239 @helper RenderVimeoPoster(string videoId) 1240 { 1241 <script type="module"> 1242 function setVideoThumbnail(source) { 1243 let figure = document.querySelector("[data-player='[email protected]'] figure"); 1244 let thumbnail = document.createElement("img"); 1245 thumbnail.style = "object-fit: cover;"; 1246 thumbnail.classList.add('mw-100','mh-100'); 1247 thumbnail.src = source; 1248 figure.appendChild(thumbnail); 1249 }; 1250 function getVimeoThumbnail() { 1251 fetch('https://vimeo.com/api/v2/video/@(videoId).json') 1252 .then(function(response) { 1253 return response.text(); 1254 }) 1255 .then(function(data) { 1256 let { thumbnail_large } = JSON.parse(data)[0]; 1257 let thumbnail = `${thumbnail_large}`; 1258 thumbnail = thumbnail.replace("_640", "_1920"); 1259 setVideoThumbnail(thumbnail); 1260 }) 1261 .catch(error => { 1262 console.log(error); 1263 }); 1264 } 1265 1266 getVimeoThumbnail(); 1267 </script> 1268 } 1269 1270 </div> 1271 } 1272 } 1273 1274 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 1275 @using System.Linq 1276 1277 @if (Model != null && Model.Item != null && @Model.Item.GetItem("Panel_Text") != null) 1278 { 1279 1280 if(headings.Count() > 0 || buttons.Any() || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead")) || !string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1281 { 1282 string headerKey = ""; 1283 string headerMarkup = ""; 1284 string headingStart = ""; 1285 string headingEnd = ""; 1286 int headerCount = 0; 1287 1288 <div class="p-txt-container @textHeight @(layout) @textColSizeClasslist theme @(hasTheme ? Model.Item?.GetItem( "Panel_Settings" )?.GetString( "Theme" ) :"")" style="z-index: 1" > 1289 <div class="p-txt-container-wrap w-100"> 1290 @foreach (var heading in headings) 1291 { 1292 string headningSize = heading.GetString("Size"); 1293 string headingDisplaySize = heading.GetString("DisplaySize"); 1294 bool headingAccentColor = heading.GetBoolean("AccentColor"); 1295 bool headingAccentLine = heading.GetBoolean("AccentLine"); 1296 1297 if (headerKey != headningSize) 1298 { 1299 if (headerCount > 0) 1300 { 1301 headingEnd = $"</{headningSize}>"; 1302 headerMarkup += headingEnd; 1303 } 1304 headerKey = headningSize; 1305 headingStart = $"<{headningSize}>"; 1306 headerMarkup += headingStart; 1307 } 1308 else if (headerCount > 0 && headerKey == headningSize) 1309 { 1310 headerMarkup += "<br>"; 1311 } 1312 1313 headerMarkup += $"<span class=\"{headingDisplaySize}{(headingAccentColor ? " text-accent" : "")}{(headingAccentLine ? " header-line" : "")}\">"; 1314 headerMarkup += heading.GetString("Heading"); 1315 headerMarkup += "</span>"; 1316 1317 headerCount++; 1318 1319 if (headerCount == headings.Count()) 1320 { 1321 headingEnd = $"</{headningSize}>"; 1322 headerMarkup += headingEnd; 1323 } 1324 } 1325 1326 @if (headerMarkup != "") 1327 { 1328 @headerMarkup 1329 } 1330 1331 1332 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Lead"))) 1333 { 1334 <p class="lead">@Model.Item.GetItem("Panel_Text").GetString("Lead")</p> 1335 } 1336 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Panel_Text").GetString("Text"))) 1337 { 1338 @Model.Item.GetItem("Panel_Text").GetString("Text") 1339 } 1340 1341 @RenderButtons() 1342 </div> 1343 </div> 1344 } 1345 } 1346 1347 1348 </div> 1349 } 1350 else 1351 { 1352 if(Pageview.IsVisualEditorMode) { 1353 <div class="alert alert-warning" role="alert"> 1354 This paragraph is empty 1355 </div> 1356 } 1357 } 1358 } 1359 @Model.GetModuleOutput() 1360
    Om Sika Footwear
    Messeoversigt
    Sponsorater
    Karriere
    Academy
    Værd at vide
    Blog
    Downloads
    Reklamationsformular
    Resistensoversigter
    EU Overensstemmelseserklæring
    Mediecenter
    Find forhandler
    Kontakt os
    Favoritlisten er opdateret