Error executing template "Designs/Swift/_parsed/Swift_Page_custom.parsed.cshtml"
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int16.Parse(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToInt16(String value)
   at CompiledRazorTemplates.Dynamic.RazorEngine_636483fc7ad74cf098455f0b86ae3e07.Execute() in D:\dynamicweb.net\Solutions\Novicell\awintherbikes.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\_parsed\Swift_Page_custom.parsed.cshtml:line 396
   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 @using Dynamicweb.Core 7 @using System.Web 8 9 @{ 10 string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt"); 11 bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase); 12 bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet; 13 string responsiveClassDesktop = string.Empty; 14 string responsiveClassMobile = string.Empty; 15 16 int? betterAreaId = Winther.Website.Helpers.Helpers.BetterAreaExists(); 17 18 if (renderAsResponsive) 19 { 20 responsiveClassDesktop = " d-none d-xl-block"; 21 responsiveClassMobile = " d-block d-xl-none"; 22 } 23 24 var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default"); 25 26 var brandingPageId = Model.Area.Item.GetLink("BrandingPage") != null ? Model.Area.Item.GetLink("BrandingPage").PageId : 0; 27 var themePageId = Model.Area.Item.GetLink("ThemesPage") != null ? Model.Area.Item.GetLink("ThemesPage").PageId : 0; 28 string customHeaderInclude = Model.Area.Item.GetFile("CustomHeaderInclude") != null ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty; 29 30 var brandingPage = Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null; 31 var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 32 33 var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt; 34 var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css")); 35 36 // Schema.org details for PDP 37 string productId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : ""; 38 bool isProductDetailsPage = !string.IsNullOrEmpty(productId); 39 bool isArticlePage = Model.ItemType == "Swift_Article"; 40 string schemaOrgType = string.Empty; 41 42 if (isProductDetailsPage) 43 { 44 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\""; 45 } 46 47 if (isArticlePage) 48 { 49 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\""; 50 } 51 52 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt) 53 { 54 //Branding page has been saved or the file is missing. Rewrite the file to disc. 55 if (brandingPageId > 0) 56 { 57 var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId); 58 brandingPageview.Redirect = false; 59 brandingPageview.Output(); 60 } 61 } 62 63 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt) 64 { 65 //Branding page has been saved or the file is missing. Rewrite the file to disc. 66 if (themePageId > 0) 67 { 68 var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId); 69 themePageview.Redirect = false; 70 themePageview.Output(); 71 } 72 } 73 74 var cssStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/styles.css")); 75 var jsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/scripts.js")); 76 77 string masterTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("Theme")) ? " theme " + Model.Area.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 78 79 string favicon = Model.Area.Item.GetFile("Favicon") != null ? Model.Area.Item.GetFile("Favicon").Path : "/Files/Templates/Designs/Swift/Assets/Images/favicon.png"; 80 81 string headerCssClass = "sticky-top"; 82 bool movePageBehind = false; 83 84 if (Pageview.Page.PropertyItem != null) 85 { 86 headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top"; 87 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 88 } 89 90 headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass; 91 headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass; 92 93 string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID"); 94 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID"); 95 96 bool allowTracking = true; 97 if (CookieManager.IsCookieManagementActive) 98 { 99 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 100 allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 101 } 102 103 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;"); 104 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;"); 105 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/aos.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;"); 106 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;"); 107 //Dynamicweb.Context.Current.Response.Flush(); //This sends the headers where we are now in the rendering making the TTFB faster 108 109 SetMetaTags(); 110 111 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>(); 112 113 if (Pageview.Area.IsMaster) 114 { 115 languages.Add(Pageview.Page); 116 if (Pageview.Page.Languages != null) 117 { 118 foreach (var language in Pageview.Page.Languages) 119 { 120 languages.Add(language); 121 } 122 } 123 } 124 else 125 { 126 languages.Add(Pageview.Page.MasterPage); 127 if (Pageview.Page.MasterPage != null) 128 { 129 if (Pageview.Page.MasterPage.Languages != null) 130 { 131 foreach (var language in Pageview.Page.MasterPage.Languages) 132 { 133 languages.Add(language); 134 } 135 } 136 } 137 } 138 139 string siteLanguage = Pageview.Area.CultureInfo.Name; 140 Uri url = Dynamicweb.Context.Current.Request.Url; 141 string hostName = url.Host; // domain.com/da-dk or domain.com/en-us 142 143 var ecomCountries = Dynamicweb.Ecommerce.Services.Countries.GetCountries(); 144 var ecomCurrencies = Dynamicweb.Ecommerce.Services.Currencies.GetAllCurrencies(); 145 146 // Custom settings 147 string embed = Model.Area.Item.GetString("Embed"); 148 149 //Language redirect WINTHER-83 150 string name = "WintherSiteSelection"; 151 int siteSelectionCookie; 152 153 //Take value from quarystring and update cookie value 154 if (HttpContext.Current.Request.QueryString.AllKeys.Any(x => x == name)) 155 { 156 var siteSelectionQuery = HttpContext.Current.Request.QueryString.GetValues(name).FirstOrDefault(); 157 if (HttpContext.Current.Request.Cookies.AllKeys.Contains(name) && !string.IsNullOrEmpty(siteSelectionQuery)) 158 { 159 HttpContext.Current.Request.Cookies[name].Value = siteSelectionQuery; 160 } 161 162 HttpContext.Current.Response.Redirect("/Default.aspx?AreaID=" + siteSelectionQuery); 163 } 164 165 //Get site selection cookie 166 if (HttpContext.Current.Request.Cookies.AllKeys.Contains(name)) 167 { 168 siteSelectionCookie = Int32.Parse(HttpContext.Current.Request.Cookies[name].Value.ToString()); 169 } 170 else 171 { 172 siteSelectionCookie = 0; 173 } 174 175 //Redirect to selected site if site selection cookie is set 176 if (siteSelectionCookie != 0) 177 { 178 if (Pageview.AreaID != siteSelectionCookie) 179 { 180 HttpContext.Current.Response.Redirect("/Default.aspx?AreaID=" + siteSelectionCookie.ToString()); 181 } 182 } 183 } 184 <!doctype html> 185 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName"> 186 <head> 187 <!-- @swiftVersion --> 188 @* Required meta tags *@ 189 <meta charset="utf-8"> 190 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0"> 191 <link rel="shortcut icon" href="@favicon"> 192 <link rel="apple-touch-icon" href="@favicon"> 193 194 @Model.MetaTags 195 196 @{ 197 @* Languages meta data *@ 198 foreach (var language in languages) 199 { 200 if (language?.Area != null) 201 { 202 if (language != null && language.Published && language.Active && language.Area.Active && language.Area.Published && language.Area.ID != Dynamicweb.Frontend.PageView.Current().AreaID) 203 { 204 if (!string.IsNullOrEmpty(language.Area.DomainLock)) 205 { 206 hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk 207 } 208 string querystring = $"Default.aspx?ID={language.ID}"; 209 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"])) 210 { 211 querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}"; 212 } 213 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 214 { 215 querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}"; 216 } 217 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"])) 218 { 219 querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}"; 220 } 221 222 string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring); 223 string href = $"{url.Scheme}://{hostName}{friendlyUrl}"; 224 225 <link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href"> 226 } 227 } 228 } 229 } 230 231 <title>@Model.Title</title> 232 @* Bootstrap + Swift stylesheet *@ 233 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 234 235 @if (disableWideBreakpoints != "disableBoth") 236 { 237 <style> 238 @@media ( min-width: 1600px ) { 239 .container-xxl, 240 .container-xl, 241 .container-lg, 242 .container-md, 243 .container-sm, 244 .container { 245 max-width: 1520px; 246 } 247 } 248 </style> 249 250 251 252 if (disableWideBreakpoints != "disableUltraWideOnly") 253 { 254 <style> 255 @@media ( min-width: 1920px ) { 256 .container-xxl, 257 .container-xl, 258 .container-lg, 259 .container-md, 260 .container-sm, 261 .container { 262 max-width: 1820px; 263 } 264 } 265 </style> 266 } 267 } 268 269 @* Branding and Themes min stylesheet *@ 270 <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"> 271 <script src="/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks" defer></script> 272 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks" defer></script> 273 274 <script type="module"> 275 AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') }); 276 swift.Scroll.hideHeadersOnScroll(); 277 swift.Scroll.handleAlternativeTheme(); 278 </script> 279 280 @* Google tag manager *@ 281 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking) 282 { 283 <script> 284 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 285 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 286 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 287 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 288 })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)'); 289 290 function gtag() { dataLayer.push(arguments); } 291 </script> 292 } 293 294 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) 295 { 296 var GoogleAnalyticsDebugMode = ""; 297 bool isLoggedInBackendUser = false; 298 299 if (Dynamicweb.Security.UserManagement.User.GetCurrentBackendUser() != null) 300 { 301 isLoggedInBackendUser = true; 302 } 303 304 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode") && isLoggedInBackendUser) 305 { 306 GoogleAnalyticsDebugMode = ", {'debug_mode': true}"; 307 } 308 309 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script> 310 <script> 311 window.dataLayer = window.dataLayer || []; 312 function gtag() { dataLayer.push(arguments); } 313 gtag('js', new Date()); 314 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode); 315 </script> 316 } 317 318 @if (!string.IsNullOrWhiteSpace(customHeaderInclude)) 319 { 320 @RenderPartial($"Components/Custom/{customHeaderInclude}") 321 } 322 323 @*_custom start*@ 324 <link href="assets/styles/main-min.css" rel="stylesheet" media="all" type="text/css"> 325 <script src="assets/scripts/main-min.js" defer></script> 326 @*_custom end*@ 327 </head> 328 <body class="brand @(masterTheme)" id="page@(Model.ID)"> 329 330 @* Google tag manager *@ 331 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking) 332 { 333 <noscript> 334 <iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)" 335 height="0" width="0" style="display:none;visibility:hidden"></iframe> 336 </noscript> 337 } 338 339 @if (renderAsResponsive || !renderMobile) 340 { 341 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop"> 342 @if (@Model.Area.Item.GetLink("HeaderDesktop") != null) 343 { 344 @RenderGrid(@Model.Area.Item.GetLink("HeaderDesktop").PageId) 345 } 346 </header> 347 } 348 349 @if ((renderAsResponsive || renderMobile)) 350 { 351 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile"> 352 @if (@Model.Area.Item.GetLink("HeaderMobile") != null) 353 { 354 @RenderGrid(@Model.Area.Item.GetLink("HeaderMobile").PageId) 355 } 356 </header> 357 } 358 359 <main id="content" @(schemaOrgType)> 360 <div data-intersect></div> 361 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 362 @using System 363 @using Dynamicweb.Ecommerce.ProductCatalog 364 365 366 @{ 367 string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty; 368 bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop"; 369 370 bool isArticlePagePage = Model.ItemType == "Swift_Article"; 371 bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage"; 372 string schemaOrgProp = string.Empty; 373 if (isArticlePagePage) 374 { 375 schemaOrgProp = "itemprop=\"articleBody\""; 376 } 377 378 string theme = ""; 379 string gridContent = ""; 380 381 if (Model.PropertyItem != null) 382 { 383 theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 384 } 385 386 if (Model.Item != null || Pageview.IsVisualEditorMode) 387 { 388 if (!isProductDetail) 389 { 390 gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page"); 391 } 392 else 393 { 394 var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId); 395 var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty; 396 var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage"); 397 398 @RenderGrid(detailPageId) 399 } 400 } 401 402 bool doNotRenderPage = false; 403 404 //Check if we are on the poduct detail page, and if there is data to render 405 ProductViewModel product = new ProductViewModel(); 406 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 407 { 408 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 409 if (string.IsNullOrEmpty(product.Id)) 410 { 411 doNotRenderPage = true; 412 } 413 } 414 415 //Render the page 416 if (!doNotRenderPage) 417 { 418 string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page"; 419 420 421 <div class="@theme @itemIdentifier" @schemaOrgProp> 422 @if (isArticleListPage) 423 { 424 var hx = $"hx-get=\"{Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(Model.ID)}\" hx-select=\"#content\" hx-target=\"#content\" hx-swap=\"outerHTML\" hx-trigger=\"change\" hx-headers='{{\"feed\": \"true\"}}' hx-push-url=\"true\" hx-indicator=\"#ArticleFacetForm\""; 425 426 <form @hx id="ArticleFacetForm"> 427 @gridContent 428 </form> 429 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/htmx.js"></script> 430 <script type="module"> 431 document.addEventListener('htmx:confirm', (event) => { 432 let filters = event.detail.elt.querySelectorAll('select'); 433 for (var i = 0; i < filters.length; i++) { 434 let input = filters[i]; 435 if (input.name && !input.value) { 436 input.name = ''; 437 } 438 } 439 }); 440 441 document.addEventListener('htmx:beforeOnLoad', (event) => { 442 swift.Scroll.stopIntersectionObserver(); 443 }); 444 445 document.addEventListener('htmx:afterOnLoad', () => { 446 swift.Scroll.hideHeadersOnScroll(); 447 swift.Scroll.handleAlternativeTheme(); 448 }); 449 </script> 450 } 451 else 452 { 453 @gridContent 454 } 455 </div> 456 457 } 458 else 459 { 460 <div class="container"> 461 <div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div> 462 </div> 463 } 464 465 if (!Model.IsCurrentUserAllowed) 466 { 467 int signInPage = GetPageIdByNavigationTag("SignInPage"); 468 int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage"); 469 470 if (!Pageview.IsVisualEditorMode) 471 { 472 if (signInPage != 0) 473 { 474 if (signInPage != Model.ID) 475 { 476 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage); 477 } 478 else 479 { 480 if (dashboardPage != 0) 481 { 482 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage); 483 } 484 else 485 { 486 Dynamicweb.Context.Current.Response.Redirect("/"); 487 } 488 } 489 } 490 else 491 { 492 <div class="alert alert-dark m-0" role="alert"> 493 <span>@Translate("You do not have access to this page")</span> 494 </div> 495 } 496 } 497 else 498 { 499 <div class="alert alert-dark m-0" role="alert"> 500 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span> 501 </div> 502 } 503 } 504 } 505 506 </main> 507 508 @if (renderAsResponsive || !renderMobile) 509 { 510 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop"> 511 @if (@Model.Area.Item.GetLink("FooterDesktop") != null) 512 { 513 @RenderGrid(@Model.Area.Item.GetLink("FooterDesktop").PageId) 514 } 515 </footer> 516 } 517 518 @if (renderAsResponsive || renderMobile) 519 { 520 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile"> 521 @if (@Model.Area.Item.GetLink("FooterMobile") != null) 522 { 523 @RenderGrid(@Model.Area.Item.GetLink("FooterMobile").PageId) 524 } 525 </footer> 526 } 527 528 @* Render any offcanvas menu here *@ 529 @RenderSnippet("offcanvas") 530 531 @{ 532 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]); 533 } 534 535 @* Language selector modal - WINTHER-83 *@ 536 @if (languages.Count > 1 || ecomCountries.Count > 1 || ecomCurrencies.Count() > 1) 537 { 538 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true"> 539 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent"> 540 @* The content here comes from an external request *@ 541 </div> 542 </div> 543 544 <script> 545 //Add cookie and redirect 546 function setAreaID(areaId) { 547 548 var today = new Date(); 549 var newDate = new Date(today.setMonth(today.getMonth() + 1)); 550 var dd = String(newDate.getDate()).padStart(2, '0'); 551 var mm = String(newDate.getMonth() + 1).padStart(2, '0'); //January is 0! 552 var yyyy = newDate.getFullYear(); 553 newDate = mm + '/' + dd + '/' + yyyy; 554 newDate = new Date(newDate).toUTCString(); 555 556 //update cookie domain 557 const url = window.location.host; 558 const index = url.indexOf("."); 559 const filteredUrl = url.substring(index); 560 561 document.cookie = "WintherSiteSelection=" + areaId + "; expires=" + newDate + ";domain=" + filteredUrl + ";path=/"; 562 window.location.assign("/Default.aspx?AreaID=" + areaId + "&" + "@name" + "=" + areaId) 563 } 564 565 let modal = document.getElementById("SiteSelectionModal"); 566 let cookieAreaID = @siteSelectionCookie; 567 let betterAreaID = "@betterAreaId"; 568 569 //Toggle modal if no cookie with area id 570 if (betterAreaID != "" && cookieAreaID == 0) { 571 document.addEventListener('DOMContentLoaded', function () { 572 document.querySelector('button[data-bs-target="#PreferencesModal"]').click(); 573 }); 574 } 575 </script> 576 } 577 578 @* Favorite toast *@ 579 <div aria-live="polite" aria-atomic="true"> 580 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11"> 581 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> 582 <div class="toast-header"> 583 <strong class="me-auto">@Translate("Favorite list updated")</strong> 584 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 585 </div> 586 <div class="toast-body d-flex gap-3"> 587 <div id="favoriteNotificationToast_Image"></div> 588 <div id="favoriteNotificationToast_Text"></div> 589 </div> 590 </div> 591 </div> 592 </div> 593 594 @* Modal for dynamic content *@ 595 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true"> 596 <div class="modal-dialog modal-dialog-centered modal-md"> 597 <div class="modal-content theme light" id="DynamicModalContent"> 598 @* The content here comes from an external request *@ 599 </div> 600 </div> 601 </div> 602 603 @* Offcanvas for dynamic content *@ 604 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas" style="width: 30rem"> 605 @* The content here comes from an external request *@ 606 </div> 607 608 @if (isErpConnectionDown && Model.Area.Item.GetBoolean("ShowErpDownMessage")) 609 { 610 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light"; 611 612 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040"> 613 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true"> 614 <div class="toast-header"> 615 <strong class="me-auto">@Translate("Connection down")</strong> 616 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 617 </div> 618 <div class="toast-body"> 619 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.") 620 </div> 621 </div> 622 </div> 623 } 624 @if (!string.IsNullOrEmpty(embed)) 625 { 626 <!-- Embed --> 627 @embed 628 } 629 </body> 630 </html> 631 @functions { 632 void SetMetaTags() 633 { 634 //Verification Tokens 635 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : ""; 636 //string siteVerificationYandex = Model.Area.Item.GetString("Yandex_Verification") != null ? Model.Area.Item.GetString("Yandex_Verification") : ""; 637 //string siteVerificationMS = Model.Area.Item.GetString("Msvalidate_01") != null ? Model.Area.Item.GetString("Msvalidate_01") : ""; 638 //string siteVerificationAlexa = Model.Area.Item.GetString("AlexaVerifyID") != null ? Model.Area.Item.GetString("AlexaVerifyID") : ""; 639 //string siteVerificationPinterest = Model.Area.Item.GetString("P_domain_verify") != null ? Model.Area.Item.GetString("P_domain_verify") : ""; 640 //string siteVerificationNorton = Model.Area.Item.GetString("Norton_safeweb_site_verification") != null ? Model.Area.Item.GetString("Norton_safeweb_site_verification") : ""; 641 642 //Generic Site Values 643 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : ""; 644 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : ""; 645 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : ""; 646 647 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : ""; 648 649 //Page specific values 650 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : ""; 651 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image"); 652 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : ""; 653 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : ""; 654 655 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : ""; 656 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : ""; 657 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : ""; 658 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image"); 659 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : ""; 660 661 if (!string.IsNullOrEmpty(siteVerificationGoogle)) 662 { 663 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle); 664 } 665 666 if (!string.IsNullOrEmpty(openGraphFacebookAppID)) 667 { 668 Pageview.Meta.AddTag("fb:app_id", openGraphFacebookAppID); 669 } 670 671 if (!string.IsNullOrEmpty(openGraphType)) 672 { 673 Pageview.Meta.AddTag("og:type", openGraphType); 674 } 675 676 if (!string.IsNullOrEmpty(openGraphSiteName)) 677 { 678 Pageview.Meta.AddTag("og:site_name", openGraphSiteName); 679 } 680 681 if (!string.IsNullOrEmpty(Model.Title)) 682 { 683 Pageview.Meta.AddTag("og:title", Model.Title); 684 } 685 else 686 { 687 Pageview.Meta.AddTag("og:title", openGraphSiteTitle); 688 } 689 690 if (!string.IsNullOrEmpty(Pageview.Page.TopImage) && openGraphImage == null) 691 { 692 Pageview.Meta.AddTag("og:image", Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + Pageview.Page.TopImage); 693 } 694 695 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 696 { 697 if (!string.IsNullOrEmpty(Model.Description)) 698 { 699 Pageview.Meta.AddTag("og:description", Model.Description); 700 } 701 else 702 { 703 Pageview.Meta.AddTag("og:description", openGraphDescription); 704 } 705 if (openGraphImage != null) 706 { 707 Pageview.Meta.AddTag("og:image", openGraphImage.Path); 708 } 709 710 if (!string.IsNullOrEmpty(openGraphImageALT)) 711 { 712 Pageview.Meta.AddTag("og:image:alt", openGraphImageALT); 713 } 714 if (!string.IsNullOrEmpty(twitterCardDescription)) 715 { 716 Pageview.Meta.AddTag("twitter:description", twitterCardDescription); 717 } 718 719 if (twitterCardImage != null) 720 { 721 Pageview.Meta.AddTag("twitter:image", twitterCardImage.Path); 722 } 723 724 if (!string.IsNullOrEmpty(twitterCardImageALT)) 725 { 726 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT); 727 } 728 } 729 730 if (!string.IsNullOrEmpty(twitterCardSite)) 731 { 732 Pageview.Meta.AddTag("twitter:site", twitterCardSite); 733 } 734 735 if (!string.IsNullOrEmpty(twitterCardURL)) 736 { 737 Pageview.Meta.AddTag("twitter:url", twitterCardURL); 738 } 739 740 if (!string.IsNullOrEmpty(twitterCardTitle)) 741 { 742 Pageview.Meta.AddTag("twitter:title", twitterCardTitle); 743 } 744 } 745 } 746