Error executing template "Designs/Swift/_parsed/Swift_Page.parsed.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): Access is denied
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetProductById(String productId, String productVariantId, String productLanguageId)
   at Dynamicweb.Ecommerce.Products.ProductService.FetchMissingProductsInternal(IProductRepository repo, IEnumerable`1 keys)
   at Dynamicweb.Caching.ServiceCache`2.GetCache(IEnumerable`1 keys)
   at Dynamicweb.Caching.ServiceCache`2.GetCache(TKey key)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId, User user, Boolean showUntranslated)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId, Boolean useAssortments)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId)
   at CompiledRazorTemplates.Dynamic.RazorEngine_aebde1cf66d540aca0a6b5d7eeb0dbcb.Execute() in D:\dynamicweb.net\Solutions\Dynamicweb\scrouples.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 419
   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()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:5,State:0,Class:20

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