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