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