Error executing template "Designs/Swift/_parsed/Swift_CustomerCenter.parsed.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_0c68279cf42d4caaa69ff40d493f74de.Execute() in C:\inetpub\wwwroot\directions2023_dev\Files\Templates\Designs\Swift\_parsed\Swift_CustomerCenter.parsed.cshtml:line 601
   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.PageViewModel> 2 @using System 3 @using Dynamicweb 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Frontend 6 7 @functions { 8 string GetCookieOptInPermission(string category) 9 { 10 bool categoryOrAllGranted = false; 11 12 if (CookieManager.IsCookieManagementActive) 13 { 14 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 15 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 16 categoryOrAllGranted = cookieOptInCategories.Contains(category) || cookieOptInLevel == CookieOptInLevel.All; 17 18 } 19 20 return categoryOrAllGranted ? "granted" : "denied"; 21 } 22 23 bool AllowTracking() 24 { 25 bool allowTracking = true; 26 if (CookieManager.IsCookieManagementActive) 27 { 28 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 29 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 30 31 bool consentEither = (cookieOptInCategories.Contains("Statistical") || cookieOptInCategories.Contains("Marketing")); 32 bool consentFunctional = cookieOptInLevel == CookieOptInLevel.Functional; 33 bool consentAtLeastOne = cookieOptInLevel == CookieOptInLevel.All || (consentFunctional && consentEither); 34 35 allowTracking = consentAtLeastOne; 36 } 37 return allowTracking; 38 } 39 } 40 41 @{ 42 43 //CUSTOM CODE 44 //handle Maintenance mode 45 var maintenancePage = Model.Area.Item?.GetLink("MaintenancePage") ?? null; 46 bool maintenanceMode = Model.Area.Item.GetBoolean("MaintenanceMode"); 47 DateTime maintenanceStartDate = Model.Area.Item.GetDateTime("MaintenanceStartDate"); 48 DateTime maintenanceEndDate = Model.Area.Item.GetDateTime("MaintenanceEndDate"); 49 DateTime currentDate = System.DateTime.Now; 50 maintenanceMode = maintenanceMode && maintenanceStartDate <= currentDate && maintenanceEndDate >= currentDate; 51 var adminUser = Dynamicweb.Security.UserManagement.User.GetCurrentBackendUser(); 52 int currentPage = Dynamicweb.Frontend.PageView.Current().Page.ID; 53 54 if(maintenanceMode && maintenancePage != null && adminUser == null && maintenancePage.PageId != currentPage) 55 { 56 string redirectLink = "/" + maintenancePage; 57 Dynamicweb.Context.Current.Response.Redirect(redirectLink); 58 } 59 60 //CUSTOM CODE 61 62 var cartSummaryPageId = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Model.Area.ID, "CartSummary")?.ID; 63 bool enableMiniCart = Model.Area.Item?.GetBoolean("EnableOffcanvasMiniCart") ?? false; 64 var offcanvasMiniCartBehaviour = Model.Area.Item?.GetRawValueString("OffcanvasMinicartBehaviour", "3") ?? "3"; 65 bool miniCartEnabled = cartSummaryPageId != null && enableMiniCart; 66 var brandingPageId = Model.Area.Item?.GetInt32("BrandingPage") ?? 0; 67 var themePageId = Model.Area.Item?.GetInt32("ThemesPage") ?? 0; 68 var cssPageId = Model.Area.Item?.GetInt32("CssPage") ?? 0; 69 var brandingPage = brandingPageId != 0 ? Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null : null; 70 var themesParagraphs = themePageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(themePageId) ?? null : null; 71 var cssParagraphs = cssPageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(cssPageId) ?? null : null; 72 73 //CUSTOM CODE 74 var backgroundPageId = Model.Area.Item?.GetInt32("BackgroundsPage") ?? 0; 75 var backgroundParagraphs = backgroundPageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(backgroundPageId) ?? null : null; 76 //CUSTOM CODE 77 } 78 79 @if (themesParagraphs != null || brandingPage != null) 80 { 81 string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt"); 82 bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase); 83 bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet; 84 string responsiveClassDesktop = string.Empty; 85 string responsiveClassMobile = string.Empty; 86 if (renderAsResponsive) 87 { 88 responsiveClassDesktop = " d-none d-xl-block"; 89 responsiveClassMobile = " d-block d-xl-none"; 90 } 91 92 var headerDesktopLink = Model.Area.Item?.GetLink("HeaderDesktop") ?? null; 93 var headerMobileLink = Model.Area.Item?.GetLink("HeaderMobile") ?? null; 94 95 var footerDesktopLink = Model.Area.Item?.GetLink("FooterDesktop") ?? null; 96 var footerMobileLink = Model.Area.Item?.GetLink("FooterMobile") ?? null; 97 98 var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default"); 99 100 string customHeaderInclude = !string.IsNullOrEmpty(Model.Area.Item.GetRawValueString("CustomHeaderInclude")) ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty; 101 102 var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 103 var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt; 104 105 var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css")); 106 107 //CUSTOM CODE 108 //Create a collection with all last modified dates 109 List<DateTime> filesAudit = new List<DateTime>(); 110 if(brandingPage != null) 111 { 112 filesAudit.Add(brandingPage.Audit.LastModifiedAt); 113 } 114 if(backgroundParagraphs != null) 115 { 116 var backgroundParagraphLastChanged = backgroundParagraphs.OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 117 filesAudit.Add(backgroundParagraphLastChanged.Audit.LastModifiedAt); 118 } 119 120 cssLastModified = filesAudit.Max(); 121 122 if (backgroundPageId != 0) 123 { 124 var backgroundFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_backgrounds_styles_{Model.Area.ID}.css")); 125 126 if(backgroundParagraphs.Any() && !backgroundFileInfo.Exists) 127 { 128 129 var backgroundParagraphLastChanged = backgroundParagraphs.OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 130 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < backgroundParagraphLastChanged.Audit.LastModifiedAt) 131 { 132 133 var backgroundPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(backgroundPageId); 134 backgroundPageview.Redirect = false; 135 backgroundPageview.Output(); 136 } 137 } 138 } 139 140 //CUSTOM CODE 141 142 if (cssPageId != 0) 143 { 144 var cssFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_css_styles_{Model.Area.ID}.css")); 145 var cssParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(cssPageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 146 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < cssParagraphLastChanged.Audit.LastModifiedAt) 147 { 148 var cssPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(cssPageId); 149 cssPageview.Redirect = false; 150 cssPageview.Output(); 151 152 var backgroundPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(backgroundPageId); 153 backgroundPageview.Redirect = false; 154 backgroundPageview.Output(); 155 } 156 } 157 158 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt) 159 { 160 //Branding page has been saved or the file is missing. Rewrite the file to disc. 161 if (brandingPageId > 0) 162 { 163 var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId); 164 brandingPageview.Redirect = false; 165 brandingPageview.Output(); 166 } 167 } 168 169 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt) 170 { 171 //Branding page has been saved or the file is missing. Rewrite the file to disc. 172 if (themePageId > 0) 173 { 174 var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId); 175 themePageview.Redirect = false; 176 themePageview.Output(); 177 } 178 } 179 180 // Schema.org details for PDP 181 bool isProductDetailsPage = Dynamicweb.Context.Current.Request.QueryString.AllKeys.Contains("ProductID"); 182 bool isArticlePage = Model.ItemType == "Swift_Article"; 183 string schemaOrgType = string.Empty; 184 185 if (isProductDetailsPage) 186 { 187 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\""; 188 } 189 190 if (isArticlePage) 191 { 192 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\""; 193 } 194 195 196 var cssStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/styles.css")); 197 var jsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/scripts.js")); 198 //CUSTOM CODE// 199 var customJsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("Files/Templates/Designs/Swift/Assets/js/custom-scripts.js")); 200 //CUSTOM CODE// 201 string masterTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("Theme")) ? " theme " + Model.Area.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 202 203 string favicon = Model.Area.Item.GetRawValueString("Favicon", "/Files/Templates/Designs/Swift/Assets/Images/favicon.png"); 204 string appleTouchIcon = Model.Area.Item.GetRawValueString("AppleTouchIcon", "/Files/Templates/Designs/Swift/Assets/Images/apple-touch-icon.png"); 205 206 string headerCssClass = "sticky-top"; 207 bool movePageBehind = false; 208 209 if (Model.PropertyItem != null) 210 { 211 headerCssClass = Model.PropertyItem.GetRawValueString("MoveThisPageBehindTheHeader", "sticky-top"); 212 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 213 } 214 215 headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass; 216 headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass; 217 218 string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID").Trim(); 219 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID").Trim(); 220 221 bool allowTracking = AllowTracking(); 222 223 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;"); 224 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css?{cssLastModified.Ticks}>; rel=preload; as=style;"); 225 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}>; rel=preload; as=script;"); 226 //CUSTOM CODE 227 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/custom-scripts.js?{customJsFileInfo.LastWriteTime.Ticks}>; rel=preload; as=script;"); 228 //CUSTOM CODE 229 230 SetMetaTags(); 231 232 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>(); 233 234 var masterPage = Pageview.Area.IsMaster ? Pageview.Page : Pageview.Page.MasterPage; 235 languages.Add(masterPage); 236 if (masterPage?.Languages != null) 237 { 238 foreach (var language in masterPage.Languages) 239 { 240 languages.Add(language); 241 } 242 } 243 244 Uri url = Dynamicweb.Context.Current.Request.Url; 245 string hostName = url.Host; 246 247 <!doctype html> 248 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName"> 249 <head> 250 <!-- @swiftVersion --> 251 @* Required meta tags *@ 252 <meta charset="utf-8"> 253 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0"> 254 <link rel="shortcut icon" href="@favicon"> 255 <link rel="apple-touch-icon" href="@appleTouchIcon"> 256 257 @Model.MetaTags 258 259 @{ 260 var alreadyWrittenTwoletterIsos = new List<string>(); 261 @* Languages meta data *@ 262 foreach (var language in languages) 263 { 264 hostName = url.Host; 265 if (language?.Area != null) 266 { 267 if (language.Area?.MasterArea != null && !string.IsNullOrEmpty(language.Area.MasterArea.DomainLock)) 268 { 269 hostName = language.Area.MasterArea.DomainLock; //dk.domain.com or dk-domain.dk 270 } 271 if (language != null && language.Area != null && language.Published && language.Area.Active && language.Area.Published) 272 { 273 if (!string.IsNullOrEmpty(language.Area.DomainLock)) 274 { 275 hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk 276 } 277 string querystring = $"Default.aspx?ID={language.ID}"; 278 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"])) 279 { 280 querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}"; 281 } 282 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 283 { 284 querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}"; 285 } 286 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"])) 287 { 288 querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}"; 289 } 290 291 string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring); 292 if (language.Area.RedirectFirstPage && language.ParentPageId == 0 && language.Sort == 1) 293 { 294 friendlyUrl = "/"; 295 } 296 string href = $"{url.Scheme}://{hostName}{friendlyUrl}"; 297 298 299 <link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href"> 300 if (!alreadyWrittenTwoletterIsos.Contains(language.Area.CultureInfo.TwoLetterISOLanguageName)) 301 { 302 alreadyWrittenTwoletterIsos.Add(language.Area.CultureInfo.TwoLetterISOLanguageName); 303 <link rel="alternate" hreflang="@language.Area.CultureInfo.TwoLetterISOLanguageName.ToLower()" href="@href"> 304 } 305 } 306 } 307 } 308 } 309 310 <title>@Model.Title</title> 311 @* Bootstrap + Swift stylesheet *@ 312 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 313 314 @if (disableWideBreakpoints != "disableBoth") 315 { 316 <style> 317 @@media ( min-width: 1600px ) { 318 .container-xxl, 319 .container-xl, 320 .container-lg, 321 .container-md, 322 .container-sm, 323 .container { 324 max-width: 1520px; 325 } 326 } 327 </style> 328 329 330 331 if (disableWideBreakpoints != "disableUltraWideOnly") 332 { 333 <style> 334 @@media ( min-width: 1920px ) { 335 .container-xxl, 336 .container-xl, 337 .container-lg, 338 .container-md, 339 .container-sm, 340 .container { 341 max-width: 1820px; 342 } 343 } 344 </style> 345 } 346 } 347 348 @* Branding and Themes min stylesheet *@ 349 <link href="/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_@(Model.Area.ID).min.css?@cssLastModified.Ticks" rel="stylesheet" media="all" type="text/css" data-last-modified-content="@cssLastModified"> 350 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks"></script> 351 @*CUSTOM CODE*@ 352 <script src="/Files/Templates/Designs/Swift/Assets/js/custom-scripts.js?@customJsFileInfo.LastWriteTime.Ticks" defer></script> 353 @*CUSTOM CODE*@ 354 <script type="module"> 355 swift.Scroll.hideHeadersOnScroll(); 356 swift.Scroll.handleAlternativeTheme(); 357 358 //Only load if AOS 359 const aosColumns = document.querySelectorAll('[data-aos]'); 360 if (aosColumns.length > 0) { 361 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks', 'js'); 362 document.addEventListener('load.swift.assetloader', function () { 363 AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') }); 364 }); 365 } 366 </script> 367 368 @* Google gtag method - always include even if it is not used for anything *@ 369 <script> 370 window.dataLayer = window.dataLayer || []; 371 function gtag() { dataLayer.push(arguments); } 372 </script> 373 374 @* Google tag manager *@ 375 @if (!string.IsNullOrWhiteSpace(googleTagManagerID)) 376 { 377 <script> 378 gtag('consent', 'default', { 379 'ad_storage': 'denied', 380 'ad_user_data': 'denied', 381 'ad_personalization': 'denied', 382 'analytics_storage': 'denied' 383 }); 384 385 window.dataLayer.push({ 386 'event': 'cookie_cat_functional', 387 'cookie_cat_functional': 'true' 388 389 }); 390 </script> 391 <script> 392 (function (w, d, s, l, i) { 393 w[l] = w[l] || []; w[l].push({ 394 'gtm.start': 395 new Date().getTime(), event: 'gtm.js' 396 }); var f = d.getElementsByTagName(s)[0], 397 j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 398 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); 399 })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)'); 400 </script> 401 402 if (allowTracking) 403 { 404 string adConsent = GetCookieOptInPermission("Marketing"); 405 string analyticsConsent = GetCookieOptInPermission("Statistical"); 406 407 string dataLayerMarketing = adConsent == "granted" ? "'event': 'cookie_cat_marketing','cookie_cat_marketing': 'true'" : "'event': 'cookie_cat_marketing','cookie_cat_marketing': 'false'"; 408 string dataLayerStatistical = analyticsConsent == "granted" ? "'event': 'cookie_cat_statistic','cookie_cat_statistic': 'true'" : "'event': 'cookie_cat_statistic','cookie_cat_statistic': 'false'"; 409 410 <script> 411 gtag('consent', 'update', { 412 'ad_storage': '@adConsent', 413 'ad_user_data': '@adConsent', 414 'ad_personalization': '@adConsent', 415 'analytics_storage': '@analyticsConsent' 416 }); 417 418 419 dataLayer.push({@dataLayerMarketing}); 420 dataLayer.push({@dataLayerStatistical}); 421 422 </script> 423 } else { 424 <script> 425 window.dataLayer.push({ 426 'event': 'cookie_cat_marketing', 427 'cookie_cat_marketing' : 'false' 428 429 }); 430 window.dataLayer.push({ 431 'event': 'cookie_cat_statistic', 432 'cookie_cat_statistic' : 'false' 433 }); 434 </script> 435 } 436 } 437 438 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) 439 { 440 var GoogleAnalyticsDebugMode = ""; 441 442 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode")) 443 { 444 GoogleAnalyticsDebugMode = ", {'debug_mode': true}"; 445 } 446 447 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script> 448 <script> 449 gtag('js', new Date()); 450 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode); 451 </script> 452 } 453 454 @if (!string.IsNullOrWhiteSpace(customHeaderInclude)) 455 { 456 @RenderPartial($"Components/Custom/{customHeaderInclude}") 457 } 458 </head> 459 <body class="brand @(masterTheme)" id="page@(Model.ID)"> 460 461 @* Google tag manager *@ 462 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking) 463 { 464 <noscript> 465 <iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)" 466 height="0" width="0" style="display:none;visibility:hidden"></iframe> 467 </noscript> 468 } 469 470 @if (renderAsResponsive || !renderMobile) 471 { 472 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop"> 473 @if (headerDesktopLink != null) 474 { 475 @RenderGrid(headerDesktopLink.PageId) 476 } 477 </header> 478 } 479 480 @if ((renderAsResponsive || renderMobile)) 481 { 482 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile"> 483 @if (headerMobileLink != null) 484 { 485 @RenderGrid(headerMobileLink.PageId) 486 } 487 </header> 488 } 489 490 <div data-intersect></div> 491 492 <main id="content" @(schemaOrgType)> 493 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 494 @using System 495 @using Dynamicweb.Ecommerce.ProductCatalog 496 @using Dynamicweb.Frontend.Navigation 497 498 499 @{ 500 string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty; 501 bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop"; 502 503 bool isArticlePagePage = Model.ItemType == "Swift_Article"; 504 bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage"; 505 string schemaOrgProp = string.Empty; 506 if(isArticlePagePage) 507 { 508 schemaOrgProp = "itemprop=\"articleBody\""; 509 } 510 511 string theme = ""; 512 string gridContent = ""; 513 514 if (Model.PropertyItem != null) 515 { 516 theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 517 } 518 519 if (Model.Item != null || Pageview.IsVisualEditorMode) 520 { 521 if (!isProductDetail) 522 { 523 gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page"); 524 } 525 else 526 { 527 var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId); 528 var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty; 529 var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage"); 530 531 @RenderGrid(detailPageId) 532 } 533 } 534 535 //Navigation settings 536 string navAlignment = "justify-content-start text-start"; 537 string navOrientation = "flex-column"; 538 string layout = "lines"; 539 string linkFontWeight = "fw-normal"; 540 string navTitleFontWeight = "fw-bold"; 541 string NavTitleCasing = "text-capitalize"; 542 string linkCasing = ""; 543 string linkFontSize = "fs-6"; 544 string navTitleFontSize = "h6"; 545 string navigationRoot = "112"; 546 bool showOnlyFirstLevel = true; 547 string contentPadding = " px-3 py-3"; 548 549 var navigationSettings = new NavigationSettings(); 550 navigationSettings.StartLevel = 1; 551 navigationSettings.StopLevel = 10; 552 navigationSettings.ExpandMode = ExpandMode.All; 553 554 navigationSettings.Parameters.Add("Layout", layout); 555 navigationSettings.Parameters.Add("LinkFontSize", linkFontSize); 556 navigationSettings.Parameters.Add("NavOrientation", navOrientation); 557 navigationSettings.Parameters.Add("LinkFontWeight", linkFontWeight); 558 navigationSettings.Parameters.Add("NavAlignment", navAlignment); 559 navigationSettings.Parameters.Add("LinkCasing", linkCasing); 560 navigationSettings.Parameters.Add("Theme", theme); 561 navigationSettings.Parameters.Add("ShowOnlyFirstNavLevel", showOnlyFirstLevel); 562 563 if (!string.IsNullOrEmpty(navigationRoot)) 564 { 565 int rootPageId = Convert.ToInt32(navigationRoot); 566 navigationSettings.RootPageId = rootPageId; 567 568 var page = Dynamicweb.Content.Services.Pages.GetPage(rootPageId); 569 if (page != null && !string.IsNullOrEmpty(page.NavigationTag)) 570 { 571 navigationSettings.Parameters.Add("menu-id", page.NavigationTag.ToLower()); 572 } 573 574 } 575 else 576 { 577 navigationSettings.Parameters.Add("menu-id", "root"); 578 } 579 580 581 bool doNotRenderPage = false; 582 583 //Check if we are on the poduct detail page, and if there is data to render 584 ProductViewModel product = new ProductViewModel(); 585 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 586 { 587 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 588 if (string.IsNullOrEmpty(product.Id)) { 589 doNotRenderPage = true; 590 } 591 } 592 593 //Render the page 594 if (!doNotRenderPage) { 595 string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page"; 596 string sectionClass = "py-3 py-lg-3"; 597 string containerClass = "container-xl"; 598 string mobileColumnSize = "1"; 599 string rowClass = ""; 600 601 <div class="@theme @itemIdentifier" @schemaOrgProp> 602 <div class="@(sectionClass)@(theme)"> 603 <div class="@containerClass"> 604 <div class="grid grid-@(mobileColumnSize) grid-lg-4@(rowClass)"> 605 <div class="g-col order-first order-lg-0" data-col-size="3" style="--bs-columns:12"> 606 <div class="h-100@(theme) item_@Model.Item.SystemName.ToLower()"> 607 @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 608 { 609 <h3 class="@contentPadding">@Model.Item.GetString("Title")</h3> 610 } 611 612 @Navigation.RenderNavigation("Navigation/Vertical.cshtml", navigationSettings) 613 </div> 614 </div> 615 <div class="g-col g-col-lg-3" data-col-size="9" style="--bs-columns:12"> 616 @gridContent 617 </div> 618 </div> 619 </div> 620 </div> 621 622 </div> 623 624 } else { 625 <div class="container"> 626 <div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div> 627 </div> 628 } 629 630 if (!Model.IsCurrentUserAllowed) 631 { 632 int signInPage = GetPageIdByNavigationTag("SignInPage"); 633 int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage"); 634 635 if (!Pageview.IsVisualEditorMode) 636 { 637 if (signInPage != 0) 638 { 639 if (signInPage != Model.ID) { 640 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage); 641 } else { 642 if (dashboardPage != 0) { 643 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage); 644 } else { 645 Dynamicweb.Context.Current.Response.Redirect("/"); 646 } 647 } 648 } 649 else 650 { 651 <div class="alert alert-dark m-0" role="alert"> 652 <span>@Translate("You do not have access to this page") @Pageview.Page.ID</span> 653 </div> 654 } 655 } 656 else 657 { 658 <div class="alert alert-dark m-0" role="alert"> 659 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span> 660 </div> 661 } 662 } 663 } 664 665 </main> 666 667 @if (renderAsResponsive || !renderMobile) 668 { 669 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop"> 670 @if (footerDesktopLink != null) 671 { 672 @RenderGrid(footerDesktopLink.PageId) 673 } 674 </footer> 675 } 676 677 @if (renderAsResponsive || renderMobile) 678 { 679 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile"> 680 @if (footerMobileLink != null) 681 { 682 @RenderGrid(footerMobileLink.PageId) 683 } 684 </footer> 685 } 686 687 @* Render any offcanvas menu here *@ 688 @RenderSnippet("offcanvas") 689 690 @{ 691 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]); 692 } 693 694 @* Language selector modal *@ 695 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true"> 696 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent"> 697 @* The content here comes from an external request *@ 698 </div> 699 </div> 700 701 @* Favorite toast *@ 702 <div aria-live="polite" aria-atomic="true"> 703 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11"> 704 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> 705 <div class="toast-header"> 706 <strong class="me-auto">@Translate("Favorite list updated")</strong> 707 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 708 </div> 709 <div class="toast-body d-flex gap-3"> 710 <div id="favoriteNotificationToast_Image"></div> 711 <div id="favoriteNotificationToast_Text"></div> 712 </div> 713 </div> 714 </div> 715 </div> 716 717 @* Modal for dynamic content *@ 718 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true"> 719 <div class="modal-dialog modal-dialog-centered modal-md"> 720 <div class="modal-content theme light" id="DynamicModalContent"> 721 @* The content here comes from an external request *@ 722 </div> 723 </div> 724 </div> 725 726 @* Offcanvas for dynamic content *@ 727 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas"> 728 @* The content here comes from an external request *@ 729 </div> 730 731 @if (Model.Area.Item.GetBoolean("ShowErpDownMessage") && !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"])) 732 { 733 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light"; 734 735 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040"> 736 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true"> 737 <div class="toast-header"> 738 <strong class="me-auto">@Translate("Connection down")</strong> 739 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 740 </div> 741 <div class="toast-body"> 742 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.") 743 </div> 744 </div> 745 </div> 746 } 747 748 @if (miniCartEnabled) 749 { 750 @* Open MiniCart when the cart is updated *@ 751 <script type="module"> 752 document.addEventListener('updated.swift.cart', (event) => { 753 let orderContext = event?.detail?.formData?.get("OrderContext"); 754 updateCartSummary(orderContext); 755 756 @if (offcanvasMiniCartBehaviour == "2" || offcanvasMiniCartBehaviour == "3") { 757 <text>openMiniCartOffcanvas();</text> 758 } 759 }); 760 </script> 761 762 if (offcanvasMiniCartBehaviour == "1" || offcanvasMiniCartBehaviour == "3") 763 { 764 @* Open MiniCart when toggle is clicked *@ 765 <script type="module"> 766 let miniCartToggles = document.querySelectorAll('.mini-cart-quantity'); 767 miniCartToggles?.forEach((toggle) => { 768 toggle.parentElement.addEventListener('click', (event) => { 769 event.preventDefault(); 770 let orderContext = toggle.dataset?.orderContext; 771 updateCartSummary(orderContext); 772 773 openMiniCartOffcanvas(); 774 }); 775 }); 776 </script> 777 } 778 779 <script> 780 781 const updateCartSummary = (orderContext) => { 782 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 783 swift.PageUpdater.UpdateFromUrlInline(event, '/Default.aspx?ID=@(cartSummaryPageId)&CartType=minicart&RequestPageID=@(Pageview.Page.ID)&OrderContext=' + orderContext +'', 'Swift_CartSummary.cshtml', dynamicOffcanvas); 784 }; 785 786 const openMiniCartOffcanvas = () => { 787 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 788 const miniCartOffcanvas = bootstrap.Offcanvas.getOrCreateInstance(dynamicOffcanvas); 789 dynamicOffcanvas.classList.add('overflow-y-auto'); 790 791 if (!miniCartOffcanvas._isShown) { 792 miniCartOffcanvas.show(); 793 hideActiveOffcanvases(miniCartOffcanvas); 794 } 795 }; 796 797 const hideActiveOffcanvases = (miniCartOffcanvas) => { 798 let activeOffcanvases = document.querySelectorAll('.offcanvas.show'); 799 activeOffcanvases?.forEach((offCanvas) => { 800 offCanvas = bootstrap.Offcanvas.getInstance(offCanvas); 801 if (offCanvas !== miniCartOffcanvas) { 802 offCanvas.hide(); 803 } 804 }); 805 }; 806 807 </script> 808 } 809 810 @* START CUSTOM CODE *@ 811 @RenderFaqModal() 812 @RenderCustomFontStyleTag() 813 @* END CUSTOM CODE *@ 814 815 816 817 @{ 818 var cookieBannerParameter = Dynamicweb.Context.Current.Request.QueryString["showcookiebanner"]; 819 string showCookieBanner = cookieBannerParameter != null ? cookieBannerParameter.ToString() : ""; 820 821 //if(showCookieBanner.Equals("true", StringComparison.OrdinalIgnoreCase)) 822 if(CookieManager.GetCookieOptInCategories().Any() && CookieManager.IsCookieManagementActive) 823 { 824 @RenderPartial($"CookieWarning/{Pageview.Area.CookieWarningTemplate}") 825 } 826 } 827 828 <button class="btn btn-secondary position-fixed bottom-0 mb-2 ms-2 bg-white" id="launchCookieModal" onclick="renderCookieModal()"> 829 @RenderIcon("/Files/Icons/cookies.svg") 830 </button> 831 </body> 832 833 </html> 834 835 } 836 else if (Pageview.IsVisualEditorMode) 837 { 838 <head> 839 <title>@Model.Title</title> 840 @* Bootstrap + Swift stylesheet *@ 841 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css" rel="stylesheet" media="all" type="text/css"> 842 </head> 843 <body class="p-3"> 844 <div class="alert alert-danger" role="alert"> 845 @Translate("Basic Swift setup is needed!") 846 </div> 847 848 @if (brandingPage == null) 849 { 850 <div class="alert alert-warning" role="alert"> 851 @Translate("Please add a Branding page and reference it in website settings") 852 </div> 853 } 854 855 @if (themesParagraphs == null) 856 { 857 <div class="alert alert-warning" role="alert"> 858 @Translate("Please add a Themes collection page and reference it in website settings") 859 </div> 860 } 861 862 863 </body> 864 } 865 866 867 @functions { 868 void SetMetaTags() 869 { 870 //Verification Tokens 871 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : ""; 872 873 //Generic Site Values 874 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : ""; 875 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : ""; 876 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : ""; 877 878 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : ""; 879 880 //Page specific values 881 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : ""; 882 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image"); 883 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : ""; 884 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : ""; 885 886 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : ""; 887 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : ""; 888 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : ""; 889 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image"); 890 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : ""; 891 string topImage = Pageview.Page.TopImage.StartsWith("/Files", StringComparison.OrdinalIgnoreCase) ? Pageview.Page.TopImage : $"/Files{Pageview.Page.TopImage}"; 892 893 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 894 { 895 if (!string.IsNullOrEmpty(Model.Description)) 896 { 897 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{Model.Description}\">"); 898 } 899 else 900 { 901 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{openGraphDescription}\">"); 902 } 903 904 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 905 { 906 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{topImage}\">"); 907 Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{topImage}\">"); 908 } 909 else if (openGraphImage != null) 910 { 911 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 912 Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 913 } 914 915 if (!string.IsNullOrEmpty(openGraphImageALT)) 916 { 917 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{openGraphImageALT}\">"); 918 } 919 if (!string.IsNullOrEmpty(twitterCardDescription)) 920 { 921 Pageview.Meta.AddTag("twitter:description", twitterCardDescription); 922 } 923 924 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 925 { 926 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{topImage}"); 927 } 928 else if (twitterCardImage != null) 929 { 930 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}"); 931 } 932 933 if (!string.IsNullOrEmpty(twitterCardImageALT)) 934 { 935 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT); 936 } 937 } 938 939 if (!string.IsNullOrEmpty(siteVerificationGoogle)) 940 { 941 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle); 942 } 943 944 if (!string.IsNullOrEmpty(openGraphFacebookAppID)) 945 { 946 Pageview.Meta.AddTag($"<meta property=\"fb:app_id\" content=\"{openGraphFacebookAppID}\">"); 947 } 948 949 if (!string.IsNullOrEmpty(openGraphType)) 950 { 951 Pageview.Meta.AddTag($"<meta property=\"og:type\" content=\"{openGraphType}\">"); 952 } 953 954 if (!string.IsNullOrEmpty(openGraphSiteName)) 955 { 956 Pageview.Meta.AddTag($"<meta property=\"og:url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Pageview.SearchFriendlyUrl}\">"); 957 } 958 959 if (!string.IsNullOrEmpty(openGraphSiteName)) 960 { 961 Pageview.Meta.AddTag($"<meta property=\"og:site_name\" content=\"{openGraphSiteName}\">"); 962 } 963 964 if (!string.IsNullOrEmpty(Model.Title)) 965 { 966 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{Model.Title}\">"); 967 } 968 else 969 { 970 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{openGraphSiteTitle}\">"); 971 } 972 973 if (!string.IsNullOrEmpty(twitterCardSite)) 974 { 975 Pageview.Meta.AddTag("twitter:site", twitterCardSite); 976 } 977 978 if (!string.IsNullOrEmpty(twitterCardURL)) 979 { 980 Pageview.Meta.AddTag("twitter:url", twitterCardURL); 981 } 982 983 if (!string.IsNullOrEmpty(twitterCardTitle)) 984 { 985 Pageview.Meta.AddTag("twitter:title", twitterCardTitle); 986 } 987 } 988 } 989 @* START CUSTOM CODE *@ 990 @helper RenderFaqModal() 991 { 992 var faqPage = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("FAQ")); 993 <div class="modal modal-xl faq-modal" aria-hidden="true" data-url="@faqPage"> 994 <div class="modal-dialog"> 995 <div class="modal-content"> 996 <div class="modal-header"> 997 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 998 </div> 999 <div class="modal-body p-0"></div> 1000 </div> 1001 </div> 1002 </div> 1003 } 1004 @helper RenderCustomFontStyleTag() 1005 { 1006 <style> 1007 @@font-face { 1008 font-family: 'Arsilon'; 1009 font-style: normal; 1010 font-weight: 400; 1011 font-display: swap; 1012 src: url(/Files/Templates/Designs/Swift/Assets/fonts/Arsilon.woff2) format('woff2'); 1013 } 1014 1015 1016 span.special { 1017 font-family:'Arsilon'; 1018 font-weight:400; 1019 font-style:normal; 1020 line-height:1.5; 1021 font-size:72px; 1022 } 1023 </style> 1024 } 1025 @helper RenderIcon(string icon) 1026 { 1027 if (System.IO.Path.GetExtension(icon).ToLower() == ".svg") 1028 { 1029 if (!icon.ToLower().Contains("none") && icon != string.Empty) 1030 { 1031 <span class="icon-auto"> 1032 @ReadFile(icon) 1033 </span> 1034 } 1035 } 1036 } 1037 @* END CUSTOM CODE *@