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.
NOK 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_20f825e296104752862f67acbb0f8cdd.<>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_20f825e296104752862f67acbb0f8cdd.<>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_20f825e296104752862f67acbb0f8cdd.<>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_20f825e296104752862f67acbb0f8cdd.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