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