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