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_fb1119f0adca481e96b0d674809f6d0f.Execute() in C:\inetpub\wwwroot\DWShop2023\Solutions\Swift_v1.21.0\Files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 352
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:2,State:0,Class:20
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
2 @using System
3 @using Dynamicweb
4 @using Dynamicweb.Environment
5 @using Dynamicweb.Frontend
6
7 @{
8 string pageDomain = Pageview.Area.UrlName;
9 var basePageUrl = "";
10 var pageURL = "";
11
12 var alternatePageAddress = Dynamicweb.Context.Current.Request.RawUrl.Split('?')[0].Replace("/products/","/proizvodi/").Replace("/"+pageDomain+"/","").Replace("/"+pageDomain,"");
13 alternatePageAddress = alternatePageAddress.Length > 1 ? alternatePageAddress : "";
14
15 string swiftVersion = ReadFile("/Files/Templates/Designs/Swift/swift_version.txt");
16 bool renderAsResponsive = Model.Area.Item.GetString("DeviceRendering", "responsive").Equals("responsive", StringComparison.OrdinalIgnoreCase);
17 bool renderMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet;
18 string responsiveClassDesktop = string.Empty;
19 string responsiveClassMobile = string.Empty;
20 if (renderAsResponsive)
21 {
22 responsiveClassDesktop = " d-none d-xl-block";
23 responsiveClassMobile = " d-block d-xl-none";
24 }
25
26 var disableWideBreakpoints = Model.Area?.Item?.GetRawValueString("DisableWideBreakpoints", "default");
27
28 var brandingPageId = Model.Area.Item.GetLink("BrandingPage") != null ? Model.Area.Item.GetLink("BrandingPage").PageId : 0;
29 var themePageId = Model.Area.Item.GetLink("ThemesPage") != null ? Model.Area.Item.GetLink("ThemesPage").PageId : 0;
30 string customHeaderInclude = Model.Area.Item.GetFile("CustomHeaderInclude") != null ? Model.Area.Item.GetFile("CustomHeaderInclude").Name : string.Empty;
31
32 var brandingPage = Dynamicweb.Content.Services.Pages?.GetPage(brandingPageId) ?? null;
33 var themesParagraphLastChanged = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(themePageId).OrderByDescending(p => p.Audit.LastModifiedAt).FirstOrDefault();
34
35 var cssLastModified = brandingPage.Audit.LastModifiedAt > themesParagraphLastChanged.Audit.LastModifiedAt ? brandingPage.Audit.LastModifiedAt : themesParagraphLastChanged.Audit.LastModifiedAt;
36 var cssThemeAndBrandingStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath($"/Files/Templates/Designs/Swift/_parsed/Swift_css/Swift_styles_{Model.Area.ID}.min.css"));
37
38 // Schema.org details for PDP
39 string productId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : "";
40 bool isProductDetailsPage = !string.IsNullOrEmpty(productId);
41 bool isArticlePage = Model.ItemType == "Swift_Article";
42 string schemaOrgType = string.Empty;
43
44 if (isProductDetailsPage)
45 {
46 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Product\"";
47 }
48
49 if (isArticlePage)
50 {
51 schemaOrgType = "itemscope=\"\" itemtype=\"https://schema.org/Article\"";
52 }
53
54 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < brandingPage.Audit.LastModifiedAt)
55 {
56 //Branding page has been saved or the file is missing. Rewrite the file to disc.
57 if (brandingPageId > 0)
58 {
59 var brandingPageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(brandingPageId);
60 brandingPageview.Redirect = false;
61 brandingPageview.Output();
62 }
63 }
64
65 if (!cssThemeAndBrandingStyleFileInfo.Exists || cssThemeAndBrandingStyleFileInfo.LastWriteTime < themesParagraphLastChanged.Audit.LastModifiedAt)
66 {
67 //Branding page has been saved or the file is missing. Rewrite the file to disc.
68 if (themePageId > 0)
69 {
70 var themePageview = Dynamicweb.Frontend.PageView.GetPageviewByPageID(themePageId);
71 themePageview.Redirect = false;
72 themePageview.Output();
73 }
74 }
75
76 var cssStyleFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/css/styles.css"));
77 var jsFileInfo = new System.IO.FileInfo(Dynamicweb.Core.SystemInformation.MapPath("/Files/Templates/Designs/Swift/Assets/js/scripts.js"));
78
79 string masterTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("Theme")) ? " theme " + Model.Area.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
80
81 string favicon = Model.Area.Item.GetFile("Favicon") != null ? Model.Area.Item.GetFile("Favicon").Path : "/Files/Templates/Designs/Swift/Assets/Images/favicon.png";
82
83 string headerCssClass = "sticky-top";
84 bool movePageBehind = false;
85
86 if (Pageview.Page.PropertyItem != null)
87 {
88 headerCssClass = Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"] != null ? Pageview.Page.PropertyItem["MoveThisPageBehindTheHeader"].ToString() : "sticky-top";
89 movePageBehind = headerCssClass == "fixed-top" && !Pageview.IsVisualEditorMode ? true : false;
90 }
91
92 headerCssClass = headerCssClass == "" ? "sticky-top" : headerCssClass;
93 headerCssClass = Pageview.IsVisualEditorMode ? "" : headerCssClass;
94
95 string googleTagManagerID = Model.Area.Item.GetString("GoogleTagManagerID");
96 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID");
97 var cookieOptInLevel = CookieManager.GetCookieOptInLevel();
98 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical"));
99
100 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;");
101 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;");
102 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/aos.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
103 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
104 //Dynamicweb.Context.Current.Response.Flush(); //This sends the headers where we are now in the rendering making the TTFB faster
105
106 SetMetaTags();
107
108 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>();
109
110 if (Pageview.Area.IsMaster)
111 {
112 languages.Add(Pageview.Page);
113 if (Pageview.Page.Languages != null)
114 {
115 foreach (var language in Pageview.Page.Languages)
116 {
117 languages.Add(language);
118 }
119 }
120 }
121 else
122 {
123 languages.Add(Pageview.Page.MasterPage);
124 if (Pageview.Page.MasterPage != null)
125 {
126 if (Pageview.Page.MasterPage.Languages != null)
127 {
128 foreach (var language in Pageview.Page.MasterPage.Languages)
129 {
130 languages.Add(language);
131 }
132 }
133 }
134 }
135
136 string siteLanguage = Pageview.Area.CultureInfo.Name;
137 Uri url = Dynamicweb.Context.Current.Request.Url;
138 string hostName = url.Host; // domain.com/da-dk or domain.com/en-us
139
140 var ecomCountries = Dynamicweb.Ecommerce.Services.Countries.GetCountries();
141 var ecomCurrencies = Dynamicweb.Ecommerce.Services.Currencies.GetAllCurrencies();
142 }
143 <!doctype html>
144 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName">
145 <head>
146 <!-- @swiftVersion -->
147 @* Required meta tags *@
148 <meta charset="utf-8">
149 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0">
150 <link rel="shortcut icon" href="@favicon">
151 <link rel="apple-touch-icon" href="/Files/Templates/Designs/Swift/Assets/Images/logo_transparent.png">
152
153 @* Preventing page from caching because of not loading cart content
154 Dignet 28.07.2023.
155 *@
156 <meta http-equiv="cache-control" content="max-age=0">
157 <meta http-equiv="cache-control" content="no-cache">
158 <meta http-equiv="expires" content="-1">
159 <meta http-equiv="expires" content="Tue, 01 Jan 1980 11:00:00 GMT">
160 <meta http-equiv="pragma" content="no-cache">
161 @*------- end Dignet 28.07.2023. *@
162
163 @Model.MetaTags
164
165 <title>@Model.Title</title>
166 @* Bootstrap + Swift stylesheet *@
167 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css">
168
169 @{
170 basePageUrl = url.Host;
171 pageURL = (basePageUrl.Substring(basePageUrl.Length - 3, 3) == "com" ? "/in-en" : "/hr-hr") + pageURL;
172 }
173 <link rel="canonical" href="https://@basePageUrl@pageURL" />
174 <link rel="alternate" href="https://@basePageUrl/hr-hr/@alternatePageAddress" hreflang="hr-hr" />
175
176 @{
177 basePageUrl = basePageUrl.Replace(".hr", ".com");
178 alternatePageAddress = Dynamicweb.Context.Current.Request.RawUrl.Split('?')[0].Replace("/proizvodi/","/products/").Replace("/"+pageDomain+"/","").Replace("/"+pageDomain,"");
179 alternatePageAddress = alternatePageAddress.Length > 1 ? alternatePageAddress : "";
180 }
181
182 <link rel="alternate" href="https://@basePageUrl/eu-en/@alternatePageAddress" hreflang="en-eu" />
183 <link rel="alternate" href="https://@basePageUrl/na-en/@alternatePageAddress" hreflang="en-ca" />
184 <link rel="alternate" href="https://@basePageUrl/na-en/@alternatePageAddress" hreflang="en-us" />
185 <link rel="alternate" href="https://@basePageUrl/ch-en/@alternatePageAddress" hreflang="en-cn" />
186 <link rel="alternate" href="https://@basePageUrl/jp-en/@alternatePageAddress" hreflang="en-jp" />
187 <link rel="alternate" href="https://@basePageUrl/sa-en/@alternatePageAddress" hreflang="es-xl" />
188 <link rel="alternate" href="https://@basePageUrl/uk-en/@alternatePageAddress" hreflang="en-gb" />
189 <link rel="alternate" href="https://@basePageUrl/au-en/@alternatePageAddress" hreflang="en-au" />
190 <link rel="alternate" href="https://@basePageUrl/in-en/@alternatePageAddress" hreflang="en" />
191 <link rel="alternate" href="https://@basePageUrl/in-en/@alternatePageAddress" hreflang="x-default" />
192
193
194
195
196
197
198 @if (disableWideBreakpoints != "disableBoth")
199 {
200 <style>
201 @@media ( min-width: 1600px ) {
202 .container-xxl,
203 .container-xl,
204 .container-lg,
205 .container-md,
206 .container-sm,
207 .container {
208 max-width: 1520px;
209 }
210 }
211 </style>
212
213
214
215 if (disableWideBreakpoints != "disableUltraWideOnly")
216 {
217 <style>
218 @@media ( min-width: 1920px ) {
219 .container-xxl,
220 .container-xl,
221 .container-lg,
222 .container-md,
223 .container-sm,
224 .container {
225 max-width: 1820px;
226 }
227 }
228 </style>
229 }
230 }
231
232 @* Branding and Themes min stylesheet *@
233 <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">
234 <script src="/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
235 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
236
237 <script type="module">
238 AOS.init({ duration: 400, delay: 100, easing: 'ease-in-out', mirror: false, disable: window.matchMedia('(prefers-reduced-motion: reduce)') });
239 swift.Scroll.hideHeadersOnScroll();
240 swift.Scroll.handleAlternativeTheme();
241 </script>
242
243 @* Google tag manager *@
244 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking)
245 {
246 <script>
247 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
248 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
249 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
250 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
251 })(window, document, 'script', 'dataLayer', '@(googleTagManagerID)');
252
253 function gtag() { dataLayer.push(arguments); }
254 </script>
255 }
256
257 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
258 {
259 var GoogleAnalyticsDebugMode = "";
260 bool isLoggedInBackendUser = false;
261
262 if (Dynamicweb.Security.UserManagement.User.GetCurrentBackendUser() != null)
263 {
264 isLoggedInBackendUser = true;
265 }
266
267 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode") && isLoggedInBackendUser)
268 {
269 GoogleAnalyticsDebugMode = ", {'debug_mode': true}";
270 }
271
272 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script>
273 <script>
274 window.dataLayer = window.dataLayer || [];
275 function gtag() { dataLayer.push(arguments); }
276 gtag('js', new Date());
277 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode);
278 </script>
279 }
280
281 @if (!string.IsNullOrWhiteSpace(customHeaderInclude))
282 {
283 @RenderPartial($"Components/Custom/{customHeaderInclude}")
284 }
285 </head>
286 <body class="brand @(masterTheme)" id="page@(Model.ID)" onload="checkCookie()">
287
288 @* Google tag manager *@
289 @if (!string.IsNullOrWhiteSpace(googleTagManagerID) && allowTracking)
290 {
291 <noscript>
292 <iframe src="https://www.googletagmanager.com/ns.html?id=@(googleTagManagerID)"
293 height="0" width="0" style="display:none;visibility:hidden"></iframe>
294 </noscript>
295 }
296
297 @if (renderAsResponsive || !renderMobile)
298 {
299 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop">
300 @if (@Model.Area.Item.GetLink("HeaderDesktop") != null)
301 {
302 @RenderGrid(@Model.Area.Item.GetLink("HeaderDesktop").PageId)
303 }
304 </header>
305 }
306
307 @if ((renderAsResponsive || renderMobile))
308 {
309 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile">
310 @if (@Model.Area.Item.GetLink("HeaderMobile") != null)
311 {
312 @RenderGrid(@Model.Area.Item.GetLink("HeaderMobile").PageId)
313 }
314 </header>
315 }
316
317 <main id="content" @(schemaOrgType)>
318 <div data-intersect></div>
319 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
320 @using System
321 @using Dynamicweb.Ecommerce.ProductCatalog
322
323
324 @{
325 string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty;
326 bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop";
327
328 bool isArticlePagePage = Model.ItemType == "Swift_Article";
329 bool isArticleListPage = Model.ItemType == "Swift_ArticleListPage";
330 string schemaOrgProp = string.Empty;
331 if(isArticlePagePage)
332 {
333 schemaOrgProp = "itemprop=\"articleBody\"";
334 }
335
336 string theme = "";
337 string gridContent = "";
338
339 if (Model.PropertyItem != null)
340 {
341 theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? "theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
342 }
343
344 if (Model.Item != null || Pageview.IsVisualEditorMode)
345 {
346 if (!isProductDetail)
347 {
348 gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page");
349 }
350 else
351 {
352 var productObject = Dynamicweb.Ecommerce.Services.Products.GetProductById(productIdFromUrl, "", Pageview.Area.EcomLanguageId);
353 var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty;
354 var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage");
355
356 @RenderGrid(detailPageId)
357 }
358 }
359
360 bool doNotRenderPage = false;
361
362 //Check if we are on the poduct detail page, and if there is data to render
363 ProductViewModel product = new ProductViewModel();
364 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
365 {
366 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
367 if (string.IsNullOrEmpty(product.Id)) {
368 doNotRenderPage = true;
369 }
370 }
371
372 //Render the page
373 if (!doNotRenderPage) {
374 string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page";
375
376
377 <div class="@theme @itemIdentifier" @schemaOrgProp>
378 @if (isArticleListPage)
379 {
380 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\"";
381
382 <form @hx id="ArticleFacetForm">
383 @gridContent
384 </form>
385 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/htmx.js"></script>
386 <script type="module">
387 document.addEventListener('htmx:confirm', (event) => {
388 let filters = event.detail.elt.querySelectorAll('select');
389 for (var i = 0; i < filters.length; i++) {
390 let input = filters[i];
391 if (input.name && !input.value) {
392 input.name = '';
393 }
394 }
395 });
396
397 document.addEventListener('htmx:beforeOnLoad', (event) => {
398 swift.Scroll.stopIntersectionObserver();
399 });
400
401 document.addEventListener('htmx:afterOnLoad', () => {
402 swift.Scroll.hideHeadersOnScroll();
403 swift.Scroll.handleAlternativeTheme();
404 });
405 </script>
406 }
407 else
408 {
409 @gridContent
410 }
411 </div>
412
413 } else {
414 <div class="container">
415 <div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div>
416 </div>
417 }
418
419 if (!Model.IsCurrentUserAllowed)
420 {
421 int signInPage = GetPageIdByNavigationTag("SignInPage");
422 int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage");
423
424 if (!Pageview.IsVisualEditorMode)
425 {
426 if (signInPage != 0)
427 {
428 if (signInPage != Model.ID) {
429 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage);
430 } else {
431 if (dashboardPage != 0) {
432 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage);
433 } else {
434 Dynamicweb.Context.Current.Response.Redirect("/");
435 }
436 }
437 }
438 else
439 {
440 <div class="alert alert-dark m-0" role="alert">
441 <span>@Translate("You do not have access to this page")</span>
442 </div>
443 }
444 }
445 else
446 {
447 <div class="alert alert-dark m-0" role="alert">
448 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span>
449 </div>
450 }
451 }
452 }
453
454 </main>
455
456 @if (renderAsResponsive || !renderMobile)
457 {
458 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop">
459 @if (@Model.Area.Item.GetLink("FooterDesktop") != null)
460 {
461 @RenderGrid(@Model.Area.Item.GetLink("FooterDesktop").PageId)
462 }
463 </footer>
464 }
465
466 @if (renderAsResponsive || renderMobile)
467 {
468 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile">
469 @if (@Model.Area.Item.GetLink("FooterMobile") != null)
470 {
471 @RenderGrid(@Model.Area.Item.GetLink("FooterMobile").PageId)
472 }
473 </footer>
474 }
475
476 @* Render any offcanvas menu here *@
477 @RenderSnippet("offcanvas")
478
479 @{
480 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Context.Current.Items["IsWebServiceConnectionAvailable"]);
481 }
482
483 @* Language selector modal *@
484 @if (languages.Count > 1 || ecomCountries.Count > 1 || ecomCurrencies.Count() > 1)
485 {
486 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true">
487 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent">
488 @* The content here comes from an external request *@
489 </div>
490 </div>
491 }
492
493 @* Favorite toast *@
494 <div aria-live="polite" aria-atomic="true">
495 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
496 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
497 <div class="toast-header">
498 <strong class="me-auto">@Translate("Favorite list updated")</strong>
499 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
500 </div>
501 <div class="toast-body d-flex gap-3">
502 <div id="favoriteNotificationToast_Image"></div>
503 <div id="favoriteNotificationToast_Text"></div>
504 </div>
505 </div>
506 </div>
507 </div>
508
509 @* Modal for dynamic content *@
510 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true">
511 <div class="modal-dialog modal-dialog-centered modal-md">
512 <div class="modal-content theme light" id="DynamicModalContent">
513 @* The content here comes from an external request *@
514 </div>
515 </div>
516 </div>
517
518 @* Offcanvas for dynamic content *@
519 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas" style="width: 30rem">
520 @* The content here comes from an external request *@
521 </div>
522
523 @if (isErpConnectionDown && Model.Area.Item.GetBoolean("ShowErpDownMessage"))
524 {
525 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light";
526
527 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040">
528 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true">
529 <div class="toast-header">
530 <strong class="me-auto">@Translate("Connection down")</strong>
531 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
532 </div>
533 <div class="toast-body">
534 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.")
535 </div>
536 </div>
537 </div>
538 }
539
540 </body>
541 </html>
542 @functions {
543 void SetMetaTags()
544 {
545 //Verification Tokens
546 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : "";
547 //string siteVerificationYandex = Model.Area.Item.GetString("Yandex_Verification") != null ? Model.Area.Item.GetString("Yandex_Verification") : "";
548 //string siteVerificationMS = Model.Area.Item.GetString("Msvalidate_01") != null ? Model.Area.Item.GetString("Msvalidate_01") : "";
549 //string siteVerificationAlexa = Model.Area.Item.GetString("AlexaVerifyID") != null ? Model.Area.Item.GetString("AlexaVerifyID") : "";
550 //string siteVerificationPinterest = Model.Area.Item.GetString("P_domain_verify") != null ? Model.Area.Item.GetString("P_domain_verify") : "";
551 //string siteVerificationNorton = Model.Area.Item.GetString("Norton_safeweb_site_verification") != null ? Model.Area.Item.GetString("Norton_safeweb_site_verification") : "";
552
553 //Generic Site Values
554 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : "";
555 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : "";
556 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : "";
557
558 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : "";
559
560 //Page specific values
561 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : "";
562 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image");
563 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : "";
564 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : "";
565
566 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : "";
567 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : "";
568 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : "";
569 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image");
570 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : "";
571
572 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"]))
573 {
574 if (!string.IsNullOrEmpty(Model.Description))
575 {
576 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{Model.Description}\" />");
577 }
578 else
579 {
580 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{openGraphDescription}\" />");
581 }
582
583 if (!string.IsNullOrEmpty(Pageview.Page.TopImage))
584 {
585 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}\" />");
586 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}\" />");
587 }
588 else if (openGraphImage != null)
589 {
590 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\" />");
591 Pageview.Meta.AddTag($"<meta property=\"og:image:secure_url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}\" />");
592 }
593
594 if (!string.IsNullOrEmpty(openGraphImageALT))
595 {
596 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{openGraphImageALT}\" />");
597 }
598 if (!string.IsNullOrEmpty(twitterCardDescription))
599 {
600 Pageview.Meta.AddTag("twitter:description", twitterCardDescription);
601 }
602
603 if (!string.IsNullOrEmpty(Pageview.Page.TopImage))
604 {
605 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}/Files{Pageview.Page.TopImage}");
606 }
607 else if (twitterCardImage != null)
608 {
609 Pageview.Meta.AddTag("twitter:image", $"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{openGraphImage.Path}");
610 }
611
612 if (!string.IsNullOrEmpty(twitterCardImageALT))
613 {
614 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT);
615 }
616 }
617
618 if (!string.IsNullOrEmpty(siteVerificationGoogle))
619 {
620 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle);
621 }
622
623 if (!string.IsNullOrEmpty(openGraphFacebookAppID))
624 {
625 Pageview.Meta.AddTag($"<meta property=\"fb:app_id\" content=\"{openGraphFacebookAppID}\" />");
626 }
627
628 if (!string.IsNullOrEmpty(openGraphType))
629 {
630 Pageview.Meta.AddTag($"<meta property=\"og:type\" content=\"{openGraphType}\" />");
631 }
632
633 if (!string.IsNullOrEmpty(openGraphSiteName))
634 {
635 Pageview.Meta.AddTag($"<meta property=\"og:url\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Pageview.SearchFriendlyUrl}\" />");
636 }
637
638 if (!string.IsNullOrEmpty(openGraphSiteName))
639 {
640 Pageview.Meta.AddTag($"<meta property=\"og:site_name\" content=\"{openGraphSiteName}\" />");
641 }
642
643 if (!string.IsNullOrEmpty(Model.Title))
644 {
645 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{Model.Title}\" />");
646 }
647 else
648 {
649 Pageview.Meta.AddTag($"<meta property=\"og:title\" content=\"{openGraphSiteTitle}\" />");
650 }
651
652 if (!string.IsNullOrEmpty(twitterCardSite))
653 {
654 Pageview.Meta.AddTag("twitter:site", twitterCardSite);
655 }
656
657 if (!string.IsNullOrEmpty(twitterCardURL))
658 {
659 Pageview.Meta.AddTag("twitter:url", twitterCardURL);
660 }
661
662 if (!string.IsNullOrEmpty(twitterCardTitle))
663 {
664 Pageview.Meta.AddTag("twitter:title", twitterCardTitle);
665 }
666 }
667 }
668 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
669
670 @using System
671 @using Dynamicweb
672 @using Dynamicweb.Environment
673 @using Dynamicweb.Frontend
674 @using System.Web
675 @using System.Web.SessionState
676
677 @{
678 var sessionRegion =(string)Dynamicweb.Context.Current.Session["selectedregion"];
679 var hostNameForRedirect = Dynamicweb.Context.Current.Request.Url.Host.Replace(".hr", ".com");
680 string HostPageLink = @Dynamicweb.Context.Current.Request.Url.Host;
681 }
682
683 <div id="regionSelector" class="changeLocationDiv" style="display: none;">
684 <div class="chooseLangMain">
685 <div>Please select a location to continue:</div>
686 <div class="languages">
687 <div class="firstRowLang langColumn">
688 <p><a href="https://@hostNameForRedirect/eu-en/?CurrencyCode=EUR&region=EU&cartcmd=emptycart" onclick="createCookie2()">European Union (EUR)</a></p>
689 <p><a href="https://@hostNameForRedirect/na-en/?CurrencyCode=USD&region=NA&cartcmd=emptycart" onclick="createCookie2()">US & Canada (USD)</a></p>
690 <p><a href="https://@hostNameForRedirect/ch-en/?CurrencyCode=CNY&region=CH&cartcmd=emptycart" onclick="createCookie2()">China (CNY)</a></p>
691 <p><a href="https://@hostNameForRedirect.Replace(".com", ".hr")/hr-hr/?CurrencyCode=EUR&region=HR&cartcmd=emptycart" onclick="createCookie2()">Croatia (Hrvatska) (EUR)</a></p>
692 <p><a href="https://@hostNameForRedirect/jp-en/?CurrencyCode=JPY&region=JP&cartcmd=emptycart" onclick="createCookie2()">Japan (JPY)</a></p>
693 </div>
694 <div class="secondRowLang langColumn">
695 <p><a href="https://@hostNameForRedirect/sa-en/?CurrencyCode=USD&region=LA&cartcmd=emptycart" onclick="createCookie2()">Latin America (USD)</a></p>
696 <p><a href="https://@hostNameForRedirect/uk-en/?CurrencyCode=GBP&region=UK&cartcmd=emptycart" onclick="createCookie2()">United Kingdom (GBP)</a></p>
697 <p><a href="https://@hostNameForRedirect/au-en/?CurrencyCode=AUD&region=AU&cartcmd=emptycart" onclick="createCookie2()">Australia (AUD)</a></p>
698 <p><a href="https://@hostNameForRedirect/in-en/?CurrencyCode=USD&region=IN&cartcmd=emptycart" onclick="createCookie2()">International (USD)</a></p>
699 </div>
700
701 </div>
702 </div>
703 <div id="toggleregionSelector" class="u-pull--right" style="position: absolute;
704 right: 10px;
705 top: 0;" onclick="document.getElementById('regionSelector').style.display = 'none';"
706 >
707 <img class="grid--external-bleed-y" src="/Files/Images/icons8-multiply-50.png" width="24" height="24" alt="Multiply icon" style="float: right;cursor: pointer;">
708 </div>
709 </div>
710
711
712
713
714
715 <div id="warningModal" class="" style="display:none">
716 <div class="">
717 <h2>@Translate("Changing language")</h2>
718 </div>
719 <div class="">
720 <p class="u-no-margin" id="">@Translate("You are changing language. If you continue, basket will be cleared. Do you wish to continue?")</p>
721 <div class="product-list__grid-item__footer dw-mod" style="border:0;">
722 <label id="backToPage" class="btn u-margin-left--lg btn--secondary btn--condensed u-no-margin u-pull--right dw-mod">@Translate("No")</label>
723 <button class="btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod" onclick="" id="ChangeLanguageButton">@Translate("Yes")</button>
724 </div>
725 </div>
726 </div>
727
728 <style>
729 .regionSelectorShow {
730 diplay: flex !important
731 }
732 </style>
733
734 <script>
735
736 function setCookie(cname, cvalue, exdays) {
737 const d = new Date();
738 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
739 let expires = "expires=" + d.toUTCString();
740 document.cookie = cname + "=" + cvalue + ";" + expires;
741 }
742
743 function getCookie(cname) {
744 let name = cname + "=";
745 let decodedCookie = decodeURIComponent(document.cookie);
746 let ca = decodedCookie.split(';');
747 for (let i = 0; i < ca.length; i++) {
748 let c = ca[i];
749 while (c.charAt(0) == ' ') {
750 c = c.substring(1);
751 }
752 if (c.indexOf(name) == 0) {
753 return c.substring(name.length, c.length);
754 }
755 }
756 return "";
757 }
758 function createCookie2() {
759 let usernameCookie = getCookie("usernameCookie");
760 usernameCookie = "Visited";
761 setCookie("usernameCookie", usernameCookie, 30);
762 document.querySelector("#FormCookie").classList.remove("FormShow");
763 }
764
765 function checkCookie() {
766 let user = getCookie("usernameCookie");
767 if (user != "Visited") {
768 document.querySelector("#regionSelector").classList.add("regionSelectorShow");
769 } else {
770 document.querySelector("#regionSelector").classList.remove("regionSelectorShow");
771 }
772 }
773 </script>
774
775
776 <style type="text/css">
777 .FormButton {
778 position: absolute;
779 top: 10%;
780 right: 20px;
781 border-radius: 48%;
782 color: red;
783 background-color: white;
784 width: 30px;
785 height: 30px;
786 }
787
788 .FormMain {
789 height: auto;
790 display: flex;
791 align-items: flex-start;
792 justify-content: center;
793 flex-direction: column;
794 font-family: "Montserrat";
795 font-size: 1.2em;
796 color: black;
797 font-weight: 500;
798 }
799
800 .FormCookie {
801 position: fixed;
802 left: 0;
803 top: 10%;
804 right: 0;
805 margin: auto;
806 display: flex;
807 width: 100vw;
808 height: auto;
809 justify-content: center;
810 align-items: center;
811 z-index: 90;
812 max-width: 500px;
813 padding: 20px;
814 }
815
816 .FormShow {
817 display: flex !important
818 }
819 </style>
820
821 <div class="FormCookie" id="FormCookie" style="display:none">
822
823 <div class="FormMain">
824 <div id="regionSelector" class="changeLocationDiv">
825 <div class="chooseLangMain">
826 <div>@Translate("Please select a location to continue"):</div>
827 <div class="languages">
828 <div class="firstRowLang langColumn">
829 <p><a href="https://@hostNameForRedirect/eu-en/?CurrencyCode=EUR&region=EU&cartcmd=emptycart" onclick="createCookie2()">European Union (EUR)</a></p>
830 <p><a href="https://@hostNameForRedirect/na-en/?CurrencyCode=USD&region=NA&cartcmd=emptycart" onclick="createCookie2()">US & Canada (USD)</a></p>
831 <p><a href="https://@hostNameForRedirect/ch-en/?CurrencyCode=CNY&region=CH&cartcmd=emptycart" onclick="createCookie2()">China (CNY)</a></p>
832 <p><a href="https://@hostNameForRedirect.Replace(".com", ".hr")/hr-hr/?CurrencyCode=EUR&region=HR&cartcmd=emptycart" onclick="createCookie2()">Croatia (Hrvatska) (EUR)</a></p>
833 <p><a href="https://@hostNameForRedirect/jp-en/?CurrencyCode=JPY&region=JP&cartcmd=emptycart" onclick="createCookie2()">Japan (JPY)</a></p>
834 </div>
835 <div class="secondRowLang langColumn">
836 <p><a href="https://@hostNameForRedirect/sa-en/?CurrencyCode=USD&region=LA&cartcmd=emptycart" onclick="createCookie2()">Latin America (USD)</a></p>
837 <p><a href="https://@hostNameForRedirect/uk-en/?CurrencyCode=GBP&region=GB&cartcmd=emptycart" onclick="createCookie2()">United Kingdom (GBP)</a></p>
838 <p><a href="https://@hostNameForRedirect/au-en/?CurrencyCode=AUD&region=AU&cartcmd=emptycart" onclick="createCookie2()">Australia (AUD)</a></p>
839 <p><a href="https://@hostNameForRedirect/in-en/?CurrencyCode=USD&region=IN&cartcmd=emptycart" onclick="createCookie2()">International (USD)</a></p>
840 </div>
841
842 </div>
843 </div>
844 <div id="toggleregionSelector" class="u-pull--right" style="position: absolute;
845 right: 10px;
846 top: 0;" onclick="document.getElementById('regionSelector').style.display = 'none';">
847 <img class="grid--external-bleed-y" src="/Files/Images/icons8-multiply-50.png" width="24" height="24" alt="Multiply icon" style="float: right;cursor: pointer;">
848 </div>
849 </div>
850 </div>
851 </div>
852
853
854 <script>
855
856 function setCookie(cname, cvalue, exdays) {
857 const d = new Date();
858 d.setTime(d.getTime() + (d * 24 * 60 * 60 * 1000));
859 let expires = "expires=" + d.toUTCString();
860 document.cookie = cname + "=" + cvalue + ";" + expires;
861 }
862
863 function getCookie(cname) {
864 let name = cname + "=";
865 let decodedCookie = decodeURIComponent(document.cookie);
866 let ca = decodedCookie.split(';');
867 for (let i = 0; i < ca.length; i++) {
868 let c = ca[i];
869 while (c.charAt(0) == ' ') {
870 c = c.substring(1);
871 }
872 if (c.indexOf(name) == 0) {
873 return c.substring(name.length, c.length);
874 }
875 }
876 return "";
877 }
878 function createCookie2() {
879 let usernameCookie = getCookie("usernameCookie");
880 usernameCookie = "Visited";
881 setCookie("usernameCookie", usernameCookie, 30);
882 document.querySelector("#FormCookie").classList.remove("FormShow");
883 }
884
885 function checkCookie() {
886 let user = getCookie("usernameCookie");
887 if (user != "Visited") {
888 document.querySelector("#FormCookie").classList.add("FormShow");
889 } else {
890 document.querySelector("#FormCookie").classList.remove("FormShow");
891 }
892 }
893 </script>