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