Limt stolpe/tverrbjelke - 9×9×148 cm

Artikkelnummer: 20463-13
EAN/GLN-nummer: 5703393748676
DB-nummer: 2479971

Når du velger sammenlimte stolper, får du en stolpe som er laget av furu - trykkimpregnert NTR klasse A, noe som betyr at den er beregnet for nedgraving. 
Stolpen er limt sammen av to trestykker for å minimere sprekkdannelser og vridning og sikre styrke og formstabilitet. 

Stolpen er rettskåret i begge ender.

🔴 Utsolgt
Expected in stock: 06.02.2025
NOK 679,00
OutOfStock
Takk, du vil bli varslet på e-post når varen er tilbake på lager.
Error executing template "Designs/Swift/Paragraph/Swift_ProductSpecification_EA.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_a5cd2fb62a7744dbb7e0d76b1a786dcd.<>c__DisplayClass30_0.<RenderArticle>b__0(TextWriter __razor_helper_writer) in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductSpecification_EA.cshtml:line 1213
   at CompiledRazorTemplates.Dynamic.RazorEngine_a5cd2fb62a7744dbb7e0d76b1a786dcd.<>c__DisplayClass27_0.<RenderField>b__0(TextWriter __razor_helper_writer) in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductSpecification_EA.cshtml:line 947
   at CompiledRazorTemplates.Dynamic.RazorEngine_a5cd2fb62a7744dbb7e0d76b1a786dcd.<>c__DisplayClass26_0.<RenderFieldsFromList>b__0(TextWriter __razor_helper_writer) in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductSpecification_EA.cshtml:line 787
   at CompiledRazorTemplates.Dynamic.RazorEngine_a5cd2fb62a7744dbb7e0d76b1a786dcd.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductSpecification_EA.cshtml:line 409
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb 3 @using Dynamicweb.Frontend 4 @using System.IO 5 @using Dynamicweb.Ecommerce.ProductCatalog 6 7 @functions { 8 public ProductViewModel product { get; set; } = new ProductViewModel(); 9 public string galleryLayout { get; set; } 10 public string[] supportedImageFormats { get; set; } 11 public string[] supportedVideoFormats { get; set; } 12 public string[] supportedDocumentFormats { get; set; } 13 public string[] allSupportedFormats { get; set; } 14 15 public class RatioSettings 16 { 17 public string Ratio { get; set; } 18 public string CssClass { get; set; } 19 public string CssVariable { get; set; } 20 public string Fill { get; set; } 21 } 22 23 public RatioSettings GetRatioSettings(string size = "desktop") 24 { 25 var ratioSettings = new RatioSettings(); 26 27 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 28 ratio = ratio != "0" ? ratio : ""; 29 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 30 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 31 cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; 32 cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; 33 34 ratioSettings.Ratio = ratio; 35 ratioSettings.CssClass = cssClass; 36 ratioSettings.CssVariable = cssVariable; 37 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 38 39 return ratioSettings; 40 } 41 } 42 @{ 43 bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false; 44 45 ProductViewModel product = new ProductViewModel(); 46 47 ProductViewModelSettings productSetting = new ProductViewModelSettings 48 { 49 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 50 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 51 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 52 ShopId = Pageview.Area.EcomShopId 53 }; 54 55 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 56 { 57 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 58 } 59 else if (Pageview.Item["DummyProduct"] != null) 60 { 61 62 string dummyProductId = ""; 63 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 64 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 65 if (productList.Products != null) 66 { 67 foreach (var p in productList.Products) { dummyProductId = p.Id; } 68 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 69 product = dummyProduct; 70 } 71 else 72 { 73 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 74 } 75 } 76 else if (Pageview.Item["DummyProduct"] == null) 77 { 78 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 79 } 80 } 81 82 @if (product?.Id != null) 83 { 84 IEnumerable<string> selectedDisplayGroupIds = Model.Item.GetRawValueString("DisplayGroups").Split(',').ToList(); 85 List<CategoryFieldViewModel> displayGroups = new List<CategoryFieldViewModel>(); 86 87 foreach (var selection in selectedDisplayGroupIds) 88 { 89 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 90 { 91 if (selection == group.Id) 92 { 93 displayGroups.Add(group); 94 } 95 } 96 } 97 98 bool showProductFields = Model.Item.GetBoolean("ProductFields"); 99 100 bool hideTitle = Model.Item.GetBoolean("HideTitle"); 101 102 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 103 104 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-4"); 105 106 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 107 contentPadding = contentPadding == "none" ? string.Empty : contentPadding; 108 contentPadding = contentPadding == "small" ? " p-2 p-md-3" : contentPadding; 109 contentPadding = contentPadding == "large" ? " p-4 p-md-5" : contentPadding; 110 111 string layout = Model.Item.GetRawValueString("Layout", "list"); 112 string size = Model.Item.GetRawValueString("Size", "full"); 113 string gaps = size == "full" ? " gap-4" : " gap-2"; 114 115 //IDictionary<string, string> customFscFields = new Dictionary<string, string>(); 116 //var anyFscDisplayGrps = false; 117 IDictionary<string, string> customDisplayFields = new Dictionary<string, string>(); 118 var anyCustomDisplayGrps = false; 119 var montagevejledningField = product.ProductFields.TryGetValue("InstallationPdf", out FieldValueViewModel installationPdf); 120 var overensstemmelseserklæringField = product.ProductFields.TryGetValue("CompliancePdf", out FieldValueViewModel compliancePdf); 121 var styrkeberegningerField = product.ProductFields.TryGetValue("StacticCalculationsPDF", out FieldValueViewModel stacticCalculationsPDF); 122 product.ProductFields.TryGetValue("DokumentsPDF", out FieldValueViewModel dokumentsPDF); 123 var fscField = product.ProductFields.TryGetValue("FSC", out FieldValueViewModel fscTag); 124 var fscLinkField = product.ProductFields.TryGetValue("FSC_link", out FieldValueViewModel fscLinkTag); 125 var pefcLinkField = product.ProductFields.TryGetValue("PEFC_link", out FieldValueViewModel pefcLinkTag); 126 var videoLinkField = product.ProductFields.TryGetValue("VideoLink", out FieldValueViewModel videoLinkTag); 127 var iconPath = "/Files/Templates/Designs/Swift/Assets/Icons/"; 128 var imageIcon = "file-image.svg"; 129 var pdfIcon = "file-pdf.svg"; 130 var fileIcon = "file-regular.svg"; 131 var fscIcon = "file-fsc.svg"; 132 var pefcIcon = "file-pefc.svg"; 133 string colCount = ""; 134 135 136 if (!String.IsNullOrEmpty(fscTag.Value.ToString())) 137 { 138 if (fscTag.Value.ToString().ToLower().Contains("fsc")) 139 { 140 customDisplayFields.Add(fscTag.Value.ToString(), fscLinkTag.Value.ToString()); 141 } 142 if (fscTag.Value.ToString().ToLower().Contains("pefc")) 143 { 144 customDisplayFields.Add(fscTag.Value.ToString(), pefcLinkTag.Value.ToString()); 145 } 146 anyCustomDisplayGrps = true; 147 } 148 149 if (!String.IsNullOrEmpty(installationPdf.Value.ToString())) 150 { 151 customDisplayFields.Add(installationPdf.Name.ToString(), installationPdf.Value.ToString()); 152 anyCustomDisplayGrps = true; 153 } 154 if (!String.IsNullOrEmpty(compliancePdf.Value.ToString())) 155 { 156 customDisplayFields.Add(compliancePdf.Name.ToString(), compliancePdf.Value.ToString()); 157 anyCustomDisplayGrps = true; 158 } 159 if (!String.IsNullOrEmpty(stacticCalculationsPDF.Value.ToString())) 160 { 161 customDisplayFields.Add(stacticCalculationsPDF.Name.ToString(), stacticCalculationsPDF.Value.ToString()); 162 anyCustomDisplayGrps = true; 163 } 164 if (!String.IsNullOrEmpty(dokumentsPDF.Value.ToString())) 165 { 166 customDisplayFields.Add(dokumentsPDF.Name.ToString(), dokumentsPDF.Value.ToString()); 167 anyCustomDisplayGrps = true; 168 } 169 if (!String.IsNullOrEmpty(videoLinkTag.Value.ToString())) 170 { 171 customDisplayFields.Add(videoLinkTag.Name.ToString(), videoLinkTag.Value.ToString()); 172 anyCustomDisplayGrps = true; 173 } 174 175 176 177 if (Pageview.IsVisualEditorMode && displayGroups.Count() == 0) 178 { 179 product.ProductFields.Clear(); 180 product.ProductFields.Add(Translate("Width"), new FieldValueViewModel { Name = Translate("Width"), Value = "99cm" }); 181 product.ProductFields.Add(Translate("Height"), new FieldValueViewModel { Name = Translate("Height"), Value = "195cm" }); 182 showProductFields = true; 183 } 184 185 if (layout == "commas") 186 { 187 gaps = size == "full" ? " gap-4" : " gap-2"; 188 189 } 190 191 <div class="grid h-100@(gaps)@(theme)@(contentPadding) item_@Model.Item.SystemName.ToLower()"> 192 @if ((product.ProductFields != null && Model.Item.GetBoolean("ProductFields")) || (product.ProductCategories != null && Model.Item.GetBoolean("CategoryFields")) || (displayGroups.Count != 0)) 193 { 194 if (!hideTitle) 195 { 196 <h2 class="g-col-12 @titleFontSize mb-0">@Model.Item.GetString("Title")</h2> 197 } 198 } 199 200 @if (displayGroups.Count != 0) 201 { 202 if (layout != "accordion") 203 { 204 foreach (var group in displayGroups) 205 { 206 bool hideHeader = Model.Item.GetBoolean("HideGroupHeaders"); 207 208 if (!hideHeader) 209 { 210 <h4 class="g-col-12 h4 mb-0">@group.Name</h4> 211 } 212 213 { @RenderFieldsFromList(group.Fields, layout, colCount) } 214 } 215 } 216 else 217 { 218 <div class="g-col-12"> 219 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 220 @foreach (var group in displayGroups) 221 { 222 <div class="accordion-item"> 223 <h2 class="accordion-header" id="SpecificationHeading_@group.Id"> 224 <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@group.Id" aria-expanded="false" aria-controls="SpecificationItem_@group.Id"> 225 @group.Name 226 </button> 227 </h2> 228 <div id="SpecificationItem_@group.Id" class="accordion-collapse collapse" aria-labelledby="SpecificationHeading_@group.Id" data-bs-parent="#Specifications_@Model.ID"> 229 <div class="accordion-body"> 230 @{ @RenderFieldsFromList(group.Fields, "list", colCount) } 231 </div> 232 </div> 233 </div> 234 } 235 </div> 236 </div> 237 } 238 } 239 240 @if (product.ProductFields != null && showProductFields) 241 { 242 if (product.ProductFields.Count > 0) 243 { 244 if (layout != "accordion") 245 { 246 {@RenderFieldsFromList(product.ProductFields, layout, colCount) } 247 } 248 else 249 { 250 <div class="g-col-12"> 251 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 252 <div class="accordion-item"> 253 <h2 class="accordion-header" id="SpecificationHeading_@Model.ID"> 254 <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@Model.ID" aria-expanded="false" aria-controls="SpecificationItem_@Model.ID"> 255 @Translate("Specifications") 256 </button> 257 </h2> 258 <div id="SpecificationItem_@Model.ID" class="accordion-collapse" aria-labelledby="SpecificationHeading_@Model.ID" data-bs-parent="#Specifications_@Model.ID"> 259 <div class="accordion-body"> 260 @{ @RenderFieldsFromList(product.ProductFields, "List", colCount) } 261 </div> 262 </div> 263 </div> 264 </div> 265 </div> 266 } 267 } 268 } 269 270 @if (product.ProductCategories != null && Model.Item.GetBoolean("CategoryFields")) 271 { 272 if (product.ProductCategories.Count > 0) 273 { 274 if (layout != "accordion") 275 { 276 foreach (var group in product.ProductCategories) 277 { 278 CategoryFieldViewModel category = group.Value; 279 bool hideHeader = Model.Item.GetBoolean("HideGroupHeaders"); 280 281 if (!hideHeader) 282 { 283 <h4 class="g-col-12 h4 mb-0">@group.Value.Name</h4> 284 } 285 286 { @RenderFieldsFromList(category.Fields, layout, "") } 287 } 288 } 289 else 290 { 291 <div class="g-col-12"> 292 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 293 @foreach (var group in product.ProductCategories) 294 { 295 CategoryFieldViewModel category = group.Value; 296 297 <div class="accordion-item"> 298 <h2 class="accordion-header" id="SpecificationHeading_@group.Value.Id"> 299 <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@group.Value.Id" aria-expanded="false" aria-controls="SpecificationItem_@group.Value.Id"> 300 @group.Key 301 </button> 302 </h2> 303 <div id="SpecificationItem_@group.Value.Id" class="accordion-collapse" aria-labelledby="SpecificationHeading_@group.Value.Id" data-bs-parent="#Specifications_@Model.ID"> 304 <div class="accordion-body"> 305 @{ @RenderFieldsFromList(category.Fields, "list", colCount) } 306 </div> 307 </div> 308 </div> 309 } 310 </div> 311 </div> 312 } 313 } 314 } 315 316 @{ string displayGroupsList = ""; 317 string divider = ""; 318 foreach (var group in displayGroups) 319 { 320 displayGroupsList = "tab_" + group.Id + "," + "SpecificationItem_" + group.Id + divider + displayGroupsList; 321 divider = ","; 322 } } 323 324 @if (displayGroups.Count != 0) 325 { 326 if (layout != "navtabs") 327 { 328 foreach (var group in displayGroups) 329 { 330 bool hideHeader = Model.Item.GetBoolean("HideGroupHeaders"); 331 332 if (!hideHeader) 333 { 334 <h4 class="g-col-12 h4 mb-0">@group.Name</h4> 335 } 336 337 { @RenderFieldsFromList(group.Fields, layout, colCount) } 338 } 339 } 340 else 341 { 342 bool first = true; 343 var displayNumber = 0; 344 var customDisplayGrpouPos = 3; 345 346 <div class="g-col-12 diplay-fields efa-mod d-none d-sm-block"> 347 <ul class="nav nav-pills px-3 px-md-5 px-lg-7" id="pills-tab" role="tablist"> 348 @{ foreach (var tab in displayGroups) 349 { 350 displayNumber++; 351 if (first) 352 { 353 <li class="nav-item pe-5 py-2 py-md-2" role="presentation"> 354 <button class="nav-link active text-uppercase fc-dark bg-transparent p-0 efa-mod" id="@tab.Id-tab" onclick="toogleReset('tab_@tab.Id')" data-bs-toggle="tab" data-bs-target="#tab_@tab.Id" type="button" role="tab" aria-controls="@tab.Id" aria-selected="true">@tab.Name</button> 355 </li> 356 first = false; 357 } 358 else 359 { 360 <li class="nav-item @displayGroups.Count || @displayNumber pe-5 py-2 py-md-2" role="presentation"> 361 <button class="nav-link text-uppercase fc-dark bg-transparent p-0 efa-mod" id="@tab.Id-tab" onclick="toogleReset('tab_@tab.Id')" data-bs-toggle="tab" data-bs-target="#tab_@tab.Id" type="button" role="tab" aria-controls="@tab.Id" aria-selected="false">@tab.Name</button> 362 </li> 363 } 364 if (displayNumber == customDisplayGrpouPos || (displayNumber == displayGroups.Count && displayNumber <= customDisplayGrpouPos)) 365 { 366 if (anyCustomDisplayGrps) 367 { 368 <li class="nav-item pe-5 py-2 py-md-2" role="presentation"> 369 <button class="nav-link text-uppercase fc-dark bg-transparent p-0 efa-mod" id="@Translate("Documents_downloads")-tab" onclick="toogleReset('tab_@Translate("Documents_downloads")')" data-bs-toggle="tab" data-bs-target="#tab_@Translate("Documents_downloads")" type="button" role="tab" aria-controls="@Translate("Documents_downloads")" aria-selected="false">@Translate("Documents/downloads")</button> 370 </li> 371 } 372 } 373 } 374 displayNumber = 0; } 375 </ul> 376 @{ first = true; } 377 <div class="tab-content bg-super-light efa-mod px-3 px-md-5 px-lg-7 py-4 py-md-5" id="pills-tabContent"> 378 @{ 379 foreach (var item in displayGroups) 380 { 381 displayNumber++; 382 383 if (item.Fields.Count >= 4) 384 { 385 colCount = "g-col-md-6 g-col-lg-4 g-col-xl-3"; 386 } 387 else if (item.Fields.Count == 3) 388 { 389 colCount = "g-col-md-6 g-col-lg-4"; 390 } 391 else if (item.Fields.Count == 2) 392 { 393 colCount = "g-col-md-6 g-col-lg-6"; 394 } 395 else 396 { 397 colCount = ""; 398 } 399 400 @*foreach(var field in item.Fields) { 401 <p><strong>@item.Id</strong></p> 402 <p>@field.Key</p> 403 }*@ 404 405 if (first) 406 { 407 <div class="tab-pane fade show active collapsed efa-mod" id="tab_@item.Id" role="tabpanel" aria-labelledby=""> 408 <div> 409 @{ @RenderFieldsFromList(item.Fields, "display-fields", colCount) } 410 </div> 411 <div class="readmore-overlay efa-mod"> 412 <div class="readmore-overlay_button fs-7 fc-grey efa-mod" onclick="readMore('tab_@item.Id')"> 413 @Translate("Read more") 414 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16"> 415 <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> 416 </svg> 417 </div> 418 </div> 419 </div> 420 first = false; 421 } 422 else 423 { 424 425 <div class="tab-pane fade collapsed efa-mod" id="tab_@item.Id" role="tabpanel" aria-labelledby=""> 426 <div> 427 @{ @RenderFieldsFromList(item.Fields, "display-fields", colCount) } 428 </div> 429 <div class="readmore-overlay efa-mod"> 430 <div class="readmore-overlay_button fs-7 fc-grey efa-mod" onclick="readMore('tab_@item.Id')"> 431 @Translate("Read more") 432 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16"> 433 <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> 434 </svg> 435 </div> 436 </div> 437 </div> 438 } 439 440 if (displayNumber == customDisplayGrpouPos || (displayNumber == displayGroups.Count && displayNumber <= customDisplayGrpouPos)) 441 { 442 if (anyCustomDisplayGrps) 443 { 444 string icon = ""; 445 446 <div class="tab-pane fade collapsed efa-mod" id="tab_@Translate("Documents_downloads")" role="tabpanel" aria-labelledby=""> 447 <div> 448 <div class="g-col-12 grid gap-0"> 449 450 @{ 451 if (customDisplayFields.Count >= 4) 452 { 453 colCount = "g-col-md-6 g-col-lg-4 g-col-xl-3"; 454 } 455 else if (customDisplayFields.Count == 3) 456 { 457 colCount = "g-col-md-6 g-col-lg-4"; 458 } 459 else if (customDisplayFields.Count == 2) 460 { 461 colCount = "g-col-md-6 g-col-lg-6"; 462 } 463 else 464 { 465 colCount = ""; 466 } 467 } 468 469 @foreach (var field in customDisplayFields) 470 { 471 if(field.Key.Contains("Video")) { 472 <div class="g-col-12 @colCount mb-3 pe-0 pe-md-4 align-items-center"> 473 @RenderVideoPreview(field.Value, field.Key) 474 </div> 475 } 476 else 477 { 478 <div class="g-col-12 @colCount mb-3 pe-0 pe-md-4 d-flex align-items-center"> 479 @if (field.Key.Contains("FSC")) 480 { 481 icon = iconPath + fscIcon; 482 } 483 else if (field.Key.Contains("PEFC")) 484 { 485 icon = iconPath + pefcIcon; 486 } 487 else if (field.Value.Contains(".pdf")) 488 { 489 icon = iconPath + pdfIcon; 490 } 491 else if (field.Value.Contains(".png") || field.Value.Contains(".jpg") || field.Value.Contains(".jpeg")) 492 { 493 icon = iconPath + imageIcon; 494 } 495 else 496 { 497 icon = iconPath + fileIcon; 498 } 499 <span class="me-2 icon-3 efa-mod"> 500 @ReadFile(icon) 501 </span> 502 <a name="@icon" class="fw-bold m-0" href="@field.Value" title="@field.Key" target="_blank" rel="noopener"> 503 <p class="m-0">@field.Key</p> 504 </a> 505 </div> 506 507 } 508 } 509 </div> 510 </div> 511 <div class="readmore-overlay efa-mod"> 512 <div class="readmore-overlay_button fs-7 fc-grey efa-mod" onclick="readMore('tab_@Translate("Documents_downloads")')"> 513 @Translate("Read more") 514 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16"> 515 <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> 516 </svg> 517 </div> 518 </div> 519 </div> 520 } 521 } 522 523 } 524 525 displayNumber = 0; } 526 </div> 527 </div> 528 529 <div class="g-col-12 d-block d-sm-none"> 530 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 531 @{ 532 foreach (var group in displayGroups) 533 { 534 displayNumber++; 535 536 if (group.Fields.Count >= 4) 537 { 538 colCount = "g-col-md-6 g-col-lg-4 g-col-xl-3"; 539 } 540 else if (group.Fields.Count == 3) 541 { 542 colCount = "g-col-md-6 g-col-lg-4"; 543 } 544 else if (group.Fields.Count == 2) 545 { 546 colCount = "g-col-md-6 g-col-lg-6"; 547 } 548 else 549 { 550 colCount = ""; 551 } 552 553 <div class="accordion-item"> 554 <h2 class="accordion-header" id="SpecificationHeading_@group.Id"> 555 <button class="accordion-button collapsed text-uppercase fc-dark efa-mod" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@group.Id" aria-expanded="false" aria-controls="SpecificationItem_@group.Id"> 556 @group.Name 557 </button> 558 </h2> 559 <div id="SpecificationItem_@group.Id" class="accordion-collapse collapse collapsed efa-mod" aria-labelledby="SpecificationHeading_@group.Id" data-bs-parent="#Specifications_@Model.ID"> 560 <div class="accordion-body bg-super-light efa-mod"> 561 @{ @RenderFieldsFromList(group.Fields, "display-fields", colCount) } 562 </div> 563 <div class="readmore-overlay pb-3 efa-mod"> 564 <div class="readmore-overlay_button fs-7 fc-grey efa-mod" onclick="readMore('SpecificationItem_@group.Id')"> 565 @Translate("Read more") 566 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16"> 567 <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> 568 </svg> 569 </div> 570 </div> 571 </div> 572 </div> 573 if (displayNumber == customDisplayGrpouPos || (displayNumber == displayGroups.Count && displayNumber <= customDisplayGrpouPos)) 574 { 575 if (anyCustomDisplayGrps) 576 { 577 string icon = ""; 578 579 <div class="accordion-item"> 580 <h2 class="accordion-header" id="SpecificationHeading_@Translate("Documents_downloads")"> 581 <button class="accordion-button collapsed text-uppercase fc-dark efa-mod" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@Translate("Documents_downloads")" aria-expanded="false" aria-controls="SpecificationItem_@Translate("Documents_downloads")"> 582 @Translate("Documents/downloads") 583 </button> 584 </h2> 585 <div id="SpecificationItem_@Translate("Documents_downloads")" class="accordion-collapse collapse collapsed efa-mod" aria-labelledby="SpecificationHeading_@Translate("Documents_downloads")" data-bs-parent="#Specifications_@Model.ID"> 586 <div class="accordion-body bg-super-light efa-mod"> 587 <div class="g-col-12 grid gap-0"> 588 589 @{ 590 if (customDisplayFields.Count >= 4) 591 { 592 colCount = "g-col-md-6 g-col-lg-4 g-col-xl-3"; 593 } 594 else if (customDisplayFields.Count == 3) 595 { 596 colCount = "g-col-md-6 g-col-lg-4"; 597 } 598 else if (customDisplayFields.Count == 2) 599 { 600 colCount = "g-col-md-6 g-col-lg-6"; 601 } 602 else 603 { 604 colCount = ""; 605 } 606 } 607 608 @foreach (var field in customDisplayFields) 609 { 610 if(field.Key.Contains("Video")) { 611 <div class="g-col-12 @colCount mb-3 pe-0 pe-md-4 d-flex align-items-start"> 612 @RenderVideoPreview(field.Value, field.Key) 613 </div> 614 615 } else { 616 <div class="g-col-12 @colCount mb-3 pe-0 pe-md-4 d-flex align-items-start"> 617 618 @if (field.Key.Contains("FSC")) 619 { 620 icon = iconPath + fscIcon; 621 } 622 else if (field.Key.Contains("PEFC")) 623 { 624 icon = iconPath + pefcIcon; 625 } 626 else if (field.Value.Contains(".pdf")) 627 { 628 icon = iconPath + pdfIcon; 629 } 630 else if (field.Value.Contains(".png") || field.Value.Contains(".jpg") || field.Value.Contains(".jpeg")) 631 { 632 icon = iconPath + imageIcon; 633 } 634 else 635 { 636 icon = iconPath + fileIcon; 637 } 638 <span class="me-2 icon-3 efa-mod"> 639 @ReadFile(icon) 640 </span> 641 <a class="fw-bold m-0" href="@field.Value" title="@field.Key" target="_blank" rel="noopener"> 642 <p class="m-0">@field.Key</p> 643 </a> 644 645 </div> 646 } 647 } 648 </div> 649 </div> 650 <div class="readmore-overlay pb-3 efa-mod"> 651 <div class="readmore-overlay_button fs-7 fc-grey efa-mod" onclick="readMore('SpecificationItem_@Translate("Documents_downloads")')"> 652 @Translate("Read more") 653 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16"> 654 <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" /> 655 </svg> 656 </div> 657 </div> 658 </div> 659 </div> 660 } 661 } 662 } 663 664 displayNumber = 0; 665 } 666 </div> 667 </div> 668 <script type="text/javascript"> 669 670 var displayGroups = '@displayGroupsList'; 671 var displayGroupList = displayGroups.split(','); 672 673 for (var i = 0; i < displayGroupList.length; i++) { 674 675 let elem = document.getElementById(displayGroupList[i]); 676 677 const observer = new ResizeObserver(change => { 678 const tapElem = change[0]; 679 if (tapElem.contentRect.height > 600) { 680 elem.classList.add('readmore-container'); 681 } 682 }); 683 observer.observe(elem); 684 } 685 686 function readMore(id) { 687 let element = document.getElementById(id); 688 element.classList.toggle('collapsed'); 689 }; 690 </script> 691 } 692 } 693 694 @if (product.ProductFields != null && showProductFields) 695 { 696 if (product.ProductFields.Count > 0) 697 { 698 if (layout != "navtabs") 699 { 700 {@RenderFieldsFromList(product.ProductFields, layout, "") } 701 } 702 else 703 { 704 <div class="g-col-12"> 705 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 706 <div class="accordion-item"> 707 <h2 class="accordion-header" id="SpecificationHeading_@Model.ID"> 708 <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@Model.ID" aria-expanded="false" aria-controls="SpecificationItem_@Model.ID"> 709 @Translate("Specifications") 710 </button> 711 </h2> 712 <div id="SpecificationItem_@Model.ID" class="accordion-collapse" aria-labelledby="SpecificationHeading_@Model.ID" data-bs-parent="#Specifications_@Model.ID"> 713 <div class="accordion-body"> 714 @{ @RenderFieldsFromList(product.ProductFields, "List", colCount) } 715 </div> 716 </div> 717 </div> 718 </div> 719 </div> 720 } 721 } 722 } 723 724 @if (product.ProductCategories != null && Model.Item.GetBoolean("CategoryFields")) 725 { 726 if (product.ProductCategories.Count > 0) 727 { 728 if (layout != "navtabs") 729 { 730 foreach (var group in product.ProductCategories) 731 { 732 CategoryFieldViewModel category = group.Value; 733 bool hideHeader = Model.Item.GetBoolean("HideGroupHeaders"); 734 735 if (!hideHeader) 736 { 737 <h4 class="g-col-12 h4 mb-0">@group.Value.Name</h4> 738 } 739 740 { @RenderFieldsFromList(category.Fields, layout, colCount) } 741 } 742 } 743 else 744 { 745 <div class="g-col-12"> 746 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 747 @foreach (var group in product.ProductCategories) 748 { 749 CategoryFieldViewModel category = group.Value; 750 751 <div class="accordion-item"> 752 <h2 class="accordion-header" id="SpecificationHeading_@group.Value.Id"> 753 <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#SpecificationItem_@group.Value.Id" aria-expanded="false" aria-controls="SpecificationItem_@group.Value.Id"> 754 @group.Key 755 </button> 756 </h2> 757 <div id="SpecificationItem_@group.Value.Id" class="accordion-collapse" aria-labelledby="SpecificationHeading_@group.Value.Id" data-bs-parent="#Specifications_@Model.ID"> 758 <div class="accordion-body"> 759 @{ @RenderFieldsFromList(category.Fields, "list", colCount) } 760 </div> 761 </div> 762 </div> 763 } 764 </div> 765 </div> 766 } 767 } 768 } 769 </div> 770 } 771 else if (Pageview.IsVisualEditorMode) 772 { 773 <div class="alert alert-warning m-0">@Translate("No products available")</div> 774 } 775 776 @helper RenderFieldsFromList(Dictionary<string, FieldValueViewModel> fields, string layout, string colCount) 777 { 778 string size = Model.Item.GetRawValueString("Size", "full"); 779 string gaps = size != "full" ? " gap-1" : string.Empty; 780 bool hideFieldLabels = Model.Item.GetBoolean("HideFieldLabels"); 781 782 if (layout == "display-fields") 783 { 784 <div class="g-col-12 grid gap-0"> 785 @foreach (var field in fields) 786 { 787 {@RenderField(field.Value, layout, colCount)} 788 } 789 </div> 790 } 791 if (layout == "columns") 792 { 793 <div class="g-col-12 grid@(gaps)"> 794 @foreach (var field in fields) 795 { 796 {@RenderField(field.Value, layout, "")} 797 } 798 </div> 799 } 800 if (layout == "list") 801 { 802 <dl class="g-col-12 grid@(gaps)"> 803 @foreach (var field in fields) 804 { 805 {@RenderField(field.Value, layout, "")} 806 } 807 </dl> 808 } 809 if (layout == "table") 810 { 811 string tableSize = size == "full" ? "" : " table-sm"; 812 <div class="g-col-12"> 813 <table class="table table-striped@(tableSize)"> 814 @foreach (var field in fields) 815 { 816 {@RenderField(field.Value, layout, "")} 817 } 818 </table> 819 </div> 820 } 821 if (layout == "bullets") 822 { 823 string listSize = size == "full" ? "" : "m-0 p-0 lh-1 fs-7 opacity-75"; 824 string listStyle = size == "full" ? "" : "style=\"list-style-position: inside\""; 825 <div class="g-col-12"> 826 <ul class="@listSize" @listStyle> 827 @foreach (var field in fields) 828 { 829 {@RenderField(field.Value, layout, "")} 830 } 831 </ul> 832 </div> 833 } 834 if (layout == "commas") 835 { 836 List<string> featuresList = new List<string>(); 837 838 foreach (var field in fields) 839 { 840 if (field.Value.Value is object && !string.IsNullOrEmpty(field.Value.Value.ToString())) 841 { 842 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 843 { 844 List<string> options = new List<string>(); 845 foreach (FieldOptionValueViewModel option in field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>) 846 { 847 if (!string.IsNullOrWhiteSpace(option.Value)) 848 { 849 if (option.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 850 { 851 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + option.Value + "\"></span>"; 852 options.Add(colorSpan); 853 } 854 else if (!string.IsNullOrEmpty(option.Value)) 855 { 856 options.Add(option.Name); 857 } 858 } 859 } 860 string optionsString = (string.Join(", ", options.Select(x => x.ToString()).ToArray())); 861 if ((Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 862 { 863 optionsString = (string.Join(" ", options.Select(x => x.ToString()).ToArray())); 864 } 865 866 if (!hideFieldLabels) 867 { 868 featuresList.Add(field.Value.Name + ": " + optionsString); 869 } 870 else 871 { 872 featuresList.Add(optionsString); 873 } 874 } 875 else 876 { 877 if (!string.IsNullOrWhiteSpace(field.Value.Value.ToString())) 878 { 879 if (field.Value.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 880 { 881 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + field.Value.Value + "\"></span>"; 882 883 if (!hideFieldLabels) 884 { 885 featuresList.Add(field.Value.Name + ": " + colorSpan); 886 } 887 else 888 { 889 featuresList.Add(colorSpan); 890 } 891 } 892 else 893 { 894 if (!hideFieldLabels) 895 { 896 featuresList.Add(field.Value.Name + ": " + field.Value.Value.ToString()); 897 } 898 else 899 { 900 featuresList.Add(field.Value.Value.ToString()); 901 } 902 } 903 } 904 } 905 } 906 } 907 908 string featuresString = (string.Join(", ", featuresList.Select(x => x.ToString()).ToArray())); 909 910 <div class="g-col-12 opacity-75 fs-7">@featuresString</div> 911 } 912 } 913 914 @helper RenderField(FieldValueViewModel field, string layout, string colCount) 915 { 916 string size = Model.Item.GetRawValueString("Size", "full"); 917 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 918 bool hideFieldLabels = Model.Item.GetBoolean("HideFieldLabels"); 919 bool noValues = false; 920 string orderLast = ""; 921 922 if (!string.IsNullOrEmpty(fieldValue)) 923 { 924 if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 925 { 926 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 927 noValues = values.Count > 0 ? false : true; 928 } 929 } 930 931 if (!string.IsNullOrEmpty(fieldValue) && noValues == false) 932 { 933 if (layout == "display-fields") 934 { 935 if (fieldValue == "1") { 936 orderLast = "order-last"; 937 } 938 939 <div class="g-col-12 @colCount @orderLast mb-3 pe-0 pe-md-4"> 940 941 @if (field.SystemName.Contains("InspirationArticleTabId")) 942 { 943 var dummy = false; 944 if (fieldValue == "1") { 945 dummy = true; 946 } else { 947 @RenderArticle(fieldValue, dummy) 948 } 949 } 950 else 951 { 952 if (!hideFieldLabels) 953 { 954 if (field?.SystemName != "ProductLongDescription") 955 { 956 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 957 { 958 <p class="fw-bold m-0">@Translate(field?.Name):</p> 959 } 960 else 961 { 962 <p class="fw-bold m-0">@field.Name:</p> 963 } 964 } 965 } 966 <p class="text-break m-0"> 967 @{ @RenderFieldValue(field) } 968 </p> 969 } 970 </div> 971 } 972 if (layout == "columns") 973 { 974 975 <div class="grid g-col-6 g-col-lg-4 gap-1"> 976 @if (!hideFieldLabels) 977 { 978 if (field?.SystemName != "ProductLongDescription") 979 { 980 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 981 { 982 <dt class="g-col-12 g-col-lg-4">@Translate(field?.Name)</dt> 983 } 984 else 985 { 986 <dt class="g-col-12 g-col-lg-4">@field?.Name</dt> 987 } 988 } 989 } 990 <dd class="g-col-12 g-col-lg-8 mb-0 text-break"> 991 @{ @RenderFieldValue(field) } 992 </dd> 993 </div> 994 } 995 if (layout == "list") 996 { 997 if (!hideFieldLabels) 998 { 999 if (field?.SystemName != "ProductLongDescription") 1000 { 1001 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1002 { 1003 <dt class="g-col-4">@Translate(field?.Name)</dt> 1004 } 1005 else 1006 { 1007 <dt class="g-col-4">@field?.Name</dt> 1008 } 1009 } 1010 } 1011 <dd class="g-col-8 mb-0 text-break"> 1012 @{ @RenderFieldValue(field) } 1013 </dd> 1014 } 1015 if (layout == "table") 1016 { 1017 <tr> 1018 @if (!hideFieldLabels) 1019 { 1020 if (field?.SystemName != "ProductLongDescription") 1021 { 1022 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1023 { 1024 <th class="w-25 w-lg-50" scope="row">@Translate(field?.Name)</th> 1025 } 1026 else 1027 { 1028 <th class="w-25 w-lg-50" scope="row">@field?.Name</th> 1029 } 1030 } 1031 } 1032 <td class="text-break"> 1033 @{ @RenderFieldValue(field) } 1034 </td> 1035 </tr> 1036 } 1037 if (layout == "bullets") 1038 { 1039 <li> 1040 @if (!hideFieldLabels) 1041 { 1042 if (field?.SystemName != "ProductLongDescription") 1043 { 1044 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1045 { 1046 <strong>@Translate(field?.Name)</strong> 1047 } 1048 else 1049 { 1050 <strong>@field?.Name</strong> 1051 } 1052 } 1053 } 1054 <span> 1055 @{ @RenderFieldValue(field) } 1056 </span> 1057 </li> 1058 } 1059 } 1060 } 1061 1062 @helper RenderFieldValue(FieldValueViewModel field) 1063 { 1064 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 1065 1066 bool isLink = field?.Type == "Link"; 1067 bool isColor = false; 1068 bool isBrandName = field?.SystemName == "Brand_name"; 1069 bool isYoutubeVideo = field?.SystemName == "VideoLink"; 1070 1071 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 1072 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 1073 1074 1075 if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 1076 { 1077 int valueCount = 0; 1078 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 1079 int totalValues = values.Count; 1080 1081 foreach (FieldOptionValueViewModel option in values) 1082 { 1083 if (!string.IsNullOrEmpty(option.Value)) 1084 { 1085 if (option.Value.Substring(0, 1) == "#") 1086 { 1087 isColor = true; 1088 } 1089 } 1090 1091 if (!isColor) 1092 { 1093 @option.Name 1094 } 1095 else 1096 { 1097 <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Name"></span> 1098 } 1099 1100 if (valueCount != totalValues && valueCount < (totalValues - 1)) 1101 { 1102 if (isColor) 1103 { 1104 <text> </text> 1105 } 1106 else 1107 { 1108 <text>, </text> 1109 } 1110 } 1111 valueCount++; 1112 } 1113 } 1114 else 1115 { 1116 if (fieldValue.Substring(0, 1) == "#") 1117 { 1118 isColor = true; 1119 } 1120 1121 if (!isColor) 1122 { 1123 if (isLink) 1124 { 1125 string linktTitle = !fieldValue.Contains("aspx") ? fieldValue : Translate("Go to link"); 1126 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "target=\"_blank\"" : string.Empty; 1127 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "rel=\"noopener\"" : string.Empty; 1128 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 1129 if (isYoutubeVideo) 1130 { 1131 var videoId = linktTitle; 1132 1133 videoId = videoId.StartsWith("http://") ? videoId.Replace("http://", "") : ""; 1134 1135 linktTitle = "https://img.youtube.com/vi/" + linktTitle.Substring(linktTitle.LastIndexOf('=') + 1) + "/maxresdefault.jpg"; 1136 1137 RatioSettings ratioSettings = GetRatioSettings("desktop"); 1138 1139 <div id="SmallScreenImagesThumbnails_@Model.ID" class="grid grid-2 gap-2 overflow-x-auto my-3"> 1140 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to=""> 1141 <a class="d-flex align-items-center justify-content-center" href="@field.Value" @target @rel> 1142 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 1143 <img src="@linktTitle" alt="" class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain" data-video-id="@field.Value"> 1144 </a> 1145 </div> 1146 </div> 1147 } 1148 else 1149 { 1150 <a href="@field.Value" title="@field.Name" @target @rel>@linktTitle</a> 1151 } 1152 1153 } 1154 else if (isBrandName) 1155 { 1156 <span itemprop="brand" itemtype="https://schema.org/Brand" itemscope> 1157 <span itemprop="name">@fieldValue</span> 1158 </span> 1159 } 1160 1161 else 1162 { 1163 @fieldValue 1164 } 1165 } 1166 else 1167 { 1168 <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> 1169 } 1170 } 1171 } 1172 1173 @helper RenderVideoPreview(string fieldValue, string fieldName) { 1174 1175 string linktTitle = !fieldValue.Contains("aspx") ? fieldValue : Translate("Go to link"); 1176 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "target=\"_blank\"" : string.Empty; 1177 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "rel=\"noopener\"" : string.Empty; 1178 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 1179 1180 var videoId = linktTitle; 1181 1182 videoId = videoId.StartsWith("http://") ? videoId.Replace("http://", "") : ""; 1183 1184 linktTitle = "https://img.youtube.com/vi/" + linktTitle.Substring(linktTitle.LastIndexOf('=') + 1) + "/maxresdefault.jpg"; 1185 1186 RatioSettings ratioSettings = GetRatioSettings("desktop"); 1187 1188 <p class="fw-bold m-0">@(fieldName):</p> 1189 <div id="SmallScreenImagesThumbnails_@Model.ID" class="grid grid-2 gap-2 overflow-x-auto my-3"> 1190 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to=""> 1191 <a class="d-flex align-items-center justify-content-center" href="@fieldValue" @target @rel> 1192 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 1193 <img src="@linktTitle" alt="" class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain" data-video-id="@fieldValue"> 1194 </a> 1195 </div> 1196 </div> 1197 1198 } 1199 1200 @helper RenderArticle(string fieldValue, bool dummy) { 1201 1202 if (!string.IsNullOrEmpty(fieldValue)) { 1203 1204 if (dummy) { 1205 //dummy filler 1206 } 1207 else 1208 { 1209 int id = fieldValue != "0" ? Int32.Parse(fieldValue) : 0; 1210 if (id > 0) { 1211 1212 var specialPage = Dynamicweb.Content.Services.Pages.GetPage(id); 1213 string title = specialPage.Item.GetItem("Title").ToString(); 1214 string coverImagePath = !string.IsNullOrEmpty(specialPage.Item.GetItem("CoverImage").ToString()) ? specialPage.Item.GetItem("CoverImage").ToString() : string.Empty; 1215 1216 <article class="d-flex flex-column mb-3 gap-0 theme plus_green-white_block h-100 shadow-hover overflow-hidden lift" itemscope="" itemtype="https://schema.org/CreativeWork" style="z-index:100;"> 1217 1218 <a class="w-100 " title="@specialPage.Item.GetItem("Title")" href="@specialPage.GetPageHrefValue()" tabindex="-1"> 1219 1220 <figure class="h-lg-100 overflow-hidden m-0 mx-auto ratio ratio-16x9" aria-label="@coverImagePath"> 1221 @RenderImage(coverImagePath, title, "50% 50%", "object-fit: cover", "2", "2") 1222 </figure> 1223 </a> 1224 <div class="d-flex flex-column flex-grow-1 gap-3 w-100 p-3 p-md-4"> 1225 <a class="text-decoration-none text-decoration-underline-hover" href="@specialPage.GetPageHrefValue()"> 1226 <h3 class="h3 mb-0" itemprop="headline">@specialPage.Item.GetItem("Title")</h3> 1227 </a> 1228 <p class="m-0 opacity-75">@specialPage.Item.GetItem("Summary")</p> 1229 </div> 1230 </article> 1231 } 1232 1233 } 1234 1235 } 1236 } 1237 1238 @helper RenderImage(string coverImagePath, string title, string cssPosition, string imageObjectFit, string gridSettings, string carouselSettings) 1239 { 1240 switch(coverImagePath) 1241 { 1242 case string a when a.Contains(".jpeg"): 1243 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".jpeg") + 5); 1244 break; 1245 case string b when b.Contains(".jpg"): 1246 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".jpg") + 4); 1247 break; 1248 case string c when c.Contains(".png"): 1249 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".png") + 4); 1250 break; 1251 1252 } 1253 1254 coverImagePath = Dynamicweb.Context.Current.Server.UrlEncode(coverImagePath); 1255 1256 string imgSizeSelector = "50vw"; 1257 1258 if (gridSettings == "1" || carouselSettings == "1") 1259 { 1260 imgSizeSelector = "100vw"; 1261 } 1262 else if (gridSettings == "2" || carouselSettings == "2") 1263 { 1264 imgSizeSelector = "50vw"; 1265 } 1266 else if (gridSettings == "3" || carouselSettings == "3") 1267 { 1268 imgSizeSelector = "33vw"; 1269 } 1270 else if (gridSettings == "4" || carouselSettings == "4") 1271 { 1272 imgSizeSelector = "25vw"; 1273 } 1274 else if (gridSettings == "5" || carouselSettings == "5") 1275 { 1276 imgSizeSelector = "17vw"; 1277 } 1278 1279 string coverImagePathM = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=640&quality=85&format=webp"; 1280 string coverImagePathL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=960&quality=85&format=webp"; 1281 string coverImagePathXL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=1280&quality=85&format=webp"; 1282 string coverImagePathXXL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=1920&quality=85&format=webp"; 1283 string imagePathFallBack = coverImagePathM; 1284 1285 <img srcset=" 1286 @coverImagePathM 640w, 1287 @coverImagePathL 960w, 1288 @coverImagePathXL 1280w, 1289 @coverImagePathXXL 1920w" 1290 src="@imagePathFallBack" 1291 sizes="(min-width: 992px) @imgSizeSelector, 100vw" 1292 loading="lazy" 1293 decoding="async" 1294 class="img-fluid image-zoom-lg-1-hover" 1295 style="@imageObjectFit; object-position: @cssPosition;" 1296 alt="@title"> 1297 } 1298 1299