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 system cannot find the file specified
   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_6659f9fb3e654c8680acf0e3718c5541.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 583
   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:2,State:0,Class:20

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