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.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_e43d4d5e87974c07bacaeae760fd9bd7.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 584
   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 @using System.Web 7 8 @functions { 9 string GetCookieOptInPermission(string category) 10 { 11 bool categoryOrAllGranted = false; 12 13 if (CookieManager.IsCookieManagementActive) 14 { 15 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 16 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 17 categoryOrAllGranted = cookieOptInCategories.Contains(category) || cookieOptInLevel == CookieOptInLevel.All; 18 } 19 20 return categoryOrAllGranted ? "granted" : "denied"; 21 } 22 23 bool AllowTracking() 24 { 25 bool allowTracking = true; 26 if (CookieManager.IsCookieManagementActive) 27 { 28 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 29 var cookieOptInCategories = CookieManager.GetCookieOptInCategories(); 30 31 bool consentEither = (cookieOptInCategories.Contains("Statistical") || cookieOptInCategories.Contains("Marketing")); 32 bool consentFunctional = cookieOptInLevel == CookieOptInLevel.Functional; 33 bool consentAtLeastOne = cookieOptInLevel == CookieOptInLevel.All || (consentFunctional && consentEither); 34 35 allowTracking = consentAtLeastOne; 36 } 37 return allowTracking; 38 } 39 } 40 41 @{ 42 var cartSummaryPageId = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Model.Area.ID, "CartSummary")?.ID; 43 bool enableMiniCart = Model.Area.Item?.GetBoolean("EnableOffcanvasMiniCart") ?? false; 44 var offcanvasMiniCartBehaviour = Model.Area.Item?.GetRawValueString("OffcanvasMinicartBehaviour", "3") ?? "3"; 45 bool miniCartEnabled = cartSummaryPageId != null && enableMiniCart; 46 var brandingPageId = Model.Area.Item?.GetInt32("BrandingPage") ?? 0; 47 var themePageId = Model.Area.Item?.GetInt32("ThemesPage") ?? 0; 48 var cssPageId = Model.Area.Item?.GetInt32("CssPage") ?? 0; 49 var brandingPage = brandingPageId != 0 ? Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null : null; 50 var themesParagraphs = themePageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(themePageId) ?? null : null; 51 var cssParagraphs = cssPageId != 0 ? Dynamicweb.Content.Services.Paragraphs?.GetParagraphsByPageId(cssPageId) ?? null : null; 52 53 } 54 55 @if (themesParagraphs != null || brandingPage != null) 56 { 57 string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt"); 58 bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase); 59 bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet; 60 string responsiveClassDesktop = string.Empty; 61 string responsiveClassMobile = string.Empty; 62 if (renderAsResponsive) 63 { 64 responsiveClassDesktop = " d-none d-xl-block"; 65 responsiveClassMobile = " d-block d-xl-none"; 66 } 67 68 var headerDesktopLink = Model.Area.Item?.GetLink("HeaderDesktop") ?? null; 69 var headerMobileLink = Model.Area.Item?.GetLink("HeaderMobile") ?? null; 70 71 var footerDesktopLink = Model.Area.Item?.GetLink("FooterDesktop") ?? null; 72 var footerMobileLink = Model.Area.Item?.GetLink("FooterMobile") ?? null; 73 74 var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default"); 75 76 string customHeaderInclude = !string.IsNullOrEmpty(Model.Area.Item.GetRawValueString("CustomHeaderInclude")) ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty; 77 78 var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 79 var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt; 80 81 var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css")); 82 83 84 if (cssPageId != 0) 85 { 86 var cssFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_css_styles_{Model.Area.ID}.css")); 87 var cssParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(cssPageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault(); 88 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < cssParagraphLastChanged.Audit.LastModifiedAt) 89 { 90 var cssPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(cssPageId); 91 cssPageview.Redirect = false; 92 cssPageview.Output(); 93 } 94 } 95 96 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt) 97 { 98 //Branding page has been saved or the file is missing. Rewrite the file to disc. 99 if (brandingPageId > 0) 100 { 101 var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId); 102 brandingPageview.Redirect = false; 103 brandingPageview.Output(); 104 } 105 } 106 107 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt) 108 { 109 //Branding page has been saved or the file is missing. Rewrite the file to disc. 110 if (themePageId > 0) 111 { 112 var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId); 113 themePageview.Redirect = false; 114 themePageview.Output(); 115 } 116 } 117 118 // Schema.org details for PDP 119 bool isProductDetailsPage = Dynamicweb.Context.Current.Request.QueryString.AllKeys.Contains("ProductID"); 120 bool isArticlePage = Model.ItemType == "Swift_Article"; 121 string schemaOrgType = string.Empty; 122 123 if (isProductDetailsPage) 124 { 125 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\""; 126 } 127 128 if (isArticlePage) 129 { 130 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\""; 131 } 132 133 134 var cssStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/styles.css")); 135 @* CS NT - custom Nextech stylesheet *@ 136 var cssStyleFileInfoNextech = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/nextech.css")); 137 @* CS NT - slick stylesheet *@ 138 var cssStyleFileInfoSlick = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/slick.css")); 139 @* CS NT - slick theme stylesheet *@ 140 var cssStyleFileInfoSlickTheme = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/slick-theme.css")); 141 142 143 144 145 var jsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/scripts.js")); 146 @*CS NT - include custom.js*@ 147 var jsFileInfoCustom = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/custom.js")); 148 @*CS NT - include slick.min.js*@ 149 var slickFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/slick.min.js")); 150 151 152 string masterTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("Theme")) ? " theme " + Model.Area.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 153 154 string favicon = Model.Area.Item.GetRawValueString("Favicon", "/Files/Templates/Designs/Swift/Assets/Images/favicon.png"); 155 string appleTouchIcon = Model.Area.Item.GetRawValueString("AppleTouchIcon", "/Files/Templates/Designs/Swift/Assets/Images/apple-touch-icon.png"); 156 157 string headerCssClass = "sticky-top"; 158 bool movePageBehind = false; 159 160 if (Model.PropertyItem != null) 161 { 162 headerCssClass = Model.PropertyItem.GetRawValueString("MoveThisPageBehindTheHeader", "sticky-top"); 163 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false; 164 } 165 166 headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass; 167 headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass; 168 169 string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID").Trim(); 170 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID").Trim(); 171 172 bool allowTracking = AllowTracking(); 173 174 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;"); 175 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/nextech.css?{cssStyleFileInfoNextech.LastWriteTime.Ticks}>; rel=preload; as=style;"); 176 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;"); 177 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/slick.css?{cssStyleFileInfoSlick.LastWriteTime.Ticks}>; rel=preload; as=style;"); 178 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/slick-theme.css?{cssStyleFileInfoSlickTheme.LastWriteTime.Ticks}>; rel=preload; as=style;"); 179 180 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}>; rel=preload; as=script;"); 181 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/custom.js?{jsFileInfoCustom.LastWriteTime.Ticks}; rel=preload; as=script;"); 182 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/slick.min.js?{slickFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;"); 183 184 185 SetMetaTags(); 186 187 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>(); 188 189 var masterPage = Pageview.Area.IsMaster ? Pageview.Page : Pageview.Page.MasterPage; 190 languages.Add(masterPage); 191 if (masterPage?.Languages != null) 192 { 193 foreach (var language in masterPage.Languages) 194 { 195 languages.Add(language); 196 } 197 } 198 199 Uri url = Dynamicweb.Context.Current.Request.Url; 200 string hostName = url.Host; 201 202 <!doctype html> 203 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName"> 204 <head> 205 <!-- @swiftVersion --> 206 @* Required meta tags *@ 207 <meta charset="utf-8"> 208 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0"> 209 <link rel="shortcut icon" href="@favicon"> 210 <link rel="apple-touch-icon" href="@appleTouchIcon"> 211 212 @*CS NT Jquery CDN*@ 213 <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> 214 215 @Model.MetaTags 216 217 218 219 @*CS NT Cookie script and raptor*@ 220 221 222 <!--Cookie Script Begin--> 223 <script type="text/javascript" charset="UTF-8" src="//cdn.cookie-script.com/s/0f7e74854350119f4ba7f565e3066cd6.js"></script> 224 <!--Cookie Script End--> 225 226 <!-- CS NT Staging? cookie script--> 227 <!--<script type="text/javascript" charset="UTF-8" src="//cdn.cookie-script.com/s/dfe7c945aeca99811bd22710360fd93f.js"></script>--> 228 229 230 <script type="text/javascript"> 231 let raptorPageViewSent = false; 232 233 window.addEventListener('CookieScriptAcceptAll', function() { 234 console.log('CookieScriptAcceptAll NT'); 235 236 if ('@googleTagManagerID' != '') 237 { 238 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 239 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 240 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 241 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 242 })(window,document,'script','dataLayer','@googleTagManagerID'); 243 } 244 245 246 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//az19942.vo.msecnd.net/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 247 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" }); 248 raptorPageViewSent = true; 249 }) 250 251 window.addEventListener('CookieScriptCategory-targeting', function() { 252 console.log('CookieScriptCategory-targeting NT'); 253 254 if ('@googleTagManagerID' != '') 255 { 256 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 257 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 258 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 259 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 260 })(window,document,'script','dataLayer','@googleTagManagerID'); 261 } 262 263 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//az19942.vo.msecnd.net/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 264 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" }); 265 raptorPageViewSent = true; 266 267 }) 268 269 window.addEventListener('CookieScriptAccept', function(e) { 270 console.log('CookieScriptAccept NT'); 271 //console.log(e.detail); 272 var i; 273 var targetingEnabled = false; 274 for (i = 0; i < e.detail.categories.length; ++i) { 275 if(e.detail.categories[i] =='targeting') 276 { 277 targetingEnabled = true; 278 } 279 console.log(e.detail.categories[i]); 280 } 281 console.log('targetingEnabled '+targetingEnabled); 282 if(targetingEnabled) 283 { 284 console.log('CookieScriptAccept targeting NT'); 285 286 if ('@googleTagManagerID' != '') 287 { 288 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 289 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 290 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 291 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 292 })(window,document,'script','dataLayer','@googleTagManagerID'); 293 } 294 295 296 (function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//az19942.vo.msecnd.net/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 297 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" }); 298 raptorPageViewSent = true; 299 } 300 }) 301 302 if(CookieScript.instance.currentState().categories.indexOf('targeting') >= 0) 303 { 304 if ('@googleTagManagerID' != '') 305 { 306 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 307 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 308 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 309 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 310 })(window,document,'script','dataLayer','@googleTagManagerID'); 311 } 312 } 313 if(!raptorPageViewSent && CookieScript.instance.currentState().action == 'accept') 314 { 315 console.log('CookieScript.instance.currentState().action = accept -> Calling pageview'); 316 317 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" }); 318 //(function (d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = "//az19942.vo.msecnd.net/script/raptor-3.0.min.js", g.async = "true", s.parentNode.insertBefore(g, s) }(document, "script")); 319 320 } 321 322 323 </script> 324 325 326 327 @{ 328 var alreadyWrittenTwoletterIsos = new List<string>(); 329 @* Languages meta data *@ 330 foreach (var language in languages) 331 { 332 hostName = url.Host; 333 if (language?.Area != null) 334 { 335 if (language.Area?.MasterArea != null && !string.IsNullOrEmpty(language.Area.MasterArea.DomainLock)) 336 { 337 hostName = language.Area.MasterArea.DomainLock; //dk.domain.com or dk-domain.dk 338 } 339 if (language != null && language.Area != null && language.Published && language.Area.Active && language.Area.Published) 340 { 341 if (!string.IsNullOrEmpty(language.Area.DomainLock)) 342 { 343 hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk 344 } 345 string querystring = $"Default.aspx?ID={language.ID}"; 346 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"])) 347 { 348 querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}"; 349 } 350 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 351 { 352 querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}"; 353 } 354 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"])) 355 { 356 querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}"; 357 } 358 359 string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring); 360 if (language.Area.RedirectFirstPage && language.ParentPageId == 0 && language.Sort == 1) 361 { 362 friendlyUrl = "/"; 363 } 364 string href = $"{url.Scheme}://{hostName}{friendlyUrl}"; 365 366 367 <link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href"> 368 if (!alreadyWrittenTwoletterIsos.Contains(language.Area.CultureInfo.TwoLetterISOLanguageName)) 369 { 370 alreadyWrittenTwoletterIsos.Add(language.Area.CultureInfo.TwoLetterISOLanguageName); 371 <link rel="alternate" hreflang="@language.Area.CultureInfo.TwoLetterISOLanguageName.ToLower()" href="@href"> 372 } 373 } 374 } 375 } 376 } 377 378 <title>@Model.Title</title> 379 @* Bootstrap + Swift stylesheet *@ 380 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 381 @* CS NT - custom Nextech stylesheet *@ 382 <link href="/Files/Templates/Designs/Swift/Assets/css/nextech.css?@cssStyleFileInfoNextech.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 383 @* CS NT - custom Slick stylesheet *@ 384 <link href="/Files/Templates/Designs/Swift/Assets/css/slick.css?@cssStyleFileInfoSlick.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 385 @* CS NT - Slick-theme stylesheet *@ 386 <link href="/Files/Templates/Designs/Swift/Assets/css/slick-theme.css?@cssStyleFileInfoSlickTheme.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css"> 387 388 @* Font Awesome CS NT *@ 389 <link href="/Files/Templates/Designs/Swift/Assets/fonts/FontAwesomeFree/css/fontawesome-all.min.css" rel="stylesheet" media="all" type="text/css"> 390 391 392 @* Flags css from Rapido CS NT *@ 393 <!-- Flag icon --> 394 <link rel="stylesheet" href="/Files/Templates/Designs/Swift/Assets/css/flag-icon.min.css" type="text/css"> 395 396 @if (disableWideBreakpoints != "disableBoth") 397 { 398 <style> 399 @@media ( min-width: 1600px ) { 400 .container-xxl, 401 .container-xl, 402 .container-lg, 403 .container-md, 404 .container-sm, 405 .container { 406 max-width: 1520px; 407 } 408 } 409 </style> 410 411 412 413 if (disableWideBreakpoints != "disableUltraWideOnly") 414 { 415 <style> 416 @@media ( min-width: 1920px ) { 417 .container-xxl, 418 .container-xl, 419 .container-lg, 420 .container-md, 421 .container-sm, 422 .container { 423 max-width: 1820px; 424 } 425 } 426 </style> 427 } 428 } 429 430 @* Branding and Themes min stylesheet *@ 431 <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"> 432 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks"></script> 433 434 435 @*CS NT - include custom.js*@ 436 <script src="/Files/Templates/Designs/Swift/Assets/js/custom.js?@jsFileInfoCustom.LastWriteTime.Ticks" defer></script> 437 @*CS NT - include slick.min.js*@ 438 <script src="/Files/Templates/Designs/Swift/Assets/js/slick.min.js?@slickFileInfo.LastWriteTime.Ticks" defer></script> 439 440 441 <script type="module"> 442 swift.Scroll.hideHeadersOnScroll(); 443 swift.Scroll.handleAlternativeTheme(); 444 445 //Only load if AOS 446 const aosColumns = document.querySelectorAll('[data-aos]'); 447 if (aosColumns.length > 0) { 448 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks', 'js'); 449 document.addEventListener('load.swift.assetloader', function () { 450 AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') }); 451 }); 452 } 453 </script> 454 455 @* Google gtag method - always include even if it is not used for anything *@ 456 <script> 457 window.dataLayer = window.dataLayer || []; 458 function gtag() { dataLayer.push(arguments); } 459 </script> 460 @* Google tag manager *@ 461 @if (false && !string.IsNullOrWhiteSpace(googleTagManagerID)) 462 { 463 <script> 464 gtag('consent', 'default', { 465 'ad_storage': 'denied', 466 'ad_user_data': 'denied', 467 'ad_personalization': 'denied', 468 'analytics_storage': 'denied' 469 }); 470 </script> 471 <script> 472 (function (w, d, s, l, i) { 473 w[l] = w[l] || []; w[l].push({ 474 'gtm.start': 475 new Date().getTime(), event: 'gtm.js' 476 }); var f = d.getElementsByTagName(s)[0], 477 j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 478 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); 479 })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)'); 480 </script> 481 if (allowTracking) 482 { 483 string adConsent = GetCookieOptInPermission("Marketing"); 484 string analyticsConsent = GetCookieOptInPermission("Statistical"); 485 <script> 486 gtag('consent', 'update', { 487 'ad_storage': '@adConsent', 488 'ad_user_data': '@adConsent', 489 'ad_personalization': '@adConsent', 490 'analytics_storage': '@analyticsConsent' 491 }); 492 </script> 493 } 494 } 495 496 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) 497 { 498 var GoogleAnalyticsDebugMode = ""; 499 500 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode")) 501 { 502 GoogleAnalyticsDebugMode = ", {'debug_mode': true}"; 503 } 504 505 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script> 506 <script> 507 gtag('js', new Date()); 508 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode); 509 </script> 510 } 511 512 @if (!string.IsNullOrWhiteSpace(customHeaderInclude)) 513 { 514 @RenderPartial($"Components/Custom/{customHeaderInclude}") 515 } 516 </head> 517 <body class="brand @(masterTheme)" id="page@(Model.ID)"> 518 519 @* Google tag manager *@ 520 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking) 521 { 522 <noscript> 523 <iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)" 524 height="0" width="0" style="display:none;visibility:hidden"></iframe> 525 </noscript> 526 } 527 528 @if (renderAsResponsive || !renderMobile) 529 { 530 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop"> 531 @if (headerDesktopLink != null) 532 { 533 @RenderGrid(headerDesktopLink.PageId) 534 } 535 </header> 536 } 537 538 @if ((renderAsResponsive || renderMobile)) 539 { 540 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile"> 541 @if (headerMobileLink != null) 542 { 543 @RenderGrid(headerMobileLink.PageId) 544 } 545 </header> 546 } 547 548 <div data-intersect></div> 549 550 <main id="content" @(schemaOrgType)> 551 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 552 @using System 553 @using Dynamicweb.Ecommerce.ProductCatalog 554 555 556 @{ 557 string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty; 558 bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop"; 559 560 bool isArticlePagePage = Model.ItemType == "Swift_Article"; 561 bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage"; 562 string schemaOrgProp = string.Empty; 563 if(isArticlePagePage) 564 { 565 schemaOrgProp = "itemprop=\"articleBody\""; 566 } 567 568 string theme = ""; 569 string gridContent = ""; 570 571 if (Model.PropertyItem != null) 572 { 573 theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 574 } 575 576 if (Model.Item != null || Pageview.IsVisualEditorMode) 577 { 578 if (!isProductDetail) 579 { 580 gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page"); 581 } 582 else 583 { 584 var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId); 585 var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty; 586 var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage"); 587 588 @RenderGrid(detailPageId) 589 } 590 } 591 592 bool doNotRenderPage = false; 593 594 //Check if we are on the poduct detail page, and if there is data to render 595 ProductViewModel product = new ProductViewModel(); 596 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 597 { 598 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 599 if (string.IsNullOrEmpty(product.Id)) { 600 doNotRenderPage = true; 601 } 602 } 603 604 //Render the page 605 if (!doNotRenderPage) { 606 string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page"; 607 608 if (Pageview.IsVisualEditorMode) { 609 @Model.Placeholder("dwcontent", "content", "default:true;sort:1") 610 } 611 612 <div class="@theme @itemIdentifier" @schemaOrgProp> 613 @if (isArticleListPage) 614 { 615 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\""; 616 617 <form @hx id="ArticleFacetForm"> 618 @gridContent 619 </form> 620 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/htmx.js"></script> 621 <script type="module"> 622 document.addEventListener('htmx:confirm', (event) => { 623 let filters = event.detail.elt.querySelectorAll('select'); 624 for (var i = 0; i < filters.length; i++) { 625 let input = filters[i]; 626 if (input.name && !input.value) { 627 input.name = ''; 628 } 629 } 630 }); 631 632 document.addEventListener('htmx:beforeOnLoad', (event) => { 633 swift.Scroll.stopIntersectionObserver(); 634 }); 635 636 document.addEventListener('htmx:afterOnLoad', () => { 637 swift.Scroll.hideHeadersOnScroll(); 638 swift.Scroll.handleAlternativeTheme(); 639 }); 640 </script> 641 } 642 else 643 { 644 @gridContent 645 } 646 </div> 647 648 } else { 649 <div class="container"> 650 <div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div> 651 </div> 652 } 653 654 if (!Model.IsCurrentUserAllowed) 655 { 656 int signInPage = GetPageIdByNavigationTag("SignInPage"); 657 int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage"); 658 659 if (!Pageview.IsVisualEditorMode) 660 { 661 if (signInPage != 0) 662 { 663 if (signInPage != Model.ID) { 664 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage); 665 } else { 666 if (dashboardPage != 0) { 667 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage); 668 } else { 669 Dynamicweb.Context.Current.Response.Redirect("/"); 670 } 671 } 672 } 673 else 674 { 675 <div class="alert alert-dark m-0" role="alert"> 676 <span>@Translate("You do not have access to this page")</span> 677 </div> 678 } 679 } 680 else 681 { 682 <div class="alert alert-dark m-0" role="alert"> 683 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span> 684 </div> 685 } 686 } 687 } 688 689 </main> 690 691 @if (renderAsResponsive || !renderMobile) 692 { 693 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop"> 694 @if (footerDesktopLink != null) 695 { 696 @RenderGrid(footerDesktopLink.PageId) 697 } 698 </footer> 699 } 700 701 @if (renderAsResponsive || renderMobile) 702 { 703 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile"> 704 @if (footerMobileLink != null) 705 { 706 @RenderGrid(footerMobileLink.PageId) 707 } 708 </footer> 709 } 710 711 @* Render any offcanvas menu here *@ 712 @RenderSnippet("offcanvas") 713 714 @{ 715 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]); 716 } 717 718 @* Language selector modal *@ 719 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true"> 720 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent"> 721 @* The content here comes from an external request *@ 722 </div> 723 </div> 724 725 @* Favorite toast *@ 726 <div aria-live="polite" aria-atomic="true"> 727 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11"> 728 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> 729 <div class="toast-header"> 730 <strong class="me-auto">@Translate("Favorite list updated")</strong> 731 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 732 </div> 733 <div class="toast-body d-flex gap-3"> 734 <div id="favoriteNotificationToast_Image"></div> 735 <div id="favoriteNotificationToast_Text"></div> 736 </div> 737 </div> 738 </div> 739 </div> 740 741 @* Modal for dynamic content *@ 742 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true"> 743 <div class="modal-dialog modal-dialog-centered modal-md"> 744 <div class="modal-content theme light" id="DynamicModalContent"> 745 @* The content here comes from an external request *@ 746 </div> 747 </div> 748 </div> 749 750 @* Offcanvas for dynamic content *@ 751 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas"> 752 @* The content here comes from an external request *@ 753 </div> 754 755 @if (Model.Area.Item.GetBoolean("ShowErpDownMessage") && !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"])) 756 { 757 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light"; 758 759 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040"> 760 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true"> 761 <div class="toast-header"> 762 <strong class="me-auto">@Translate("Connection down")</strong> 763 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> 764 </div> 765 <div class="toast-body"> 766 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.") 767 </div> 768 </div> 769 </div> 770 } 771 772 @if (miniCartEnabled) 773 { 774 @* Open MiniCart when the cart is updated *@ 775 <script type="module"> 776 document.addEventListener('updated.swift.cart', (event) => { 777 let orderContext = event?.detail?.formData?.get("OrderContext"); 778 updateCartSummary(orderContext); 779 780 @if (offcanvasMiniCartBehaviour == "2" || offcanvasMiniCartBehaviour == "3") { 781 <text>openMiniCartOffcanvas();</text> 782 } 783 }); 784 </script> 785 786 if (offcanvasMiniCartBehaviour == "1" || offcanvasMiniCartBehaviour == "3") 787 { 788 @* Open MiniCart when toggle is clicked *@ 789 <script type="module"> 790 let miniCartToggles = document.querySelectorAll('.mini-cart-quantity'); 791 miniCartToggles?.forEach((toggle) => { 792 toggle.parentElement.addEventListener('click', (event) => { 793 event.preventDefault(); 794 let orderContext = toggle.dataset?.orderContext; 795 updateCartSummary(orderContext); 796 797 openMiniCartOffcanvas(); 798 }); 799 }); 800 </script> 801 } 802 803 <script> 804 805 const updateCartSummary = (orderContext) => { 806 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 807 swift.PageUpdater.UpdateFromUrlInline(event, '/Default.aspx?ID=@(cartSummaryPageId)&CartType=minicart&RequestPageID=@(Pageview.Page.ID)&OrderContext=' + orderContext +'', 'Swift_CartSummary.cshtml', dynamicOffcanvas); 808 }; 809 810 const openMiniCartOffcanvas = () => { 811 const dynamicOffcanvas = document.getElementById('DynamicOffcanvas'); 812 const miniCartOffcanvas = bootstrap.Offcanvas.getOrCreateInstance(dynamicOffcanvas); 813 dynamicOffcanvas.classList.add('overflow-y-auto'); 814 815 if (!miniCartOffcanvas._isShown) { 816 miniCartOffcanvas.show(); 817 hideActiveOffcanvases(miniCartOffcanvas); 818 } 819 }; 820 821 const hideActiveOffcanvases = (miniCartOffcanvas) => { 822 let activeOffcanvases = document.querySelectorAll('.offcanvas.show'); 823 activeOffcanvases?.forEach((offCanvas) => { 824 offCanvas = bootstrap.Offcanvas.getInstance(offCanvas); 825 if (offCanvas !== miniCartOffcanvas) { 826 offCanvas.hide(); 827 } 828 }); 829 }; 830 831 </script> 832 } 833 834 </body> 835 836 </html> 837 838 } 839 else if (Pageview.IsVisualEditorMode) 840 { 841 <head> 842 <title>@Model.Title</title> 843 @* Bootstrap + Swift stylesheet *@ 844 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css" rel="stylesheet" media="all" type="text/css"> 845 </head> 846 <body class="p-3"> 847 <div class="alert alert-danger" role="alert"> 848 @Translate("Basic Swift setup is needed!") 849 </div> 850 851 @if (brandingPage == null) 852 { 853 <div class="alert alert-warning" role="alert"> 854 @Translate("Please add a Branding page and reference it in website settings") 855 </div> 856 } 857 858 @if (themesParagraphs == null) 859 { 860 <div class="alert alert-warning" role="alert"> 861 @Translate("Please add a Themes collection page and reference it in website settings") 862 </div> 863 } 864 </body> 865 } 866 867 868 @functions { 869 void SetMetaTags() 870 { 871 //Verification Tokens 872 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : ""; 873 874 //Generic Site Values 875 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : ""; 876 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : ""; 877 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : ""; 878 879 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : ""; 880 881 //Page specific values 882 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : ""; 883 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image"); 884 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : ""; 885 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : ""; 886 887 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : ""; 888 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : ""; 889 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : ""; 890 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image"); 891 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : ""; 892 893 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"])) 894 { 895 if (!string.IsNullOrEmpty(Model.Description)) 896 { 897 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{Model.Description}\">"); 898 } 899 else 900 { 901 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{openGraphDescription}\">"); 902 } 903 904 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 905 { 906 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}\">"); 907 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}\">"); 908 } 909 else if (openGraphImage != null) 910 { 911 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 912 Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\">"); 913 } 914 915 if (!string.IsNullOrEmpty(openGraphImageALT)) 916 { 917 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{openGraphImageALT}\">"); 918 } 919 if (!string.IsNullOrEmpty(twitterCardDescription)) 920 { 921 Pageview.Meta.AddTag("twitter:description", twitterCardDescription); 922 } 923 924 if (!string.IsNullOrEmpty(Pageview.Page.TopImage)) 925 { 926 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}"); 927 } 928 else if (twitterCardImage != null) 929 { 930 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}"); 931 } 932 933 if (!string.IsNullOrEmpty(twitterCardImageALT)) 934 { 935 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT); 936 } 937 } 938 939 if (!string.IsNullOrEmpty(siteVerificationGoogle)) 940 { 941 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle); 942 } 943 944 if (!string.IsNullOrEmpty(openGraphFacebookAppID)) 945 { 946 Pageview.Meta.AddTag($"<meta property=\"fb:app_id\" content=\"{openGraphFacebookAppID}\">"); 947 } 948 949 if (!string.IsNullOrEmpty(openGraphType)) 950 { 951 Pageview.Meta.AddTag($"<meta property=\"og:type\" content=\"{openGraphType}\">"); 952 } 953 954 if (!string.IsNullOrEmpty(openGraphSiteName)) 955 { 956 Pageview.Meta.AddTag($"<meta property=\"og:url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Pageview.SearchFriendlyUrl}\">"); 957 } 958 959 if (!string.IsNullOrEmpty(openGraphSiteName)) 960 { 961 Pageview.Meta.AddTag($"<meta property=\"og:site_name\" content=\"{openGraphSiteName}\">"); 962 } 963 964 if (!string.IsNullOrEmpty(Model.Title)) 965 { 966 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{Model.Title}\">"); 967 } 968 else 969 { 970 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{openGraphSiteTitle}\">"); 971 } 972 973 if (!string.IsNullOrEmpty(twitterCardSite)) 974 { 975 Pageview.Meta.AddTag("twitter:site", twitterCardSite); 976 } 977 978 if (!string.IsNullOrEmpty(twitterCardURL)) 979 { 980 Pageview.Meta.AddTag("twitter:url", twitterCardURL); 981 } 982 983 if (!string.IsNullOrEmpty(twitterCardTitle)) 984 { 985 Pageview.Meta.AddTag("twitter:title", twitterCardTitle); 986 } 987 } 988 } 989