Error executing template "Designs/Swift/_parsed/Swift_Page.parsed.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Dynamicweb.Content.Layouts.LayoutTemplateLocator.FindLayoutTemplateForPage(Page page)
   at Dynamicweb.Frontend.Content.GetLayoutForDevice(Page page, DeviceType device)
   at Dynamicweb.Frontend.Content.CreateGridContent(Int32 contentId, Boolean ignoreVisualEdit)
   at Dynamicweb.Frontend.Content.RenderExternalGrid(Int32 pageId, String container)
   at CompiledRazorTemplates.Dynamic.RazorEngine_3925bebf2efa49dbb992b84c1509de14.Execute() in D:\Solution\BKI LIVE\Files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 661
   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 S_DW_BKI_Swift.CustomModules.Helpers
  7     @using S_DW_BKI_Swift.CustomModules.Extensions;
  8     @using S_DW_BKI_Swift.CustomModules.TemplateHelpers
  9     
 10     @{
 11     	string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt");
 12     	bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase);
 13     	bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet;
 14     	string responsiveClassDesktop = string.Empty;
 15     	string responsiveClassMobile = string.Empty;
 16     	if (renderAsResponsive)
 17     	{
 18     		responsiveClassDesktop = " d-none d-xl-block";
 19     		responsiveClassMobile = " d-block d-xl-none";
 20     	}
 21     
 22     	var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default");
 23     
 24     	var brandingPageId = Model.Area.Item.GetLink("BrandingPage") != null ? Model.Area.Item.GetLink("BrandingPage").PageId : 0;
 25     	var themePageId = Model.Area.Item.GetLink("ThemesPage") != null ? Model.Area.Item.GetLink("ThemesPage").PageId : 0;
 26     	string customHeaderInclude = Model.Area.Item.GetFile("CustomHeaderInclude") != null ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty;
 27     
 28     	var brandingPage = Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null;
 29     	var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault();
 30     
 31     	var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt;
 32     	var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css"));
 33     
 34     
 35     	string productId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : "";
 36     	bool isProductDetailsPage = !string.IsNullOrEmpty(productId);
 37     	bool isArticlePage = Model.ItemType == "Swift_Article";
 38     	Dynamicweb.Content.PageService ps = new Dynamicweb.Content.PageService();
 39     	var page = ps.GetFirstPageForArea(Dynamicweb.Frontend.PageView.Current().AreaID);
 40     
 41     
 42     	bool isFrontpage = Dynamicweb.Frontend.PageView.Current().Page.ID == page.ID ? true : false;
 43     	var getSchemaParagraph = SchemaMarkupHelpers.GetParagraphById(Pageview, "ActivateSchema");
 44     	bool activateOrgSchema = getSchemaParagraph != null ? Convert.ToBoolean(getSchemaParagraph.Item["ShowOrganizationShema"]) : false;
 45     
 46     
 47     	bool showOrgSchema = false;
 48     	var customSettings = SchemaMarkupHelpers.GetCustomSettings(Pageview);
 49     
 50     	bool useSchema = false;
 51     	if (customSettings != null)
 52     	{
 53     		useSchema = customSettings.Item["ShowSchema"] != null ? Convert.ToBoolean(customSettings.Item["ShowSchema"]) : false;
 54     	}
 55     
 56     	string schemaOrgType = string.Empty;
 57     
 58     	if (isProductDetailsPage)
 59     	{
 60     		schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\"";
 61     	}
 62     
 63     	if (isArticlePage)
 64     	{
 65     		schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\"";
 66     	}
 67     
 68     	if (isFrontpage)
 69     	{
 70     		schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Organization\"";
 71     	}
 72     
 73     	if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt)
 74     	{
 75     		//Branding page has been saved or the file is missing. Rewrite the file to disc.
 76     		if (brandingPageId > 0)
 77     		{
 78     			var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId);
 79     			brandingPageview.Redirect = false;
 80     			brandingPageview.Output();
 81     		}
 82     	}
 83     
 84     	if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt)
 85     	{
 86     		//Branding page has been saved or the file is missing. Rewrite the file to disc.
 87     		if (themePageId > 0)
 88     		{
 89     			var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId);
 90     			themePageview.Redirect = false;
 91     			themePageview.Output();
 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.GetFile("Favicon") != null ? Model.Area.Item.GetFile("Favicon").Path : "/Files/Templates/Designs/Swift/Assets/Images/favicon.png";
101     
102     	string headerCssClass = "sticky-top";
103     	bool movePageBehind = false;
104     
105     	if (Pageview.Page.PropertyItem != null)
106     	{
107     		headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top";
108     		movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false;
109     	}
110     
111     	headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass;
112     	headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass;
113     
114     	string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID");
115     	string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID");
116     	var cookieOptInLevel = CookieManager.GetCookieOptInLevel();
117     	bool allowTracking = true;
118     
119     	Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;");
120     	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;");
121     	Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/aos.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
122     	Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
123     	//Dynamicweb.Context.Current.Response.Flush(); //This sends the headers where we are now in the rendering making the TTFB faster
124     
125     	SetMetaTags();
126     
127     	List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>();
128     
129     	if (Pageview.Area.IsMaster)
130     	{
131     		languages.Add(Pageview.Page);
132     		if (Pageview.Page.Languages != null)
133     		{
134     			foreach (var language in Pageview.Page.Languages)
135     			{
136     				languages.Add(language);
137     			}
138     		}
139     	}
140     	else
141     	{
142     		languages.Add(Pageview.Page.MasterPage);
143     		if (Pageview.Page.MasterPage != null)
144     		{
145     			if (Pageview.Page.MasterPage.Languages != null)
146     			{
147     				foreach (var language in Pageview.Page.MasterPage.Languages)
148     				{
149     					languages.Add(language);
150     				}
151     			}
152     		}
153     	}
154     
155     	string siteLanguage = Pageview.Area.CultureInfo.Name;
156     	Uri url = Dynamicweb.Context.Current.Request.Url;
157     	string hostName = url.Host; // domain.com/da-dk or domain.com/en-us
158     
159     	var ecomCountries = Dynamicweb.Ecommerce.Services.Countries.GetCountries();
160     	var ecomCurrencies = Dynamicweb.Ecommerce.Services.Currencies.GetAllCurrencies();
161     
162         // CUSTOM ADD START
163         string customHeadScripts = CustomSettingsHelper.GetSetting<string>("CustomHeadScripts");
164         string customBodyScripts = CustomSettingsHelper.GetSetting<string>("CustomBodyScripts");
165         bool renderCustomHeadScripts = !string.IsNullOrEmpty(customHeadScripts);
166         bool renderCustomBodyScripts = !string.IsNullOrEmpty(customBodyScripts);
167     
168         var currentPage = S_DW_BKI_Swift.CustomModules.Helpers.TemplateHelper.GetCurrentPage();
169         var isBCRpage = S_DW_BKI_Swift.CustomModules.Helpers.TemplateHelper.IsBCRPage(currentPage);
170         // CUSTOM ADD END
171     }
172     <!doctype html>
173     <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName">
174     <head>
175     	<!-- @swiftVersion -->
176     	@if (renderCustomHeadScripts)
177         {
178     		@customHeadScripts
179         }
180         @* Required meta tags *@
181         <meta charset="utf-8">
182         <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0">
183         <link rel="shortcut icon" href="@favicon">
184         @*custom edit start*@
185         @if (isFrontpage && useSchema || activateOrgSchema && useSchema)
186         {
187     		@SchemaMarkupHelpers.GetSchemaMarkupForOrganization(customSettings, Pageview)
188         }
189     
190     	@if (isArticlePage && useSchema)
191         {
192     		@SchemaMarkupHelpers.GetSchemaMarkupForArticle(customSettings, Pageview)
193     
194     	}
195     
196     	@if (isProductDetailsPage && useSchema)
197         {
198     		@SchemaMarkupHelpers.GetSchemaMarkupForProduct(customSettings, Pageview, productId)
199         }
200     
201     	@if (!string.IsNullOrEmpty(favicon))
202         {
203     		<link rel="apple-touch-icon" href="@favicon">
204         }
205     
206     
207     	@RenderSnippet("videoSchema")
208     	@RenderSnippet("recipeSchema")
209     	<link rel="canonical" href="@Pageview.GetCanonical()">
210     
211     @*Custom Scripts*@
212     	@{
213             var headscripts = Pageview.Page.PropertyItem != null && Pageview.Page.PropertyItem["HeadScripts"] != null ? Pageview.Page.PropertyItem["HeadScripts"].ToString() : "";
214     
215     
216             if (headscripts != null && !string.IsNullOrEmpty(headscripts.ToString()))
217             {
218                 @headscripts
219     
220             }
221     	}
222     
223     
224     	@*Add noindex nofollow on category pages but check first if added already*@
225     
226     	@if (!Model.MetaTags.Contains("<meta name=\"robots\" content=\"noindex,nofollow\">"))
227         {
228     		@RenderSnippet("robotsProductList")
229     		@Model.MetaTags
230     
231     
232         }
233         else
234         {
235     		@Model.MetaTags}
236     
237     
238     	@{
239             var alreadyWrittenTwoletterIsos = new List<string>();
240     		@* Languages meta data *@
241         foreach (var language in languages)
242         {
243             hostName = url.Host;
244             if (language?.Area != null)
245             {
246                 if (language.Area?.MasterArea != null && !string.IsNullOrEmpty(language.Area.MasterArea.DomainLock))
247                 {
248                     hostName = language.Area.MasterArea.DomainLock; //dk.domain.com or dk-domain.dk
249                 }
250                 if (language != null && language.Published && language.Area.Active && language.Area.Published)
251                 {
252                     if (!string.IsNullOrEmpty(language.Area.DomainLock))
253                     {
254                         hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk
255                     }
256                     string querystring = $"Default.aspx?ID={language.ID}";
257                     if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"]))
258                     {
259                         querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}";
260                     }
261                     if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"]))
262                     {
263                         querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}";
264                     }
265                     if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"]))
266                     {
267                         querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}";
268                     }
269     
270                     string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring);
271                     if (language.Area.RedirectFirstPage && language.ParentPageId == 0 && language.Sort == 1)
272                     {
273                         friendlyUrl = "/";
274                     }
275                     string href = $"{url.Scheme}://{hostName}{friendlyUrl}";
276     
277     
278     					<link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href">
279                     if (!alreadyWrittenTwoletterIsos.Contains(language.Area.CultureInfo.TwoLetterISOLanguageName))
280                     {
281     						<link rel="alternate" hreflang="@language.Area.CultureInfo.TwoLetterISOLanguageName.ToLower()" href="@href">
282                     }
283                 }
284             }
285         }
286     	}
287     
288     	<title>@Model.Title</title>
289     	@* Bootstrap + Swift stylesheet *@
290     	<link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css">
291     
292     	@if (disableWideBreakpoints != "disableBoth")
293         {
294     		<style>
295     			@@media ( min-width: 1600px ) {
296     				.container-xxl,
297     				.container-xl,
298     				.container-lg,
299     				.container-md,
300     				.container-sm,
301     				.container {
302     					max-width: 1520px;
303     				}
304     			}
305     		</style>
306     
307     
308     
309             if (disableWideBreakpoints != "disableUltraWideOnly")
310             {
311     			<style>
312     				@@media ( min-width: 1920px ) {
313     					.container-xxl,
314     					.container-xl,
315     					.container-lg,
316     					.container-md,
317     					.container-sm,
318     					.container {
319     						max-width: 1820px;
320     					}
321     				}
322     			</style>
323             }
324         }
325     
326     	@* Branding and Themes min stylesheet *@
327     	<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">
328     	<script src="/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
329     	<script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
330     
331     	<script type="module">
332     		AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') });
333     		swift.Scroll.hideHeadersOnScroll();
334     		swift.Scroll.handleAlternativeTheme();
335     	</script>
336     
337     	@* Google tag manager *@
338     	@if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking)
339         {
340     		<script>
341                 @if (!renderCustomHeadScripts)
342                 {
343                     <text>
344     		        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
345     		        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
346     		        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
347     		        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
348                     })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)');
349                     </text>
350                 }
351     
352                 function gtag() {
353                     if (dataLayer) {
354                         dataLayer.push(arguments);
355                     }
356                 }
357     		</script>
358         }
359     
360     	@if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
361         {
362             var GoogleAnalyticsDebugMode = "";
363             bool isLoggedInBackendUser = false;
364     
365     		if (Dynamicweb.Security.UserManagement.User.GetCurrentBackendUser() != null)
366     		{
367     			isLoggedInBackendUser = true;
368     		}
369     
370     		if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode") && isLoggedInBackendUser)
371     		{
372     			GoogleAnalyticsDebugMode = ", {'debug_mode': true}";
373     		}
374     
375     		<script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script>
376     		<script>
377     			window.dataLayer = window.dataLayer || [];
378                 function gtag() {
379                     if (dataLayer) {
380                         dataLayer.push(arguments);
381                     }
382                 }
383     			gtag('js', new Date());
384     			gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode);
385     		</script>
386         }
387     
388     	@if (!string.IsNullOrWhiteSpace(customHeaderInclude) && !isBCRpage)
389         {
390     		@RenderPartial($"Components/Custom/{customHeaderInclude}")
391         }
392     
393     	@if (isBCRpage)
394         {
395             <link rel="stylesheet" href=https://use.typekit.net/jbn6ewy.css>
396     	    <style>
397     		    main {
398     			    font-family: "tomarik-poster", sans-serif !important;
399     		    }
400     
401     			main h1, main h2, main h3, main h4, main h5, main h6,
402     			main .h1, main .h2, main .h3, main .h4, main .h5, main .h6,
403     			main .display-1, main .display-2, main .display-3,
404     			main .display-4, main .display-5, main .display-6 {
405     				font-family: "citrus-gothic-solid", sans-serif !important;
406     			}
407     
408     			@@font-face {
409     				font-family: 'Gotham Book';
410     				src: url('/Files/Templates/Designs/Swift/Assets/fonts/gotham-book.woff');
411     				font-weight: normal;
412     				font-style: normal;
413     			}
414     
415     			main .gotham h3, main .gotham p, main .gotham p span {
416     				text-align: center;
417     				font-weight: 600;
418     				font-style: normal;
419     				font-family: 'Gotham Book', sans-serif !important;
420     				--swift-font-family: 'Gotham Book', sans-serif !important;
421     			}
422     
423     			ul.slideralignement-left {
424     				justify-content: left;
425     			}
426     
427     			ul.slideralignement-center {
428     				justify-content: center;
429     			}
430     
431     			ul.slideralignement-right {
432     				justify-content: right;
433     			}
434     
435     
436     	    </style>
437         }
438     	@{
439     		Dictionary<int, string> labelList = new Dictionary<int, string>();
440     		var customSettingsItem = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "CustomSettings")?.Item;
441     		if (customSettingsItem != null)
442     		{
443     			labelList = CheckoutTemplateHelper.GetSignLabelItemList(customSettingsItem);
444     		}
445     	}
446     	<script>
447             window.Translations = {
448                 AddNewOrderLine: '@Translate("Add new order line")',
449                 WithDescription: "@Translate("With description")",
450                 WithoutDescription: "@Translate("Without description")",
451                 WithSign: "@Translate("With sign")",
452                 Sign: "@Translate("Sign")",
453                 Yes: "@Translate("Yes")",
454                 No: "@Translate("No")",
455                 None: "@Translate("None")",
456             };
457     
458     		window.POSMaterials = {};
459     		@foreach (var label in labelList)
460     		{
461     			<text>
462     				POSMaterials['@label.Key'] = "@label.Value";
463     			</text>
464     		}
465     
466     	</script>
467     </head>
468     <body class="brand @(masterTheme)" id="page@(Model.ID)">
469     	@* CUSTOM EDIT START *@
470     	@if (renderCustomBodyScripts)
471     	{
472     		@customBodyScripts
473     	}
474     	else
475     	{
476     		@* Google tag manager *@
477     		if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking)
478     		{
479     			<noscript>
480     				<iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)"
481     						height="0" width="0" style="display:none;visibility:hidden"></iframe>
482     			</noscript>
483     		}
484     	}
485     	@* CUSTOM EDIT END *@
486     
487     	@if (renderAsResponsive || !renderMobile)
488     	{
489     		<header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop">
490     			@if (@Model.Area.Item.GetLink("HeaderDesktop") != null)
491     			{
492     				@RenderGrid(@Model.Area.Item.GetLink("HeaderDesktop").PageId)
493     			}
494     		</header>
495     	}
496     
497     	@if ((renderAsResponsive || renderMobile))
498     	{
499     		<header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile">
500     			@if (@Model.Area.Item.GetLink("HeaderMobile") != null)
501     			{
502     				@RenderGrid(@Model.Area.Item.GetLink("HeaderMobile").PageId)
503     			}
504     		</header>
505     	}
506     
507     	<main id="content" @(schemaOrgType)>
508     		<div data-intersect></div>
509     		@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
510     @using System
511     @using Dynamicweb.Ecommerce.ProductCatalog
512     
513     
514     @{
515     	string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty;
516         bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && new[] { "shop", "shopanonymous" }.Contains(Pageview.Page.NavigationTag.ToLower()); // CUSTOM EDIT
517     
518     	bool isArticlePagePage = Model.ItemType == "Swift_Article";
519     	bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage";
520     	string schemaOrgProp = string.Empty;
521     	if(isArticlePagePage)
522     	{
523     		schemaOrgProp = "itemprop=\"articleBody\"";
524     	}
525     
526     	string theme = "";
527     	string gridContent = "";
528     
529     	if (Model.PropertyItem != null)
530     	{
531     		theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
532     	}
533     
534     	if (Model.Item != null || Pageview.IsVisualEditorMode)
535     	{
536     		if (!isProductDetail)
537     		{
538     			gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page");
539     		}
540     		else
541     		{
542     			var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId);
543     			var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty;
544     			var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage");
545     
546     			@RenderGrid(detailPageId)
547     		}
548     	}
549     
550     	bool doNotRenderPage = false;
551     
552     	//Check if we are on the poduct detail page, and if there is data to render
553     	ProductViewModel product = new ProductViewModel();
554     	if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
555     	{
556     		product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
557     		if (string.IsNullOrEmpty(product.Id)) {
558     			doNotRenderPage = true;
559     		}
560     	}
561     
562     	//Render the page
563     	if (!doNotRenderPage) {
564     		string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page";
565     		
566     
567     	<div class="@theme @itemIdentifier" @schemaOrgProp>
568     		@if (isArticleListPage)
569     		{					
570     			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\"";
571     			
572     			<form @hx id="ArticleFacetForm">
573     				@gridContent
574     			</form>
575     			<script type="module" src="/Files/Templates/Designs/Swift/Assets/js/htmx.js"></script>
576     			<script type="module">
577     				document.addEventListener('htmx:confirm', (event) => {
578     					let filters = event.detail.elt.querySelectorAll('select');
579     					for (var i = 0; i < filters.length; i++) {
580     						let input = filters[i];
581     						if (input.name && !input.value) {
582     							input.name = '';
583     						}
584     					}
585     				});
586     
587     				document.addEventListener('htmx:beforeOnLoad', (event) => {
588     					swift.Scroll.stopIntersectionObserver();
589     				});
590     
591     				document.addEventListener('htmx:afterOnLoad', () => {
592     					swift.Scroll.hideHeadersOnScroll();
593     					swift.Scroll.handleAlternativeTheme();
594     				});
595     			</script>
596     		}
597     		else
598     		{
599     			@gridContent
600     		}
601     	</div>
602     		
603     	} else {
604     		<div class="container">
605     			<div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div>
606     		</div>
607     	}
608     
609     	if (!Model.IsCurrentUserAllowed)
610     	{
611     		int signInPage = GetPageIdByNavigationTag("SignInPage");
612     		int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage");
613     
614     		if (!Pageview.IsVisualEditorMode)
615     		{
616     			if (signInPage != 0)
617     			{
618     				if (signInPage != Model.ID) {
619     					Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage);
620     				} else {
621     					if (dashboardPage != 0) {
622     						Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage);
623     					} else {
624     						Dynamicweb.Context.Current.Response.Redirect("/");
625     					}
626     				}
627     			}
628     			else
629     			{
630     				<div class="alert alert-dark m-0" role="alert">
631     					<span>@Translate("You do not have access to this page")</span>
632     				</div>
633     			}
634     		}
635     		else
636     		{
637     			<div class="alert alert-dark m-0" role="alert">
638     				<span>@Translate("To work on this page, you must be signed in, in the frontend")</span>
639     			</div>
640     		}
641     	}
642     }
643     
644     	</main>
645     
646     	@if (renderAsResponsive || !renderMobile)
647     	{
648     		<footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop">
649     			@if (@Model.Area.Item.GetLink("FooterDesktop") != null)
650     			{
651     				@RenderGrid(@Model.Area.Item.GetLink("FooterDesktop").PageId)
652     			}
653     		</footer>
654     	}
655     
656     	@if (renderAsResponsive || renderMobile)
657     	{
658     		<footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile">
659     			@if (@Model.Area.Item.GetLink("FooterMobile") != null)
660     			{
661     				@RenderGrid(@Model.Area.Item.GetLink("FooterMobile").PageId)
662     			}
663     		</footer>
664     	}
665     
666     	@* Render any offcanvas menu here *@
667     	@RenderSnippet("offcanvas")
668     
669     	@{
670     		bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]);
671     	}
672     
673     	@* Language selector modal *@
674     	@if (languages.Count > 1 || ecomCountries.Count > 1 || ecomCurrencies.Count() > 1)
675     	{
676     		<div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true">
677     			<div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent">
678     				@* The content here comes from an external request *@
679     			</div>
680     		</div>
681     	}
682     
683     	@* Favorite toast *@
684     	<div aria-live="polite" aria-atomic="true">
685     		<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
686     			<div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
687     				<div class="toast-header">
688     					<strong class="me-auto">@Translate("Favorite list updated")</strong>
689     					<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
690     				</div>
691     				<div class="toast-body d-flex gap-3">
692     					<div id="favoriteNotificationToast_Image"></div>
693     					<div id="favoriteNotificationToast_Text"></div>
694     				</div>
695     			</div>
696     		</div>
697     	</div>
698     
699     	@* Modal for dynamic content *@
700     	<div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true">
701     		<div class="modal-dialog modal-dialog-centered modal-md">
702     			<div class="modal-content theme light" id="DynamicModalContent">
703     				@* The content here comes from an external request *@
704     			</div>
705     		</div>
706     	</div>
707     
708     	@* Offcanvas for dynamic content *@
709     	<div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas" style="width: 30rem">
710     		@* The content here comes from an external request *@
711     	</div>
712     
713     	@if (isErpConnectionDown && Model.Area.Item.GetBoolean("ShowErpDownMessage"))
714     	{
715     		string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light";
716     
717     		<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040">
718     			<div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true">
719     				<div class="toast-header">
720     					<strong class="me-auto">@Translate("Connection down")</strong>
721     					<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
722     				</div>
723     				<div class="toast-body">
724     					@Translate("We are experiencing some connectivity issues. Not all features may be available to you.")
725     				</div>
726     			</div>
727     		</div>
728     	}
729     </body>
730     </html>
731     @functions {
732     	void SetMetaTags()
733     	{
734     		//Verification Tokens
735     		string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : "";
736     		//string siteVerificationYandex = Model.Area.Item.GetString("Yandex_Verification") != null ? Model.Area.Item.GetString("Yandex_Verification") : "";
737     		//string siteVerificationMS = Model.Area.Item.GetString("Msvalidate_01") != null ? Model.Area.Item.GetString("Msvalidate_01") : "";
738     		//string siteVerificationAlexa = Model.Area.Item.GetString("AlexaVerifyID") != null ? Model.Area.Item.GetString("AlexaVerifyID") : "";
739     		//string siteVerificationPinterest = Model.Area.Item.GetString("P_domain_verify") != null ? Model.Area.Item.GetString("P_domain_verify") : "";
740     		//string siteVerificationNorton = Model.Area.Item.GetString("Norton_safeweb_site_verification") != null ? Model.Area.Item.GetString("Norton_safeweb_site_verification") : "";
741     
742     		//Generic Site Values
743     		string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : "";
744     		string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : "";
745     		string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : "";
746     
747     		string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : "";
748     
749     		//Page specific values
750     		string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : "";
751     		FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image");
752     		string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : "";
753     		string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : "";
754     
755     		string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : "";
756     		string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : "";
757     		string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : "";
758     		FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image");
759     		string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : "";
760     
761     		if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"]))
762     		{
763     			if (!string.IsNullOrEmpty(Model.Description))
764     			{
765     				Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{Model.Description}\" />");
766     			}
767     			else
768     			{
769     				Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{openGraphDescription}\" />");
770     			}
771     
772     			if (!string.IsNullOrEmpty(Pageview.Page.TopImage))
773     			{
774     				Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}\" />");
775     				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}\" />");
776     			}
777     			else if (openGraphImage != null)
778     			{
779     				Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\" />");
780     				Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\" />");
781     			}
782     
783     			if (!string.IsNullOrEmpty(openGraphImageALT))
784     			{
785     				Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{openGraphImageALT}\"/>");
786     			}
787     			if (!string.IsNullOrEmpty(twitterCardDescription))
788     			{
789     				Pageview.Meta.AddTag("twitter:description", twitterCardDescription);
790     			}
791     
792     			if (!string.IsNullOrEmpty(Pageview.Page.TopImage))
793     			{
794     				Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}");
795     			}
796     			else if (twitterCardImage != null)
797     			{
798     				Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}");
799     			}
800     
801     			if (!string.IsNullOrEmpty(twitterCardImageALT))
802     			{
803     				Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT);
804     			}
805     		}
806     
807     		if (!string.IsNullOrEmpty(siteVerificationGoogle))
808     		{
809     			Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle);
810     		}
811     
812     		if (!string.IsNullOrEmpty(openGraphFacebookAppID))
813     		{
814     			Pageview.Meta.AddTag($"<meta property=\"fb:app_id\" content=\"{openGraphFacebookAppID}\" />");
815     		}
816     
817     		if (!string.IsNullOrEmpty(openGraphType))
818     		{
819     			Pageview.Meta.AddTag($"<meta property=\"og:type\" content=\"{openGraphType}\" />");
820     		}
821     
822     		if (!string.IsNullOrEmpty(openGraphSiteName))
823     		{
824     			Pageview.Meta.AddTag($"<meta property=\"og:url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Pageview.SearchFriendlyUrl}\" />");
825     		}
826     
827     		if (!string.IsNullOrEmpty(openGraphSiteName))
828     		{
829     			Pageview.Meta.AddTag($"<meta property=\"og:site_name\" content=\"{openGraphSiteName}\" />");
830     		}
831     
832     		if (!string.IsNullOrEmpty(Model.Title))
833     		{
834     			Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{Model.Title}\"/>");
835     		}
836     		else
837     		{
838     			Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{openGraphSiteTitle}\" />");
839     		}
840     
841     		if (!string.IsNullOrEmpty(twitterCardSite))
842     		{
843     			Pageview.Meta.AddTag("twitter:site", twitterCardSite);
844     		}
845     
846     		if (!string.IsNullOrEmpty(twitterCardURL))
847     		{
848     			Pageview.Meta.AddTag("twitter:url", twitterCardURL);
849     		}
850     
851     		if (!string.IsNullOrEmpty(twitterCardTitle))
852     		{
853     			Pageview.Meta.AddTag("twitter:title", twitterCardTitle);
854     		}
855     	}
856     }
857