Omlimmad stolpe/balk - 9×9×148 cm
Artikelnummer: 20463-13
EAN/GLN-nummer: 5703393748676
DB-nummer: 2479971
När du väljer omlimmade stolpar får du en stolpe som är tillverkad av furu - tryckimpregnerad NTR klass A, vilket innebär att den är avsedd för nedgrävning. Stolpen limmas ihop av två bitar trä för att minimera sprickbildning och skevhet samt säkerställa hållfasthet och formstabilitet.
Stolpen är rakt kapad i båda ändar.
SEK 679,00
InStock
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_947bd5314dd642dca41ff1cf97892cf6.<>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 1225 at CompiledRazorTemplates.Dynamic.RazorEngine_947bd5314dd642dca41ff1cf97892cf6.<>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 959 at CompiledRazorTemplates.Dynamic.RazorEngine_947bd5314dd642dca41ff1cf97892cf6.<>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 799 at CompiledRazorTemplates.Dynamic.RazorEngine_947bd5314dd642dca41ff1cf97892cf6.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 let toggleElement = document.querySelector(`.readmore-overlay_button[onclick="readMore('${id}')"]`); 691 if (toggleElement) { 692 let chevronIcon = toggleElement.querySelector("svg"); // Keep the chevron icon 693 toggleElement.innerHTML = element.classList.contains('collapsed') 694 ? '@Translate("Read more")' 695 : '@Translate("Read less")'; 696 697 if (chevronIcon) { 698 toggleElement.appendChild(chevronIcon); // Reattach the chevron icon 699 } 700 } 701 }; 702 </script> 703 } 704 } 705 706 @if (product.ProductFields != null && showProductFields) 707 { 708 if (product.ProductFields.Count > 0) 709 { 710 if (layout != "navtabs") 711 { 712 {@RenderFieldsFromList(product.ProductFields, layout, "") } 713 } 714 else 715 { 716 <div class="g-col-12"> 717 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 718 <div class="accordion-item"> 719 <h2 class="accordion-header" id="SpecificationHeading_@Model.ID"> 720 <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"> 721 @Translate("Specifications") 722 </button> 723 </h2> 724 <div id="SpecificationItem_@Model.ID" class="accordion-collapse" aria-labelledby="SpecificationHeading_@Model.ID" data-bs-parent="#Specifications_@Model.ID"> 725 <div class="accordion-body"> 726 @{ @RenderFieldsFromList(product.ProductFields, "List", colCount) } 727 </div> 728 </div> 729 </div> 730 </div> 731 </div> 732 } 733 } 734 } 735 736 @if (product.ProductCategories != null && Model.Item.GetBoolean("CategoryFields")) 737 { 738 if (product.ProductCategories.Count > 0) 739 { 740 if (layout != "navtabs") 741 { 742 foreach (var group in product.ProductCategories) 743 { 744 CategoryFieldViewModel category = group.Value; 745 bool hideHeader = Model.Item.GetBoolean("HideGroupHeaders"); 746 747 if (!hideHeader) 748 { 749 <h4 class="g-col-12 h4 mb-0">@group.Value.Name</h4> 750 } 751 752 { @RenderFieldsFromList(category.Fields, layout, colCount) } 753 } 754 } 755 else 756 { 757 <div class="g-col-12"> 758 <div class="accordion accordion-flush w-100" id="Specifications_@Model.ID"> 759 @foreach (var group in product.ProductCategories) 760 { 761 CategoryFieldViewModel category = group.Value; 762 763 <div class="accordion-item"> 764 <h2 class="accordion-header" id="SpecificationHeading_@group.Value.Id"> 765 <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"> 766 @group.Key 767 </button> 768 </h2> 769 <div id="SpecificationItem_@group.Value.Id" class="accordion-collapse" aria-labelledby="SpecificationHeading_@group.Value.Id" data-bs-parent="#Specifications_@Model.ID"> 770 <div class="accordion-body"> 771 @{ @RenderFieldsFromList(category.Fields, "list", colCount) } 772 </div> 773 </div> 774 </div> 775 } 776 </div> 777 </div> 778 } 779 } 780 } 781 </div> 782 } 783 else if (Pageview.IsVisualEditorMode) 784 { 785 <div class="alert alert-warning m-0">@Translate("No products available")</div> 786 } 787 788 @helper RenderFieldsFromList(Dictionary<string, FieldValueViewModel> fields, string layout, string colCount) 789 { 790 string size = Model.Item.GetRawValueString("Size", "full"); 791 string gaps = size != "full" ? " gap-1" : string.Empty; 792 bool hideFieldLabels = Model.Item.GetBoolean("HideFieldLabels"); 793 794 if (layout == "display-fields") 795 { 796 <div class="g-col-12 grid gap-0"> 797 @foreach (var field in fields) 798 { 799 {@RenderField(field.Value, layout, colCount)} 800 } 801 </div> 802 } 803 if (layout == "columns") 804 { 805 <div class="g-col-12 grid@(gaps)"> 806 @foreach (var field in fields) 807 { 808 {@RenderField(field.Value, layout, "")} 809 } 810 </div> 811 } 812 if (layout == "list") 813 { 814 <dl class="g-col-12 grid@(gaps)"> 815 @foreach (var field in fields) 816 { 817 {@RenderField(field.Value, layout, "")} 818 } 819 </dl> 820 } 821 if (layout == "table") 822 { 823 string tableSize = size == "full" ? "" : " table-sm"; 824 <div class="g-col-12"> 825 <table class="table table-striped@(tableSize)"> 826 @foreach (var field in fields) 827 { 828 {@RenderField(field.Value, layout, "")} 829 } 830 </table> 831 </div> 832 } 833 if (layout == "bullets") 834 { 835 string listSize = size == "full" ? "" : "m-0 p-0 lh-1 fs-7 opacity-75"; 836 string listStyle = size == "full" ? "" : "style=\"list-style-position: inside\""; 837 <div class="g-col-12"> 838 <ul class="@listSize" @listStyle> 839 @foreach (var field in fields) 840 { 841 {@RenderField(field.Value, layout, "")} 842 } 843 </ul> 844 </div> 845 } 846 if (layout == "commas") 847 { 848 List<string> featuresList = new List<string>(); 849 850 foreach (var field in fields) 851 { 852 if (field.Value.Value is object && !string.IsNullOrEmpty(field.Value.Value.ToString())) 853 { 854 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 855 { 856 List<string> options = new List<string>(); 857 foreach (FieldOptionValueViewModel option in field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>) 858 { 859 if (!string.IsNullOrWhiteSpace(option.Value)) 860 { 861 if (option.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 862 { 863 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + option.Value + "\"></span>"; 864 options.Add(colorSpan); 865 } 866 else if (!string.IsNullOrEmpty(option.Value)) 867 { 868 options.Add(option.Name); 869 } 870 } 871 } 872 string optionsString = (string.Join(", ", options.Select(x => x.ToString()).ToArray())); 873 if ((Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 874 { 875 optionsString = (string.Join(" ", options.Select(x => x.ToString()).ToArray())); 876 } 877 878 if (!hideFieldLabels) 879 { 880 featuresList.Add(field.Value.Name + ": " + optionsString); 881 } 882 else 883 { 884 featuresList.Add(optionsString); 885 } 886 } 887 else 888 { 889 if (!string.IsNullOrWhiteSpace(field.Value.Value.ToString())) 890 { 891 if (field.Value.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 892 { 893 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + field.Value.Value + "\"></span>"; 894 895 if (!hideFieldLabels) 896 { 897 featuresList.Add(field.Value.Name + ": " + colorSpan); 898 } 899 else 900 { 901 featuresList.Add(colorSpan); 902 } 903 } 904 else 905 { 906 if (!hideFieldLabels) 907 { 908 featuresList.Add(field.Value.Name + ": " + field.Value.Value.ToString()); 909 } 910 else 911 { 912 featuresList.Add(field.Value.Value.ToString()); 913 } 914 } 915 } 916 } 917 } 918 } 919 920 string featuresString = (string.Join(", ", featuresList.Select(x => x.ToString()).ToArray())); 921 922 <div class="g-col-12 opacity-75 fs-7">@featuresString</div> 923 } 924 } 925 926 @helper RenderField(FieldValueViewModel field, string layout, string colCount) 927 { 928 string size = Model.Item.GetRawValueString("Size", "full"); 929 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 930 bool hideFieldLabels = Model.Item.GetBoolean("HideFieldLabels"); 931 bool noValues = false; 932 string orderLast = ""; 933 934 if (!string.IsNullOrEmpty(fieldValue)) 935 { 936 if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 937 { 938 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 939 noValues = values.Count > 0 ? false : true; 940 } 941 } 942 943 if (!string.IsNullOrEmpty(fieldValue) && noValues == false) 944 { 945 if (layout == "display-fields") 946 { 947 if (fieldValue == "1") { 948 orderLast = "order-last"; 949 } 950 951 <div class="g-col-12 @colCount @orderLast mb-3 pe-0 pe-md-4"> 952 953 @if (field.SystemName.Contains("InspirationArticleTabId")) 954 { 955 var dummy = false; 956 if (fieldValue == "1") { 957 dummy = true; 958 } else { 959 @RenderArticle(fieldValue, dummy) 960 } 961 } 962 else 963 { 964 if (!hideFieldLabels) 965 { 966 if (field?.SystemName != "ProductLongDescription") 967 { 968 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 969 { 970 <p class="fw-bold m-0">@Translate(field?.Name):</p> 971 } 972 else 973 { 974 <p class="fw-bold m-0">@field.Name:</p> 975 } 976 } 977 } 978 <p class="text-break m-0"> 979 @{ @RenderFieldValue(field) } 980 </p> 981 } 982 </div> 983 } 984 if (layout == "columns") 985 { 986 987 <div class="grid g-col-6 g-col-lg-4 gap-1"> 988 @if (!hideFieldLabels) 989 { 990 if (field?.SystemName != "ProductLongDescription") 991 { 992 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 993 { 994 <dt class="g-col-12 g-col-lg-4">@Translate(field?.Name)</dt> 995 } 996 else 997 { 998 <dt class="g-col-12 g-col-lg-4">@field?.Name</dt> 999 } 1000 } 1001 } 1002 <dd class="g-col-12 g-col-lg-8 mb-0 text-break"> 1003 @{ @RenderFieldValue(field) } 1004 </dd> 1005 </div> 1006 } 1007 if (layout == "list") 1008 { 1009 if (!hideFieldLabels) 1010 { 1011 if (field?.SystemName != "ProductLongDescription") 1012 { 1013 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1014 { 1015 <dt class="g-col-4">@Translate(field?.Name)</dt> 1016 } 1017 else 1018 { 1019 <dt class="g-col-4">@field?.Name</dt> 1020 } 1021 } 1022 } 1023 <dd class="g-col-8 mb-0 text-break"> 1024 @{ @RenderFieldValue(field) } 1025 </dd> 1026 } 1027 if (layout == "table") 1028 { 1029 <tr> 1030 @if (!hideFieldLabels) 1031 { 1032 if (field?.SystemName != "ProductLongDescription") 1033 { 1034 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1035 { 1036 <th class="w-25 w-lg-50" scope="row">@Translate(field?.Name)</th> 1037 } 1038 else 1039 { 1040 <th class="w-25 w-lg-50" scope="row">@field?.Name</th> 1041 } 1042 } 1043 } 1044 <td class="text-break"> 1045 @{ @RenderFieldValue(field) } 1046 </td> 1047 </tr> 1048 } 1049 if (layout == "bullets") 1050 { 1051 <li> 1052 @if (!hideFieldLabels) 1053 { 1054 if (field?.SystemName != "ProductLongDescription") 1055 { 1056 if (Dynamicweb.Ecommerce.Common.Context.LanguageID == "LANG2") 1057 { 1058 <strong>@Translate(field?.Name)</strong> 1059 } 1060 else 1061 { 1062 <strong>@field?.Name</strong> 1063 } 1064 } 1065 } 1066 <span> 1067 @{ @RenderFieldValue(field) } 1068 </span> 1069 </li> 1070 } 1071 } 1072 } 1073 1074 @helper RenderFieldValue(FieldValueViewModel field) 1075 { 1076 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 1077 1078 bool isLink = field?.Type == "Link"; 1079 bool isColor = false; 1080 bool isBrandName = field?.SystemName == "Brand_name"; 1081 bool isYoutubeVideo = field?.SystemName == "VideoLink"; 1082 1083 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 1084 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 1085 1086 1087 if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 1088 { 1089 int valueCount = 0; 1090 System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; 1091 int totalValues = values.Count; 1092 1093 foreach (FieldOptionValueViewModel option in values) 1094 { 1095 if (!string.IsNullOrEmpty(option.Value)) 1096 { 1097 if (option.Value.Substring(0, 1) == "#") 1098 { 1099 isColor = true; 1100 } 1101 } 1102 1103 if (!isColor) 1104 { 1105 @option.Name 1106 } 1107 else 1108 { 1109 <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Name"></span> 1110 } 1111 1112 if (valueCount != totalValues && valueCount < (totalValues - 1)) 1113 { 1114 if (isColor) 1115 { 1116 <text> </text> 1117 } 1118 else 1119 { 1120 <text>, </text> 1121 } 1122 } 1123 valueCount++; 1124 } 1125 } 1126 else 1127 { 1128 if (fieldValue.Substring(0, 1) == "#") 1129 { 1130 isColor = true; 1131 } 1132 1133 if (!isColor) 1134 { 1135 if (isLink) 1136 { 1137 string linktTitle = !fieldValue.Contains("aspx") ? fieldValue : Translate("Go to link"); 1138 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "target=\"_blank\"" : string.Empty; 1139 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "rel=\"noopener\"" : string.Empty; 1140 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 1141 if (isYoutubeVideo) 1142 { 1143 var videoId = linktTitle; 1144 1145 videoId = videoId.StartsWith("http://") ? videoId.Replace("http://", "") : ""; 1146 1147 linktTitle = "https://img.youtube.com/vi/" + linktTitle.Substring(linktTitle.LastIndexOf('=') + 1) + "/maxresdefault.jpg"; 1148 1149 RatioSettings ratioSettings = GetRatioSettings("desktop"); 1150 1151 <div id="SmallScreenImagesThumbnails_@Model.ID" class="grid grid-2 gap-2 overflow-x-auto my-3"> 1152 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to=""> 1153 <a class="d-flex align-items-center justify-content-center" href="@field.Value" @target @rel> 1154 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 1155 <img src="@linktTitle" alt="" class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain" data-video-id="@field.Value"> 1156 </a> 1157 </div> 1158 </div> 1159 } 1160 else 1161 { 1162 <a href="@field.Value" title="@field.Name" @target @rel>@linktTitle</a> 1163 } 1164 1165 } 1166 else if (isBrandName) 1167 { 1168 <span itemprop="brand" itemtype="https://schema.org/Brand" itemscope> 1169 <span itemprop="name">@fieldValue</span> 1170 </span> 1171 } 1172 1173 else 1174 { 1175 @fieldValue 1176 } 1177 } 1178 else 1179 { 1180 <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> 1181 } 1182 } 1183 } 1184 1185 @helper RenderVideoPreview(string fieldValue, string fieldName) { 1186 1187 string linktTitle = !fieldValue.Contains("aspx") ? fieldValue : Translate("Go to link"); 1188 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "target=\"_blank\"" : string.Empty; 1189 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && fieldValue.Contains("http") ? "rel=\"noopener\"" : string.Empty; 1190 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 1191 1192 var videoId = linktTitle; 1193 1194 videoId = videoId.StartsWith("http://") ? videoId.Replace("http://", "") : ""; 1195 1196 linktTitle = "https://img.youtube.com/vi/" + linktTitle.Substring(linktTitle.LastIndexOf('=') + 1) + "/maxresdefault.jpg"; 1197 1198 RatioSettings ratioSettings = GetRatioSettings("desktop"); 1199 1200 <p class="fw-bold m-0">@(fieldName):</p> 1201 <div id="SmallScreenImagesThumbnails_@Model.ID" class="grid grid-2 gap-2 overflow-x-auto my-3"> 1202 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to=""> 1203 <a class="d-flex align-items-center justify-content-center" href="@fieldValue" @target @rel> 1204 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 1205 <img src="@linktTitle" alt="" class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain" data-video-id="@fieldValue"> 1206 </a> 1207 </div> 1208 </div> 1209 1210 } 1211 1212 @helper RenderArticle(string fieldValue, bool dummy) { 1213 1214 if (!string.IsNullOrEmpty(fieldValue)) { 1215 1216 if (dummy) { 1217 //dummy filler 1218 } 1219 else 1220 { 1221 int id = fieldValue != "0" ? Int32.Parse(fieldValue) : 0; 1222 if (id > 0) { 1223 1224 var specialPage = Dynamicweb.Content.Services.Pages.GetPage(id); 1225 string title = specialPage.Item.GetItem("Title").ToString(); 1226 string coverImagePath = !string.IsNullOrEmpty(specialPage.Item.GetItem("CoverImage").ToString()) ? specialPage.Item.GetItem("CoverImage").ToString() : string.Empty; 1227 1228 <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;"> 1229 1230 <a class="w-100 " title="@specialPage.Item.GetItem("Title")" href="@specialPage.GetPageHrefValue()" tabindex="-1"> 1231 1232 <figure class="h-lg-100 overflow-hidden m-0 mx-auto ratio ratio-16x9" aria-label="@coverImagePath"> 1233 @RenderImage(coverImagePath, title, "50% 50%", "object-fit: cover", "2", "2") 1234 </figure> 1235 </a> 1236 <div class="d-flex flex-column flex-grow-1 gap-3 w-100 p-3 p-md-4"> 1237 <a class="text-decoration-none text-decoration-underline-hover" href="@specialPage.GetPageHrefValue()"> 1238 <h3 class="h3 mb-0" itemprop="headline">@specialPage.Item.GetItem("Title")</h3> 1239 </a> 1240 <p class="m-0 opacity-75">@specialPage.Item.GetItem("Summary")</p> 1241 </div> 1242 </article> 1243 } 1244 1245 } 1246 1247 } 1248 } 1249 1250 @helper RenderImage(string coverImagePath, string title, string cssPosition, string imageObjectFit, string gridSettings, string carouselSettings) 1251 { 1252 switch(coverImagePath) 1253 { 1254 case string a when a.Contains(".jpeg"): 1255 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".jpeg") + 5); 1256 break; 1257 case string b when b.Contains(".jpg"): 1258 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".jpg") + 4); 1259 break; 1260 case string c when c.Contains(".png"): 1261 coverImagePath = coverImagePath.Substring(0, coverImagePath.IndexOf(".png") + 4); 1262 break; 1263 1264 } 1265 1266 coverImagePath = Dynamicweb.Context.Current.Server.UrlEncode(coverImagePath); 1267 1268 string imgSizeSelector = "50vw"; 1269 1270 if (gridSettings == "1" || carouselSettings == "1") 1271 { 1272 imgSizeSelector = "100vw"; 1273 } 1274 else if (gridSettings == "2" || carouselSettings == "2") 1275 { 1276 imgSizeSelector = "50vw"; 1277 } 1278 else if (gridSettings == "3" || carouselSettings == "3") 1279 { 1280 imgSizeSelector = "33vw"; 1281 } 1282 else if (gridSettings == "4" || carouselSettings == "4") 1283 { 1284 imgSizeSelector = "25vw"; 1285 } 1286 else if (gridSettings == "5" || carouselSettings == "5") 1287 { 1288 imgSizeSelector = "17vw"; 1289 } 1290 1291 string coverImagePathM = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=640&quality=85&format=webp"; 1292 string coverImagePathL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=960&quality=85&format=webp"; 1293 string coverImagePathXL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=1280&quality=85&format=webp"; 1294 string coverImagePathXXL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=1920&quality=85&format=webp"; 1295 string imagePathFallBack = coverImagePathM; 1296 1297 <img srcset=" 1298 @coverImagePathM 640w, 1299 @coverImagePathL 960w, 1300 @coverImagePathXL 1280w, 1301 @coverImagePathXXL 1920w" 1302 src="@imagePathFallBack" 1303 sizes="(min-width: 992px) @imgSizeSelector, 100vw" 1304 loading="lazy" 1305 decoding="async" 1306 class="img-fluid image-zoom-lg-1-hover" 1307 style="@imageObjectFit; object-position: @cssPosition;" 1308 alt="@title"> 1309 } 1310 1311