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