Error executing template "Designs/Swift/Swift_Page.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 specified network name is no longer available
   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.DetailRepository.GetDefaultImage(String productId, String productVariantId, String productLanguageId, String detailType)
   at Dynamicweb.Ecommerce.Products.DetailService.GetDefaultDetail(String productId, String productVariantId, String languageId, IList`1 details)
   at Dynamicweb.Ecommerce.Products.ProductImageService.GetImagePath(Product product, List`1 details, Boolean ignoreNoPictureSetting, Shop shop)
   at Dynamicweb.Ecommerce.Products.ProductImageService.GetImagePath(Product product)
   at CompiledRazorTemplates.Dynamic.RazorEngine_7d1fca181aac4722939548360dfc71bb.SetMetaTags() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Swift_Page.cshtml:line 1204
   at CompiledRazorTemplates.Dynamic.RazorEngine_7d1fca181aac4722939548360dfc71bb.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Swift_Page.cshtml:line 267
   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:64,State:0,Class:20

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 2 @using System 3 @using System.Web 4 @using Dynamicweb 5 @using Dynamicweb.Environment 6 @using Dynamicweb.Frontend 7 @using NextechDWAddIn.Common 8 9 @using NextechDWAddIn.Helpers 10 @using NextechDWAddIn.AWSCognito 11 12 @functions { 13 string GetCookieOptInPermission(string category) 14 { 15 bool categoryOrAllGranted = false; 16 17 if (CookieManager.IsCookieManagementActive) 18 { 19 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 20 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 21 categoryOrAllGranted = cookieOptInCategories.Contains(category) || cookieOptInLevel == CookieOptInLevel.All; 22 } 23 24 return categoryOrAllGranted ? "granted" : "denied"; 25 } 26 27 bool AllowTracking() 28 { 29 bool allowTracking = true; 30 if (CookieManager.IsCookieManagementActive) 31 { 32 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 33 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 34 35 bool consentEither = (cookieOptInCategories.Contains("Statistical") || cookieOptInCategories.Contains("Marketing")); 36 bool consentFunctional = cookieOptInLevel == CookieOptInLevel.Functional; 37 bool consentAtLeastOne = cookieOptInLevel == CookieOptInLevel.All || (consentFunctional && consentEither); 38 39 allowTracking = consentAtLeastOne; 40 } 41 return allowTracking; 42 } 43 } 44 45 @{ 46 var cartSummaryPageId = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Model.Area.ID, "CartSummary")?.ID; 47 bool enableMiniCart = Model.Area.Item?.GetBoolean("EnableOffcanvasMiniCart") ?? false; 48 var offcanvasMiniCartBehaviour = Model.Area.Item?.GetRawValueString("OffcanvasMinicartBehaviour", "3") ?? "3"; 49 bool miniCartEnabled = cartSummaryPageId != null && enableMiniCart; 50 var brandingPageId = Model.Area.Item?.GetInt32("BrandingPage") ?? 0; 51 var themePageId = Model.Area.Item?.GetInt32("ThemesPage") ?? 0; 52 var cssPageId = Model.Area.Item?.GetInt32("CssPage") ?? 0; 53 var brandingPage = brandingPageId != 0 ? Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null : null; 54 var themesParagraphs = themePageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(themePageId) ?? null : null; 55 var cssParagraphs = cssPageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(cssPageId) ?? null : null; 56 string currentLanguageTwoLetter = ExecutingContext.GetCulture(true).TwoLetterISOLanguageName; 57 58 59 60 61 62 //CS NT Autologin cookie 20251105.. 63 if(Pageview.User == null) 64 { 65 var sessioncookie = CookieManager.GetCookie("DW_Extranet"); 66 if (sessioncookie is object && sessioncookie != null) 67 { 68 string DWExtranetUsername = sessioncookie["DWExtranetUsername"]; 69 string DWExtranetTkn = sessioncookie["DWExtranetTkn"]; 70 //Logger.Instance.Log(ErrorLevel.DebugInfo, $"Swift_Master.cshtml DWExtranetUsername: {DWExtranetUsername} DWExtranetTkn: {DWExtranetTkn}"); 71 if (!string.IsNullOrWhiteSpace(DWExtranetUsername) && !string.IsNullOrWhiteSpace(DWExtranetTkn)) 72 { 73 var logOnHandler = new Dynamicweb.Frontend.LogOnHandler(); 74 logOnHandler.LogOnWithToken(DWExtranetUsername, DWExtranetTkn); 75 if (HttpContext.Current.Request != null && HttpContext.Current.Request.RawUrl != null) 76 { 77 //Logger.Instance.Log(ErrorLevel.DebugInfo, $"Swift_Master.cshtml HttpContext.Current.Request.RawUrl: {HttpContext.Current.Request.RawUrl}"); 78 HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl); 79 } 80 } 81 } 82 } 83 //..CS NT Autologin cookie 20251105 84 85 86 87 //CS NT 20251121 88 89 string redirectURL_cognito = ""; 90 try 91 { 92 if(Pageview == null || Pageview.User == null) 93 { 94 string authURL = HttpCookieHelper.GetHttpCookie("AWS_AuthURL"); 95 if (string.IsNullOrWhiteSpace(authURL)) 96 { 97 var openIdConfiguration = AWSCognito.GetOpenIdConfiguration(); 98 if (openIdConfiguration != null && openIdConfiguration.authorization_endpoint != null) 99 { 100 authURL = openIdConfiguration.authorization_endpoint; 101 HttpCookieHelper.SetHttpCookie("AWS_AuthURL", authURL); 102 } 103 } 104 //Logger.Instance.Log(ErrorLevel.Error, $"AWSCognito.cs RedirectToAWSLogin() authURL: " + authURL); 105 106 107 string languagePrefix = "/english"; 108 string currentLanguage = ExecutingContext.GetCulture(true).TwoLetterISOLanguageName; 109 if (currentLanguage == "el" || currentLanguage == "gr") { languagePrefix = "/greek"; } 110 string AWSCognitoCallback_redirect = languagePrefix + "/AWSCognitoCallback"; 111 string baseUrl = $"{Context.Current.Request.Url.Scheme}://{Context.Current.Request.Url.Host}"; 112 string redirectUri = baseUrl + AWSCognitoCallback_redirect; 113 114 //Create url then redirect to it 115 string clientID = CommonFunctions.GetCustomWebsiteSetting("AWS_Cognito_Client_ID"); 116 string stateGuid = HttpCookieHelper.GetHttpCookie("AWS_StateGuid"); 117 if (string.IsNullOrWhiteSpace(stateGuid)) 118 { 119 stateGuid = Guid.NewGuid().ToString(); 120 } 121 HttpCookieHelper.SetHttpCookie("AWS_StateGuid", stateGuid); 122 redirectURL_cognito = authURL + "?response_type=code&client_id=" + clientID; 123 redirectURL_cognito += "&redirect_uri=" + redirectUri; 124 redirectURL_cognito += "&scope=openid%20profile%20email+phone"; 125 redirectURL_cognito += "&state=" + stateGuid; 126 } 127 } 128 catch (Exception ex) 129 { 130 Logger.Instance.Log(ErrorLevel.Error, $"Navigation.cshtml RedirectToAWSLogin Error: {ex.Message} StackTrace: {ex.StackTrace}"); 131 } 132 133 134 135 } 136 137 @if (themesParagraphs != null || brandingPage != null) 138 { 139 string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt"); 140 bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase); 141 bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet; 142 string responsiveClassDesktop = string.Empty; 143 string responsiveClassMobile = string.Empty; 144 if (renderAsResponsive) 145 { 146 responsiveClassDesktop = " d-none d-xl-block"; 147 responsiveClassMobile = " d-block d-xl-none"; 148 } 149 150 var headerDesktopLink = Model.Area.Item?.GetLink("HeaderDesktop") ?? null; 151 var headerMobileLink = Model.Area.Item?.GetLink("HeaderMobile") ?? null; 152 153 var footerDesktopLink = Model.Area.Item?.GetLink("FooterDesktop") ?? null; 154 var footerMobileLink = Model.Area.Item?.GetLink("FooterMobile") ?? null; 155 156 var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default"); 157 158 string customHeaderInclude = !string.IsNullOrEmpty(Model.Area.Item.GetRawValueString("CustomHeaderInclude")) ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty; 159 160 var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 161 var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt; 162 163 var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css")); 164 165 166 if (cssPageId != 0) 167 { 168 var cssFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_css_styles_{Model.Area.ID}.css")); 169 var cssParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(cssPageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 170 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < cssParagraphLastChanged.Audit.LastModifiedAt) 171 { 172 var cssPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(cssPageId); 173 cssPageview.Redirect = false; 174 cssPageview.Output(); 175 } 176 } 177 178 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt) 179 { 180 //Branding page has been saved or the file is missing. Rewrite the file to disc. 181 if (brandingPageId > 0) 182 { 183 var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId); 184 brandingPageview.Redirect = false; 185 brandingPageview.Output(); 186 } 187 } 188 189 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt) 190 { 191 //Branding page has been saved or the file is missing. Rewrite the file to disc. 192 if (themePageId > 0) 193 { 194 var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId); 195 themePageview.Redirect = false; 196 themePageview.Output(); 197 } 198 } 199 200 // Schema.org details for PDP 201 bool isProductDetailsPage = Dynamicweb.Context.Current.Request.QueryString.AllKeys.Contains("ProductID"); 202 bool isArticlePage = Model.ItemType == "Swift_Article"; 203 string schemaOrgType = string.Empty; 204 205 if (isProductDetailsPage) 206 { 207 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\""; 208 } 209 210 if (isArticlePage) 211 { 212 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\""; 213 } 214 215 216 var cssStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/styles.css")); 217 @* CS NT - custom Nextech stylesheet *@ 218 var cssStyleFileInfoNextech = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/nextech.css")); 219 @* CS NT - slick stylesheet *@ 220 var cssStyleFileInfoSlick = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/slick.css")); 221 @* CS NT - slick theme stylesheet *@ 222 var cssStyleFileInfoSlickTheme = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/slick-theme.css")); 223 224 225 226 227 var jsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/scripts.js")); 228 @*CS NT - include custom.js*@ 229 var jsFileInfoCustom = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/custom.js")); 230 @*CS NT - include slick.min.js*@ 231 var slickFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/slick.min.js")); 232 233 234 string masterTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("Theme")) ? " theme " + Model.Area.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 235 236 string favicon = Model.Area.Item.GetRawValueString("Favicon", "/Files/Templates/Designs/Swift/Assets/Images/favicon.png"); 237 string appleTouchIcon = Model.Area.Item.GetRawValueString("AppleTouchIcon", "/Files/Templates/Designs/Swift/Assets/Images/apple-touch-icon.png"); 238 239 string headerCssClass = "sticky-top"; 240 bool movePageBehind = false; 241 242 if (Model.PropertyItem != null) 243 { 244 headerCssClass = Model.PropertyItem.GetRawValueString("MoveThisPageBehindTheHeader", "sticky-top"); 245 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 246 } 247 248 headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass; 249 headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass; 250 251 string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID").Trim(); 252 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID").Trim(); 253 254 bool allowTracking = AllowTracking(); 255 256 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;"); 257 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/nextech.css?{cssStyleFileInfoNextech.LastWriteTime.Ticks}>; rel=preload; as=style;"); 258 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;"); 259 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/slick.css?{cssStyleFileInfoSlick.LastWriteTime.Ticks}>; rel=preload; as=style;"); 260 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/slick-theme.css?{cssStyleFileInfoSlickTheme.LastWriteTime.Ticks}>; rel=preload; as=style;"); 261 262 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}>; rel=preload; as=script;"); 263 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/custom.js?{jsFileInfoCustom.LastWriteTime.Ticks}; rel=preload; as=script;"); 264 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/slick.min.js?{slickFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;"); 265 266 267 SetMetaTags(); 268 269 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>(); 270 271 var masterPage = Pageview.Area.IsMaster ? Pageview.Page : Pageview.Page.MasterPage; 272 languages.Add(masterPage); 273 if (masterPage?.Languages != null) 274 { 275 foreach (var language in masterPage.Languages) 276 { 277 languages.Add(language); 278 } 279 } 280 281 Uri url = Dynamicweb.Context.Current.Request.Url; 282 string hostName = url.Host; 283 284 <!doctype html> 285 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName"> 286 <head> 287 <!-- @swiftVersion --> 288 @* Required meta tags *@ 289 <meta charset="utf-8"> 290 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0"> 291 <link rel="shortcut icon" href="@favicon"> 292 <link rel="icon" type="image/png" href="@favicon"> 293 <link rel="apple-touch-icon" href="@appleTouchIcon"> 294 295 @*CS NT Jquery CDN*@ 296 <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> 297 298 @Model.MetaTags 299 @*BG 20250416-Google Merchant Listing*@ 300 @RenderSnippet("MerchantlistingJSON") 301 302 303 304 @*CS NT Cookie script, raptor, AI chatbot*@ 305 306 <script async id="octocom-script" src="https://www.octocom.ai/chatbot/bundle.js"></script> 307 308 <!--Cookie Script Begin--> 309 <script type="text/javascript" charset="UTF-8" src="//cdn.cookie-script.com/s/0f7e74854350119f4ba7f565e3066cd6.js"></script> 310 <!--Cookie Script End--> 311 312 <!-- CS NT Staging? cookie script--> 313 <!--<script type="text/javascript" charset="UTF-8" src="//cdn.cookie-script.com/s/dfe7c945aeca99811bd22710360fd93f.js"></script>--> 314 315 <!-- CS NT natively--> 316 <script async onload="nativelyOnLoad()" src="https://cdn.jsdelivr.net/npm/natively@2.15.16/natively-frontend.min.js"></script> 317 <script> 318 function nativelyOnLoad() { 319 window.natively.setDebug(true); // To see errors 320 } 321 </script> 322 323 324 <script type="text/javascript"> 325 let raptorPageViewSent = false; 326 327 window.addEventListener('CookieScriptAcceptAll', function() { 328 console.log('CookieScriptAcceptAll NT'); 329 330 if ('@googleTagManagerID' != '') 331 { 332 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 333 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 334 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 335 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 336 })(window,document,'script','dataLayer','@googleTagManagerID'); 337 } 338 339 340 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//deliver.raptorstatic.com/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 341 window.raptor || (window.raptor = { q: [{ event: "trackevent", params: { p1: "pageview" } }], push: function (event, params, options) { this.q.push({ event: event, params: params, options: options }) }, customerId: "6463" }); 342 raptorPageViewSent = true; 343 }) 344 345 window.addEventListener('CookieScriptCategory-targeting', function() { 346 console.log('CookieScriptCategory-targeting NT'); 347 348 if ('@googleTagManagerID' != '') 349 { 350 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 351 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 352 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 353 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 354 })(window,document,'script','dataLayer','@googleTagManagerID'); 355 } 356 357 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//deliver.raptorstatic.com/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 358 window.raptor || (window.raptor = { q: [{ event: "trackevent", params: { p1: "pageview" } }], push: function (event, params, options) { this.q.push({ event: event, params: params, options: options }) }, customerId: "6463" }); 359 raptorPageViewSent = true; 360 361 }) 362 363 window.addEventListener('CookieScriptAccept', function(e) { 364 console.log('CookieScriptAccept NT'); 365 //console.log(e.detail); 366 var i; 367 var targetingEnabled = false; 368 for (i = 0; i < e.detail.categories.length; ++i) { 369 if(e.detail.categories[i] =='targeting') 370 { 371 targetingEnabled = true; 372 } 373 console.log(e.detail.categories[i]); 374 } 375 console.log('targetingEnabled '+targetingEnabled); 376 if(targetingEnabled) 377 { 378 console.log('CookieScriptAccept targeting NT'); 379 380 if ('@googleTagManagerID' != '') 381 { 382 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 383 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 384 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 385 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 386 })(window,document,'script','dataLayer','@googleTagManagerID'); 387 } 388 389 390 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//deliver.raptorstatic.com/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 391 window.raptor || (window.raptor = { q: [{ event: "trackevent", params: { p1: "pageview" } }], push: function (event, params, options) { this.q.push({ event: event, params: params, options: options }) }, customerId: "6463" }); 392 raptorPageViewSent = true; 393 } 394 }) 395 396 if(CookieScript.instance.currentState().categories.indexOf('targeting') >= 0) 397 { 398 if ('@googleTagManagerID' != '') 399 { 400 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 401 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 402 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 403 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 404 })(window,document,'script','dataLayer','@googleTagManagerID'); 405 } 406 } 407 if(!raptorPageViewSent && CookieScript.instance.currentState().action == 'accept') 408 { 409 console.log('CookieScript.instance.currentState().action = accept -> Calling pageview'); 410 411 window.raptor || (window.raptor = { q: [{ event: "trackevent", params: { p1: "pageview" } }], push: function (event, params, options) { this.q.push({ event: event, params: params, options: options }) }, customerId: "6463" }); 412 //(function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//deliver.raptorstatic.com/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 413 414 } 415 416 417 </script> 418 419 420 421 @{ 422 var alreadyWrittenTwoletterIsos = new List<string>(); 423 @* Languages meta data *@ 424 foreach (var language in languages) 425 { 426 hostName = url.Host; 427 if (language?.Area != null) 428 { 429 if (language.Area?.MasterArea != null && !string.IsNullOrEmpty(language.Area.MasterArea.DomainLock)) 430 { 431 hostName = language.Area.MasterArea.DomainLock; //dk.domain.com or dk-domain.dk 432 } 433 if (language != null && language.Area != null && language.Published && language.Area.Active && language.Area.Published) 434 { 435 if (!string.IsNullOrEmpty(language.Area.DomainLock)) 436 { 437 hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk 438 } 439 string querystring = $"Default.aspx?ID={language.ID}"; 440 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"])) 441 { 442 querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}"; 443 } 444 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 445 { 446 querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}"; 447 } 448 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"])) 449 { 450 querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}"; 451 } 452 453 string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring); 454 if (language.Area.RedirectFirstPage && language.ParentPageId == 0 && language.Sort == 1) 455 { 456 friendlyUrl = "/"; 457 } 458 string href = $"{url.Scheme}://{hostName}{friendlyUrl}"; 459 460 461 <link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href"> 462 if (!alreadyWrittenTwoletterIsos.Contains(language.Area.CultureInfo.TwoLetterISOLanguageName)) 463 { 464 alreadyWrittenTwoletterIsos.Add(language.Area.CultureInfo.TwoLetterISOLanguageName); 465 <link rel="alternate" hreflang="@language.Area.CultureInfo.TwoLetterISOLanguageName.ToLower()" href="@href"> 466 } 467 } 468 } 469 } 470 } 471 472 <title>@Model.Title</title> 473 @* Bootstrap + Swift stylesheet *@ 474 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 475 @* CS NT - custom Nextech stylesheet *@ 476 <link href="/Files/Templates/Designs/Swift/Assets/css/nextech.css?@cssStyleFileInfoNextech.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 477 @* CS NT - custom Slick stylesheet *@ 478 <link href="/Files/Templates/Designs/Swift/Assets/css/slick.css?@cssStyleFileInfoSlick.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 479 @* CS NT - Slick-theme stylesheet *@ 480 <link href="/Files/Templates/Designs/Swift/Assets/css/slick-theme.css?@cssStyleFileInfoSlickTheme.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 481 482 @* Font Awesome CS NT *@ 483 <link href="/Files/Templates/Designs/Swift/Assets/fonts/FontAwesomeFree/css/fontawesome-all.min.css" rel="stylesheet" media="all" type="text/css"> 484 485 486 @* Flags css from Rapido CS NT *@ 487 <!-- Flag icon --> 488 <link rel="stylesheet" href="/Files/Templates/Designs/Swift/Assets/css/flag-icon.min.css" type="text/css"> 489 490 @if (disableWideBreakpoints != "disableBoth") 491 { 492 <style> 493 @@media ( min-width: 1600px ) { 494 .container-xxl, 495 .container-xl, 496 .container-lg, 497 .container-md, 498 .container-sm, 499 .container { 500 max-width: 1520px; 501 } 502 } 503 </style> 504 505 506 507 if (disableWideBreakpoints != "disableUltraWideOnly") 508 { 509 <style> 510 @@media ( min-width: 1920px ) { 511 .container-xxl, 512 .container-xl, 513 .container-lg, 514 .container-md, 515 .container-sm, 516 .container { 517 max-width: 1820px; 518 } 519 } 520 </style> 521 } 522 } 523 524 @* Branding and Themes min stylesheet *@ 525 <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"> 526 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks"></script> 527 528 @*<script src="https://cdn.jsdelivr.net/gh/igorlino/elevatezoom-plus@1.2.5/src/jquery.ez-plus.min.js"></script>*@ 529 <script src="/Files/Templates/Designs/Swift/Assets/js/jquery.ez-plus1.2.5.min.js"></script> 530 531 532 @*CS NT - include custom.js*@ 533 <script src="/Files/Templates/Designs/Swift/Assets/js/custom.js?@jsFileInfoCustom.LastWriteTime.Ticks" defer></script> 534 @*CS NT - include slick.min.js*@ 535 <script src="/Files/Templates/Designs/Swift/Assets/js/slick.min.js?@slickFileInfo.LastWriteTime.Ticks" defer></script> 536 537 <script src="https://www.google.com/recaptcha/api.js" async defer></script> 538 539 <script type="module"> 540 swift.Scroll.hideHeadersOnScroll(); 541 swift.Scroll.handleAlternativeTheme(); 542 543 //Only load if AOS 544 const aosColumns = document.querySelectorAll('[data-aos]'); 545 if (aosColumns.length > 0) { 546 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks', 'js'); 547 document.addEventListener('load.swift.assetloader', function () { 548 AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') }); 549 }); 550 } 551 </script> 552 553 @* Google gtag method - always include even if it is not used for anything *@ 554 <script> 555 window.dataLayer = window.dataLayer || []; 556 function gtag() { dataLayer.push(arguments); } 557 </script> 558 @* Google tag manager *@ 559 @if (false && !string.IsNullOrWhiteSpace(googleTagManagerID)) 560 { 561 <script> 562 gtag('consent', 'default', { 563 'ad_storage': 'denied', 564 'ad_user_data': 'denied', 565 'ad_personalization': 'denied', 566 'analytics_storage': 'denied' 567 }); 568 </script> 569 <script> 570 (function (w, d, s, l, i) { 571 w[l] = w[l] || []; w[l].push({ 572 'gtm.start': 573 new Date().getTime(), event: 'gtm.js' 574 }); var f = d.getElementsByTagName(s)[0], 575 j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 576 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); 577 })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)'); 578 </script> 579 if (allowTracking) 580 { 581 string adConsent = GetCookieOptInPermission("Marketing"); 582 string analyticsConsent = GetCookieOptInPermission("Statistical"); 583 <script> 584 gtag('consent', 'update', { 585 'ad_storage': '@adConsent', 586 'ad_user_data': '@adConsent', 587 'ad_personalization': '@adConsent', 588 'analytics_storage': '@analyticsConsent' 589 }); 590 </script> 591 } 592 } 593 594 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) 595 { 596 var GoogleAnalyticsDebugMode = ""; 597 598 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode")) 599 { 600 GoogleAnalyticsDebugMode = ", {'debug_mode': true}"; 601 } 602 603 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script> 604 <script> 605 gtag('js', new Date()); 606 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode); 607 </script> 608 } 609 610 @*BG-NT Findbar start *@ 611 @if (currentLanguageTwoLetter == "el") 612 { 613 <script type="text/javascript" src="https://app.findbar.io/js/superhome.com.cy/findbar.js?index=wmswot" async></script> 614 } 615 else 616 { 617 <script type="text/javascript" src="https://app.findbar.io/js/superhome.com.cy/findbar.js" async></script> 618 } 619 @*BG-NT Findbar end *@ 620 621 622 @if (!string.IsNullOrWhiteSpace(customHeaderInclude)) 623 { 624 @RenderPartial($"Components/Custom/{customHeaderInclude}") 625 } 626 </head> 627 <body class="brand @(masterTheme)" id="page@(Model.ID)"> 628 629 @* Google tag manager *@ 630 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking) 631 { 632 <noscript> 633 <iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)" 634 height="0" width="0" style="display:none;visibility:hidden"></iframe> 635 </noscript> 636 } 637 638 @if (renderAsResponsive || !renderMobile) 639 { 640 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop"> 641 @if (headerDesktopLink != null) 642 { 643 @RenderGrid(headerDesktopLink.PageId) 644 } 645 </header> 646 } 647 648 @if ((renderAsResponsive || renderMobile)) 649 { 650 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile"> 651 @if (headerMobileLink != null) 652 { 653 @RenderGrid(headerMobileLink.PageId) 654 } 655 </header> 656 } 657 658 <div data-intersect></div> 659 660 <main id="content" @(schemaOrgType)> 661 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 662 @using System 663 @using Dynamicweb.Ecommerce.ProductCatalog 664 665 666 @{ 667 string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty; 668 bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop"; 669 670 bool isArticlePagePage = Model.ItemType == "Swift_Article"; 671 bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage"; 672 string schemaOrgProp = string.Empty; 673 if(isArticlePagePage) 674 { 675 schemaOrgProp = "itemprop=\"articleBody\""; 676 } 677 678 string theme = ""; 679 string gridContent = ""; 680 681 if (Model.PropertyItem != null) 682 { 683 theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 684 } 685 686 if (Model.Item != null || Pageview.IsVisualEditorMode) 687 { 688 if (!isProductDetail) 689 { 690 gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page"); 691 } 692 else 693 { 694 var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId); 695 var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty; 696 var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage"); 697 698 @RenderGrid(detailPageId) 699 } 700 } 701 702 bool doNotRenderPage = false; 703 704 //Check if we are on the poduct detail page, and if there is data to render 705 ProductViewModel product = new ProductViewModel(); 706 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 707 { 708 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 709 if (string.IsNullOrEmpty(product.Id)) { 710 doNotRenderPage = true; 711 } 712 } 713 714 //Render the page 715 if (!doNotRenderPage) { 716 string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page"; 717 718 if (Pageview.IsVisualEditorMode) { 719 @Model.Placeholder("dwcontent", "content", "default:true;sort:1") 720 } 721 722 <div class="@theme @itemIdentifier" @schemaOrgProp> 723 @if (isArticleListPage) 724 { 725 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\""; 726 727 <form @hx id="ArticleFacetForm"> 728 @gridContent 729 </form> 730 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/htmx.js"></script> 731 <script type="module"> 732 document.addEventListener('htmx:confirm', (event) => { 733 let filters = event.detail.elt.querySelectorAll('select'); 734 for (var i = 0; i < filters.length; i++) { 735 let input = filters[i]; 736 if (input.name && !input.value) { 737 input.name = ''; 738 } 739 } 740 }); 741 742 document.addEventListener('htmx:beforeOnLoad', (event) => { 743 swift.Scroll.stopIntersectionObserver(); 744 }); 745 746 document.addEventListener('htmx:afterOnLoad', () => { 747 swift.Scroll.hideHeadersOnScroll(); 748 swift.Scroll.handleAlternativeTheme(); 749 }); 750 </script> 751 } 752 else 753 { 754 @gridContent 755 } 756 </div> 757 758 } else { 759 <div class="container"> 760 <div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div> 761 </div> 762 } 763 764 if (!Model.IsCurrentUserAllowed) 765 { 766 int signInPage = GetPageIdByNavigationTag("SignInPage"); 767 int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage"); 768 769 if (!Pageview.IsVisualEditorMode) 770 { 771 if (signInPage != 0) 772 { 773 if (signInPage != Model.ID) { 774 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage); 775 } else { 776 if (dashboardPage != 0) { 777 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage); 778 } else { 779 Dynamicweb.Context.Current.Response.Redirect("/"); 780 } 781 } 782 } 783 else 784 { 785 <div class="alert alert-dark m-0" role="alert"> 786 <span>@Translate("You do not have access to this page")</span> 787 </div> 788 } 789 } 790 else 791 { 792 <div class="alert alert-dark m-0" role="alert"> 793 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span> 794 </div> 795 } 796 } 797 } 798 799 </main> 800 801 @if (renderAsResponsive || !renderMobile) 802 { 803 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop"> 804 @if (footerDesktopLink != null) 805 { 806 @RenderGrid(footerDesktopLink.PageId) 807 } 808 </footer> 809 } 810 811 @if (renderAsResponsive || renderMobile) 812 { 813 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile"> 814 @if (footerMobileLink != null) 815 { 816 @RenderGrid(footerMobileLink.PageId) 817 } 818 </footer> 819 } 820 821 @* Render any offcanvas menu here *@ 822 @RenderSnippet("offcanvas") 823 824 @{ 825 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]); 826 } 827 828 @* Language selector modal *@ 829 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true"> 830 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent"> 831 @* The content here comes from an external request *@ 832 </div> 833 </div> 834 835 @* Favorite toast *@ 836 <div aria-live="polite" aria-atomic="true"> 837 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11"> 838 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> 839 <div class="toast-header"> 840 <strong class="me-auto">@Translate("Favorite list updated")</strong> 841 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 842 </div> 843 <div class="toast-body d-flex gap-3"> 844 <div id="favoriteNotificationToast_Image"></div> 845 <div id="favoriteNotificationToast_Text"></div> 846 </div> 847 </div> 848 </div> 849 </div> 850 851 @* Modal for dynamic content *@ 852 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true"> 853 <div class="modal-dialog modal-dialog-centered modal-md"> 854 <div class="modal-content theme light" id="DynamicModalContent"> 855 @* The content here comes from an external request *@ 856 </div> 857 </div> 858 </div> 859 860 @*CS NT 20251104 *@ 861 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 862 @using System.Web 863 @using NextechDWAddIn.Common 864 @using NextechDWAddIn.Helpers 865 866 @{ 867 bool showMarketingPreferencesModal = false; 868 string userId_newsPref = ""; 869 if (Pageview != null && Pageview.User != null) 870 { 871 try 872 { 873 userId_newsPref = Pageview.User.ID.ToString(); 874 //todo get cookie value if to show modal. Check this on afterLogin and set the cookie value! 875 876 string UserMarketingPreferences_AttemptsRemaining = HttpCookieHelper.GetHttpCookie("UserMarketingPreferences_AttemptsRemaining"); 877 if (!string.IsNullOrWhiteSpace(UserMarketingPreferences_AttemptsRemaining)) 878 { 879 if (int.TryParse(UserMarketingPreferences_AttemptsRemaining, out int UserMarketingPreferences_AttemptsRemaining_int)) 880 { 881 if (UserMarketingPreferences_AttemptsRemaining_int > 0) 882 { 883 showMarketingPreferencesModal = true; 884 UserMarketingPreferences_AttemptsRemaining_int -= 1; 885 HttpCookieHelper.SetHttpCookie("UserMarketingPreferences_AttemptsRemaining", UserMarketingPreferences_AttemptsRemaining_int.ToString()); 886 887 } 888 } 889 } 890 } 891 catch (Exception ex) 892 { 893 Logger.Instance.Log(ErrorLevel.DebugInfo, "MarketingPreferencesModal.cshtml EXCEPTION: " + ex.Message + " StackTrace: " + ex.StackTrace); 894 } 895 896 //if(Pageview.User.ID == 3700){showMarketingPreferencesModal = true;}//CS NT 897 898 } 899 900 } 901 902 @if (showMarketingPreferencesModal) 903 { 904 905 <button type="button" class="btn btn-link p-0 border-0" data-bs-toggle="modal" data-bs-target="#MarketingPreferencesModal" id="MarketingPreferencesModal_Target_Btn" aria-expanded="true" aria-controls="MarketingPreferencesModal_Target_Btn" hidden></button> 906 <div class="modal fade js-product" id="MarketingPreferencesModal" tabindex="-1" aria-hidden="true"> 907 <div class="modal-dialog modal-dialog-centered modal-md"> 908 <div class="modal-content theme light" id="MarketingPreferencesModalContent"> 909 910 <div class="promo-section"> 911 <div class="speech-box"> 912 <h2>@Translate("Stay in the loop!")</h2> 913 <p>@Translate("I agree to receive updates, offers, and promotional communications from") <span class="fw-bold">SUPERHOME CENTER (DIY) LIMITED</span> @Translate("via SMS and email.")</p> 914 915 <div class="marketing-options"> 916 <label class="marketing-checkbox-container"> 917 <input type="checkbox" name="marketing_email" id="email_MarketingPreferences" /> 918 <span class="marketing-checkmark"></span> 919 <span class="label-text">@Translate("Email")</span> 920 </label> 921 922 <label class="marketing-checkbox-container"> 923 <input type="checkbox" name="marketing_sms" id="sms_MarketingPreferences" /> 924 <span class="marketing-checkmark"></span> 925 <span class="marketing-label-text">@Translate("SMS")</span> 926 </label> 927 </div> 928 929 <button type="button" class="" id="MarketingPreferencesModal_ConfirmBtn">@Translate("Confirm")</button> 930 </div> 931 </div> 932 933 934 935 @* 936 <div class="modal-header"> 937 <button type="button" id="MarketingPreferencesModal-btn-close" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 938 </div> 939 940 <div class="modal-body d-grid gap-3"> 941 <span class="w-100">@Translate("I would like to receive updates and marketing information via:")</span> 942 943 <div class="marketing-options"> 944 <label class="marketing-checkbox-container"> 945 <input type="checkbox" name="marketing_email" id="email_MarketingPreferences" /> 946 <span class="marketing-checkmark"></span> 947 <span class="label-text">@Translate("Email")</span> 948 </label> 949 950 <label class="marketing-checkbox-container"> 951 <input type="checkbox" name="marketing_sms" id="sms_MarketingPreferences" /> 952 <span class="marketing-checkmark"></span> 953 <span class="marketing-label-text">@Translate("SMS")</span> 954 </label> 955 </div> 956 </div> 957 958 <div class="modal-footer text-center" id="MarketingPreferences-modal-footer"> 959 <button type="button" class="btn btn-primary" id="MarketingPreferencesModal_ConfirmBtn">@Translate("Confirm")</button> 960 </div> 961 *@ 962 </div> 963 </div> 964 </div> 965 966 967 968 <script type="text/javascript"> 969 $(document).ready(function () { 970 // Wait for the button element to appear (assuming waitForElm is defined elsewhere) 971 waitForElm('#MarketingPreferencesModal_Target_Btn').then((elm) => { 972 $("#MarketingPreferencesModal_Target_Btn").trigger("click"); 973 }); 974 975 // Confirm button click handler 976 $("#MarketingPreferencesModal_ConfirmBtn").on("click", function () { 977 const userId = '@userId_newsPref'; // server-side injected variable (string) 978 979 // Get checkbox states 980 const emailSelected = $('#email_MarketingPreferences').is(':checked') ? 1 : 0; 981 const smsSelected = $('#sms_MarketingPreferences').is(':checked') ? 1 : 0; 982 983 console.log("Email marketing:", emailSelected); 984 console.log("SMS marketing:", smsSelected); 985 986 // ✅ Use backticks for template literals, not single quotes 987 const apiUrl = `/MarketingPreferencesAPI?userId=${userId}&emailMarketingSelected=${emailSelected}&SMSMarketingSelected=${smsSelected}`; 988 989 console.log("apiUrl:", apiUrl); 990 991 // Make the GET request 992 $.get(apiUrl) 993 .done(function (response) { 994 console.log('Preferences saved:', response); 995 //alert('Your preferences have been saved successfully!'); 996 }) 997 .fail(function (xhr, status, error) { 998 //console.log('Error:' + error); 999 //alert('There was a problem saving your preferences.'); 1000 }); 1001 1002 1003 //document.getElementById('MarketingPreferencesModal-btn-close').click();//close modal 1004 }); 1005 }); 1006 </script> 1007 1008 <script> 1009 document.addEventListener("DOMContentLoaded", function () { 1010 const confirmBtn = document.getElementById("MarketingPreferencesModal_ConfirmBtn"); 1011 1012 confirmBtn.addEventListener("click", function () { 1013 // Get the Bootstrap modal instance 1014 const modalElement = document.getElementById("MarketingPreferencesModal"); 1015 const modalInstance = bootstrap.Modal.getInstance(modalElement); 1016 1017 // Hide the modal 1018 modalInstance.hide(); 1019 }); 1020 }); 1021 </script> 1022 } 1023 1024 @* Offcanvas for dynamic content *@ 1025 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas"> 1026 @* The content here comes from an external request *@ 1027 </div> 1028 1029 @if (Model.Area.Item.GetBoolean("ShowErpDownMessage") && !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"])) 1030 { 1031 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light"; 1032 1033 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040"> 1034 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true"> 1035 <div class="toast-header"> 1036 <strong class="me-auto">@Translate("Connection down")</strong> 1037 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 1038 </div> 1039 <div class="toast-body"> 1040 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.") 1041 </div> 1042 </div> 1043 </div> 1044 } 1045 1046 @if (miniCartEnabled) 1047 { 1048 @* Open MiniCart when the cart is updated *@ 1049 <script type="module"> 1050 document.addEventListener('updated.swift.cart', (event) => { 1051 let orderContext = event?.detail?.formData?.get("OrderContext"); 1052 updateCartSummary(orderContext); 1053 1054 @if (offcanvasMiniCartBehaviour == "2" || offcanvasMiniCartBehaviour == "3") { 1055 <text>openMiniCartOffcanvas();</text> 1056 } 1057 }); 1058 </script> 1059 1060 if (offcanvasMiniCartBehaviour == "1" || offcanvasMiniCartBehaviour == "3") 1061 { 1062 @* Open MiniCart when toggle is clicked *@ 1063 <script type="module"> 1064 let miniCartToggles = document.querySelectorAll('.mini-cart-quantity'); 1065 miniCartToggles?.forEach((toggle) => { 1066 toggle.parentElement.addEventListener('click', (event) => { 1067 event.preventDefault(); 1068 let orderContext = toggle.dataset?.orderContext; 1069 updateCartSummary(orderContext); 1070 1071 openMiniCartOffcanvas(); 1072 }); 1073 }); 1074 </script> 1075 } 1076 1077 <script> 1078 1079 const updateCartSummary = (orderContext) => { 1080 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 1081 swift.PageUpdater.UpdateFromUrlInline(event, '/Default.aspx?ID=@(cartSummaryPageId)&CartType=minicart&RequestPageID=@(Pageview.Page.ID)&OrderContext=' + orderContext +'', 'Swift_CartSummary.cshtml', dynamicOffcanvas); 1082 }; 1083 1084 const openMiniCartOffcanvas = () => { 1085 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 1086 const miniCartOffcanvas = bootstrap.Offcanvas.getOrCreateInstance(dynamicOffcanvas); 1087 dynamicOffcanvas.classList.add('overflow-y-auto'); 1088 1089 if (!miniCartOffcanvas._isShown) { 1090 miniCartOffcanvas.show(); 1091 hideActiveOffcanvases(miniCartOffcanvas); 1092 } 1093 }; 1094 1095 const hideActiveOffcanvases = (miniCartOffcanvas) => { 1096 let activeOffcanvases = document.querySelectorAll('.offcanvas.show'); 1097 activeOffcanvases?.forEach((offCanvas) => { 1098 offCanvas = bootstrap.Offcanvas.getInstance(offCanvas); 1099 if (offCanvas !== miniCartOffcanvas) { 1100 offCanvas.hide(); 1101 } 1102 }); 1103 }; 1104 1105 </script> 1106 } 1107 1108 1109 1110 1111 <script> 1112 //CS NT 20251121 1113 1114 document.addEventListener("click", function (e) { 1115 const target = e.target.closest(".is-redirect-cognito-login"); 1116 if (!target) return; 1117 1118 e.preventDefault(); 1119 1120 const isAndroid = window && window.natively && window.natively.isAndroidApp; 1121 1122 window.location.reload(true); 1123 1124 setTimeout(() => { 1125 if (isAndroid) { 1126 window.natively.openExternalURL('@redirectURL_cognito', true); 1127 } else { 1128 window.location.assign('@redirectURL_cognito'); 1129 } 1130 }, 100); 1131 }); 1132 </script> 1133 1134 1135 </body> 1136 1137 </html> 1138 1139 } 1140 else if (Pageview.IsVisualEditorMode) 1141 { 1142 <head> 1143 <title>@Model.Title</title> 1144 @* Bootstrap + Swift stylesheet *@ 1145 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css" rel="stylesheet" media="all" type="text/css"> 1146 </head> 1147 <body class="p-3"> 1148 <div class="alert alert-danger" role="alert"> 1149 @Translate("Basic Swift setup is needed!") 1150 </div> 1151 1152 @if (brandingPage == null) 1153 { 1154 <div class="alert alert-warning" role="alert"> 1155 @Translate("Please add a Branding page and reference it in website settings") 1156 </div> 1157 } 1158 1159 @if (themesParagraphs == null) 1160 { 1161 <div class="alert alert-warning" role="alert"> 1162 @Translate("Please add a Themes collection page and reference it in website settings") 1163 </div> 1164 } 1165 </body> 1166 } 1167 1168 1169 @functions { 1170 void SetMetaTags() 1171 { 1172 //Verification Tokens 1173 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : ""; 1174 1175 //Generic Site Values 1176 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : ""; 1177 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : ""; 1178 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : ""; 1179 1180 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : ""; 1181 1182 //Page specific values 1183 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : ""; 1184 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image"); 1185 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : ""; 1186 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : ""; 1187 1188 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : ""; 1189 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : ""; 1190 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : ""; 1191 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image"); 1192 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : ""; 1193 1194 //CS NT 20260116 1195 string productImageNT = ""; 1196 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID"))) 1197 { 1198 string productId = Dynamicweb.Context.Current.Request.QueryString.Get("ProductID"); 1199 if(!string.IsNullOrEmpty(productId)) 1200 { 1201 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, "",true); 1202 if (product != null) 1203 { 1204 productImageNT = Dynamicweb.Ecommerce.Services.ProductImages.GetImagePath(product); 1205 if(!string.IsNullOrEmpty(productImageNT)) 1206 { 1207 productImageNT = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + productImageNT; 1208 } 1209 } 1210 } 1211 } 1212 //..CS NT 1213 1214 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 1215 { 1216 if (!string.IsNullOrEmpty(Model.Description)) 1217 { 1218 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{Model.Description}\">"); 1219 } 1220 else 1221 { 1222 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{openGraphDescription}\">"); 1223 } 1224 1225 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 1226 { 1227 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}\">"); 1228 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}\">"); 1229 } 1230 else if (openGraphImage != null) 1231 { 1232 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 1233 Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 1234 } 1235 1236 if (!string.IsNullOrEmpty(openGraphImageALT)) 1237 { 1238 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{openGraphImageALT}\">"); 1239 } 1240 if (!string.IsNullOrEmpty(twitterCardDescription)) 1241 { 1242 Pageview.Meta.AddTag("twitter:description", twitterCardDescription); 1243 } 1244 1245 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 1246 { 1247 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}"); 1248 } 1249 else if (twitterCardImage != null) 1250 { 1251 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}"); 1252 } 1253 1254 if (!string.IsNullOrEmpty(twitterCardImageALT)) 1255 { 1256 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT); 1257 } 1258 }else if (!string.IsNullOrEmpty(productImageNT)) 1259 { 1260 //CS NT 20260116 1261 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{productImageNT}\">"); 1262 } 1263 1264 if (!string.IsNullOrEmpty(siteVerificationGoogle)) 1265 { 1266 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle); 1267 } 1268 1269 if (!string.IsNullOrEmpty(openGraphFacebookAppID)) 1270 { 1271 Pageview.Meta.AddTag($"<meta property=\"fb:app_id\" content=\"{openGraphFacebookAppID}\">"); 1272 } 1273 1274 if (!string.IsNullOrEmpty(openGraphType)) 1275 { 1276 Pageview.Meta.AddTag($"<meta property=\"og:type\" content=\"{openGraphType}\">"); 1277 } 1278 1279 if (!string.IsNullOrEmpty(openGraphSiteName)) 1280 { 1281 Pageview.Meta.AddTag($"<meta property=\"og:url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Pageview.SearchFriendlyUrl}\">"); 1282 } 1283 1284 if (!string.IsNullOrEmpty(openGraphSiteName)) 1285 { 1286 Pageview.Meta.AddTag($"<meta property=\"og:site_name\" content=\"{openGraphSiteName}\">"); 1287 } 1288 1289 1290 1291 /*CS NT 20260116 fix " in name 1292 if (!string.IsNullOrEmpty(Model.Title)) 1293 { 1294 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{Model.Title}\">"); 1295 } 1296 else 1297 { 1298 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{openGraphSiteTitle}\">"); 1299 } 1300 */ 1301 1302 //CS NT 20260116 new 1303 if (!string.IsNullOrEmpty(Model.Title)) 1304 { 1305 var safeTitle = System.Net.WebUtility.HtmlEncode(Model.Title); 1306 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{safeTitle}\">"); 1307 } 1308 else 1309 { 1310 var safeDefaultTitle = System.Net.WebUtility.HtmlEncode(openGraphSiteTitle); 1311 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{safeDefaultTitle}\">"); 1312 } 1313 1314 1315 if (!string.IsNullOrEmpty(twitterCardSite)) 1316 { 1317 Pageview.Meta.AddTag("twitter:site", twitterCardSite); 1318 } 1319 1320 if (!string.IsNullOrEmpty(twitterCardURL)) 1321 { 1322 Pageview.Meta.AddTag("twitter:url", twitterCardURL); 1323 } 1324 1325 if (!string.IsNullOrEmpty(twitterCardTitle)) 1326 { 1327 Pageview.Meta.AddTag("twitter:title", twitterCardTitle); 1328 } 1329 } 1330 } 1331