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