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 specified network name is no longer available
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.Product.GetProductById(String productId)
at CompiledRazorTemplates.Dynamic.RazorEngine_8d187e95c64e4d699ea233adaf61096f.Execute() in D:\dynamicweb.net\Solutions\Skabertrang\clemco.swift.dynamicweb-cms.com\files\Templates\Designs\Swift\_parsed\Swift_Page.parsed.cshtml:line 342
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:64,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.Services.Pages?.GetPage(brandingPageId) ?? null;
26 var themesParagraphLastChanged = 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 // Har overskrevet denne for at fjerne sticky /LLA
89 headerCssClass = "never-sticky-top";
90
91 string googleAnalyticsTrackingID = Model.Area.Item.GetString("GoogleAnalyticsTrackingID");
92 string googleAnalyticsMeasurementID = Model.Area.Item.GetString("GoogleAnalyticsMeasurementID");
93 var cookieOptInLevel = CookieManager.GetCookieOptInLevel();
94 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical"));
95
96 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/css/styles.css?{cssStyleFileInfo.LastWriteTime.Ticks}>; rel=preload; as=style;");
97 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;");
98 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/aos.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
99 Dynamicweb.Context.Current.Response.AddHeader("link", $"</Files/Templates/Designs/Swift/Assets/js/scripts.js?{jsFileInfo.LastWriteTime.Ticks}; rel=preload; as=script;");
100 //Dynamicweb.Context.Current.Response.Flush(); //This sends the headers where we are now in the rendering making the TTFB faster
101
102 SetMetaTags();
103
104 List<Dynamicweb.Content.Page> languages = new List<Dynamicweb.Content.Page>();
105
106 if (Pageview.Area.IsMaster)
107 {
108 languages.Add(Pageview.Page);
109 if (Pageview.Page.Languages != null)
110 {
111 foreach (var language in Pageview.Page.Languages)
112 {
113 languages.Add(language);
114 }
115 }
116 }
117 else
118 {
119 languages.Add(Pageview.Page.MasterPage);
120 if (Pageview.Page.MasterPage != null)
121 {
122 if (Pageview.Page.MasterPage.Languages != null)
123 {
124 foreach (var language in Pageview.Page.MasterPage.Languages)
125 {
126 languages.Add(language);
127 }
128 }
129 }
130 }
131
132 string siteLanguage = Pageview.Area.CultureInfo.Name;
133 Uri url = Dynamicweb.Context.Current.Request.Url;
134 string hostName = url.Host; // domain.com/da-dk or domain.com/en-us
135
136 var ecomCountries = Dynamicweb.Ecommerce.Services.Countries.GetCountries();
137 var ecomCurrencies = Dynamicweb.Ecommerce.Services.Currencies.GetAllCurrencies();
138 }
139 <!doctype html>
140 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName">
141 <head>
142 <!-- @swiftVersion -->
143 @* Required meta tags *@
144 <meta charset="utf-8">
145 <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0">
146 <link rel="shortcut icon" href="@favicon">
147 <link rel="apple-touch-icon" href="/Files/Templates/Designs/Swift/Assets/Images/logo_transparent.png">
148
149 @Model.MetaTags
150
151 @{
152 @* Languages meta data *@
153 foreach (var language in languages)
154 {
155 if (language?.Area != null)
156 {
157 if (language != null && language.Published && language.Active && language.Area.Active && language.Area.Published && language.Area.ID != Dynamicweb.Frontend.PageView.Current().AreaID)
158 {
159 if (!string.IsNullOrEmpty(language.Area.DomainLock))
160 {
161 hostName = language.Area.DomainLock; //dk.domain.com or dk-domain.dk
162 }
163 string querystring = $"Default.aspx?ID={language.ID}";
164 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["GroupID"]))
165 {
166 querystring += $"&GroupID={Dynamicweb.Context.Current.Request.QueryString["GroupID"]}";
167 }
168 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"]))
169 {
170 querystring += $"&ProductID={Dynamicweb.Context.Current.Request.QueryString["ProductID"]}";
171 }
172 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["VariantID"]))
173 {
174 querystring += $"&VariantID={Dynamicweb.Context.Current.Request.QueryString["VariantID"]}";
175 }
176
177 string friendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(querystring);
178 string href = $"{url.Scheme}://{hostName}{friendlyUrl}";
179
180 <link rel="alternate" hreflang="@language.Area.CultureInfo.Name.ToLower()" href="@href">
181 }
182 }
183 }
184 }
185
186 <title>@Model.Title</title>
187 @* Bootstrap + Swift stylesheet *@
188 <link href="/Files/Templates/Designs/Swift/Assets/css/styles.css?@cssStyleFileInfo.LastWriteTime.Ticks" rel="stylesheet" media="all" type="text/css">
189
190 @if (disableWideBreakpoints != "disableBoth")
191 {
192 <style>
193 @@media ( min-width: 1600px ) {
194 .container-xxl,
195 .container-xl,
196 .container-lg,
197 .container-md,
198 .container-sm,
199 .container {
200 max-width: 1520px;
201 }
202 }
203 </style>
204
205 if (disableWideBreakpoints != "disableUltraWideOnly")
206 {
207 <style>
208 @@media ( min-width: 1920px ) {
209 .container-xxl,
210 .container-xl,
211 .container-lg,
212 .container-md,
213 .container-sm,
214 .container {
215 max-width: 1820px;
216 }
217 }
218 </style>
219 }
220 }
221
222 @* Branding and Themes min stylesheet *@
223 <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">
224 <script src="/Files/Templates/Designs/Swift/Assets/js/aos.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
225 <script src="/Files/Templates/Designs/Swift/Assets/js/scripts.js?@jsFileInfo.LastWriteTime.Ticks" defer></script>
226
227 <script type="module">
228 AOS.init({ offset: 0, duration: 400, delay: 100, easing: 'ease-in-out', mirror: true, disable: window.matchMedia('(prefers-reduced-motion: reduce)') });
229 swift.Scroll.hideHeadersOnScroll();
230 swift.Scroll.handleAlternativeTheme();
231 </script>
232
233 @* Global site tag (gtag.js) - Google Analytics *@
234 @if (!string.IsNullOrWhiteSpace(googleAnalyticsTrackingID) && allowTracking)
235 {
236 if (googleAnalyticsTrackingID.IndexOf("G-") == 0 || googleAnalyticsTrackingID.IndexOf("UA-") == 0)
237 {
238 <script src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsTrackingID" async></script>
239 <script>
240 window.dataLayer = window.dataLayer || [];
241 function gtag() { window.dataLayer.push(arguments); }
242 gtag('js', new Date());
243 gtag('config', '@googleAnalyticsTrackingID');
244 </script>
245 }
246 else if (googleAnalyticsTrackingID.IndexOf("GTM-") == 0)
247 {
248 <script>
249 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
250 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
251 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
252 })(window, document, 'script', 'dataLayer', '@googleAnalyticsTrackingID');
253 </script>
254 }
255
256 }
257
258 @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking)
259 {
260 var GoogleAnalyticsDebugMode = "";
261 bool isLoggedInBackendUser = false;
262
263 if (Dynamicweb.Environment.ExecutingContext.IsAdminLoggedIn())
264 {
265 isLoggedInBackendUser = true;
266 }
267
268 if (Model.Area.Item.GetBoolean("EnableGoogleAnalyticsDebugMode") && @isLoggedInBackendUser)
269 {
270 GoogleAnalyticsDebugMode = ", {'debug_mode': true}";
271 }
272
273 <script async src="https://www.googletagmanager.com/gtag/js?id=@googleAnalyticsMeasurementID"></script>
274 <script>
275 window.dataLayer = window.dataLayer || [];
276 function gtag() { dataLayer.push(arguments); }
277 gtag('js', new Date());
278 gtag('config', '@googleAnalyticsMeasurementID'@GoogleAnalyticsDebugMode);
279 </script>
280 }
281
282 @if (!string.IsNullOrWhiteSpace(customHeaderInclude))
283 {
284 @RenderPartial($"Components/Custom/{customHeaderInclude}")
285 }
286 </head>
287 <body class="brand @(masterTheme)" id="page@(Model.ID)">
288 @if (renderAsResponsive || !renderMobile)
289 {
290 <header class="page-header @headerCssClass top-0@(responsiveClassDesktop)" id="page-header-desktop">
291 @if (@Model.Area.Item.GetLink("HeaderDesktop") != null)
292 {
293 @RenderGrid(@Model.Area.Item.GetLink("HeaderDesktop").PageId)
294 }
295 </header>
296 }
297
298 @if ((renderAsResponsive || renderMobile))
299 {
300 <header class="page-header @headerCssClass top-0@(responsiveClassMobile)" id="page-header-mobile">
301 @if (@Model.Area.Item.GetLink("HeaderMobile") != null)
302 {
303 @RenderGrid(@Model.Area.Item.GetLink("HeaderMobile").PageId)
304 }
305 </header>
306 }
307
308 <main id="content" @(schemaOrgType)>
309 <div data-intersect></div>
310 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
@using System
@using Dynamicweb.Ecommerce.ProductCatalog
@{
string productIdFromUrl = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : string.Empty;
bool isProductDetail = !string.IsNullOrEmpty(productIdFromUrl) && Pageview.Page.NavigationTag.ToLower() == "shop";
bool isArticlePagePage = Model.ItemType == "Swift_Article";
string schemaOrgProp = string.Empty;
if(isArticlePagePage)
{
schemaOrgProp = "itemprop=\"articleBody\"";
}
string theme = "";
string gridContent = "";
if (Model.PropertyItem != null)
{
theme = !string.IsNullOrWhiteSpace(Model.PropertyItem.GetRawValueString("Theme")) ? " theme " + Model.PropertyItem.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
}
if (Model.Item != null || Pageview.IsVisualEditorMode)
{
if (!isProductDetail)
{
gridContent = Model.Grid("Grid", "Grid", "default:true;sort:1", "Page");
}
else
{
var productObject = Dynamicweb.Ecommerce.Products.Product.GetProductById(productIdFromUrl);
var detailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(productObject.PrimaryGroupId)?.Meta.PrimaryPage ?? string.Empty;
var detailPageId = detailPage != string.Empty ? Convert.ToInt16(detailPage.Substring(detailPage.LastIndexOf('=') + 1)) : GetPageIdByNavigationTag("ProductDetailPage");
@RenderGrid(detailPageId)
}
}
bool doNotRenderPage = false;
//Check if we are on the poduct detail page, and if there is data to render
ProductViewModel product = new ProductViewModel();
if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
{
product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
if (string.IsNullOrEmpty(product.Id)) {
doNotRenderPage = true;
}
}
//Render the page
if (!doNotRenderPage) {
string itemIdentifier = Model?.Item?.SystemName != null ? "item_" + Model.Item.SystemName.ToLower() : "item_Swift_Page";
if (theme != "")
{
<div class="@theme item_@itemIdentifier" @schemaOrgProp>
@gridContent
</div>
}
else
{
<div class="item_@itemIdentifier" @schemaOrgProp>
@gridContent
</div>
}
} else {
<div class="container">
<div class="alert alert-info" role="alert">@Translate("Sorry. There is nothing to view here")</div>
</div>
}
if (!Model.IsCurrentUserAllowed)
{
int signInPage = GetPageIdByNavigationTag("SignInPage");
int dashboardPage = GetPageIdByNavigationTag("MyAccountDashboardPage");
if (!Pageview.IsVisualEditorMode)
{
if (signInPage != 0)
{
if (signInPage != Model.ID) {
Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage);
} else {
if (dashboardPage != 0) {
Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage);
} else {
Dynamicweb.Context.Current.Response.Redirect("/");
}
}
}
else
{
<div class="alert alert-dark m-0" role="alert">
<span>@Translate("You do not have access to this page")</span>
</div>
}
}
else
{
<div class="alert alert-dark m-0" role="alert">
<span>@Translate("To work on this page, you must be signed in, in the frontend")</span>
</div>
}
}
}
311 </main>
312
313
314
315
316 @if (renderAsResponsive || !renderMobile)
317 {
318 <footer class="page-footer@(responsiveClassDesktop)" id="page-footer-desktop">
319 @if (@Model.Area.Item.GetLink("FooterDesktop") != null)
320 {
321 @RenderGrid(@Model.Area.Item.GetLink("FooterDesktop").PageId)
322 }
323 </footer>
324 }
325
326 @if (renderAsResponsive || renderMobile)
327 {
328 <footer class="page-footer@(responsiveClassMobile)" id="page-footer-mobile">
329 @if (@Model.Area.Item.GetLink("FooterMobile") != null)
330 {
331 @RenderGrid(@Model.Area.Item.GetLink("FooterMobile").PageId)
332 }
333 </footer>
334 }
335
336 @* TIL CK - HER ER COOKIE KNAPPEN *@
337 @if (!Pageview.IsVisualEditorMode && Dynamicweb.Environment.CookieManager.GetCookie("Dynamicweb.CookieOptInLevel") != null)
338 {
339 //eneste der virkede var at kopiere alt fra Cookies.cshtml herind...
340 var categories = CookieManager.GetCategories();
341
342 string cookieNoticeLink = Pageview.AreaSettings.GetLink("CookiePolicyLink") != null ? Pageview.AreaSettings.GetLink("CookiePolicyLink").Url : "";
343 string privacyPolicyLink = Pageview.AreaSettings.GetLink("PrivacyPolicyLink") != null ? Pageview.AreaSettings.GetLink("PrivacyPolicyLink").Url : "";
344 int cookieNoticePageID = Pageview.AreaSettings.GetLink("CookiePolicyLink") != null ? Pageview.AreaSettings.GetLink("CookiePolicyLink").PageId : 0;
345 int privacyPolicyPageID = Pageview.AreaSettings.GetLink("PrivacyPolicyLink") != null ? Pageview.AreaSettings.GetLink("PrivacyPolicyLink").PageId : 0;
346
347 string layout = Pageview.AreaSettings.GetRawValueString("CookieLayout", "modal");
348
349 layout = Pageview.Page.ID == cookieNoticePageID || Pageview.Page.ID == privacyPolicyPageID ? "both" : layout;
350
351
352 if (!Pageview.IsVisualEditorMode)
353 {
354 // Jeg har tilf�jet "false" /LLA
355 if (false && (layout == "banner" || layout == "both"))
356 {
357 string bannerTheme = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetRawValueString("CookieBannerTheme")) ? " theme " + Pageview.AreaSettings.GetRawValueString("CookieBannerTheme").Replace(" ", "").Trim().ToLower() : "theme light";
358
359 <div class="position-fixed bottom-0 w-100 shadow @bannerTheme" id="dwCookieBanner">
360 <div class="align-items-center grid p-3">
361 @if (layout == "banner")
362 {
363 <div class="g-col-12 g-col-md-6 g-col-lg-8">
364 <span>@Translate("By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Functionality, Statistics and Marketing")</span>
365 </div>
366 <div class="g-col-12 g-col-md-6 g-col-lg-4">
367 <div class="grid grid-1 grid-sm-2">
368 <button type="button" onclick="setOptInCookie(2)" class="btn btn-primary">
369 @Translate("Accept all")
370 </button>
371 <button type="button" onclick="setOptInCookie(0)" class="btn btn-secondary">
372 @Translate("Decline all")
373 </button>
374 </div>
375 </div>
376 }
377 @if (layout == "both")
378 {
379 <div class="g-col-12 g-col-lg-6 g-col-xxl-8">
380 <span>@Translate("By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Functionality, Statistics and Marketing")</span>
381 </div>
382 <div class="g-col-12 g-col-lg-6 g-col-xxl-4">
383 <div class="grid grid-1 grid-sm-3">
384 <button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#dwCookieModal">
385 @Translate("Customize settings")
386 </button>
387 <button type="button" onclick="setOptInCookie(2)" class="btn btn-secondary">
388 @Translate("Accept all")
389 </button>
390 <button type="button" onclick="setOptInCookie(0)" class="btn btn-secondary">
391 @Translate("Decline all")
392 </button>
393 </div>
394 </div>
395 }
396 </div>
397 </div>
398 }
399
400 if (layout == "modal" || layout == "both")
401 {
402 string modalTheme = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetRawValueString("CookieModalTheme")) ? " theme " + Pageview.AreaSettings.GetRawValueString("CookieModalTheme").Replace(" ", "").Trim().ToLower() : "theme light";
403
404 <div class="modal fade" id="dwCookieModal">
405 <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" style="max-width:560px;">
406 <div class="modal-content @modalTheme">
407 <div style="overflow-y:auto;overflow-x:hidden">
408 <div class="p-3 p-md-4 overflow-auto" style="max-height:50vh;">
409 <div class="h3 mb-3">@Translate("You control your data")</div>
410 <p>@Translate("We and our partners use technologies, including cookies, to collect information about you for various purposes, including"):</p>
411 <ol>
412 <li>@Translate("Functionality")</li>
413 <li>@Translate("Statistics")</li>
414 <li>@Translate("Marketing")</li>
415 </ol>
416 <p>@Translate("By clicking 'Accept All' you consent to all these purposes. You can also choose to indicate what purposes you will consent to using the custom selections and then click 'Accept selected'").</p>
417
418 @if (!string.IsNullOrEmpty(cookieNoticeLink) || !string.IsNullOrEmpty(privacyPolicyLink))
419 {
420 <p>@Translate("You can read more about our use of cookies and other technologies, as well as our collection and processing of personal data by clicking here"):</p>
421 }
422
423 @if (!string.IsNullOrEmpty(cookieNoticeLink))
424 {
425 <a href="@cookieNoticeLink" class="d-block mb-3">@Translate("Read more about Cookies")</a>
426 }
427 @if (!string.IsNullOrEmpty(privacyPolicyLink))
428 {
429 <a href="@privacyPolicyLink" class="d-block">@Translate("Our privacy policy")</a>
430 }
431 </div>
432
433 <div class="p-3 px-md-4 border-top">
434 <div class="grid grid-1 grid-sm-2 gap-3">
435 <button type="button" onclick="setOptInCookie(0)" class="btn btn-secondary" data-bs-dismiss="modal" id="dwCookieDeclineAll">@Translate("Decline All")</button>
436 @if (categories.Any())
437 {
438 <button type="button" onclick="acceptCustomSetup()" class="btn btn-secondary d-none" data-bs-dismiss="modal" id="dwCookieAcceptSelected">@Translate("Accept selected")</button>
439 }
440 <button type="button" onclick="setOptInCookie(2)" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Accept All")</button>
441 </div>
442 </div>
443
444 @if (categories.Any())
445 {
446 int categoriesCount = 0;
447 int totalCategories = categories.Count();
448
449 <form id="dwCookieModalCustomForm" method="post" action="/Admin/Public/CookieOptInLevelConfig.aspx">
450 <input type="hidden" name="cmd" value="SetCookieOptInLevel">
451 <input type="hidden" name="OptInLevel" id="OptInLevel" value="1">
452 <div class="grid grid-2 grid-sm-4 gap-0 px-md-3 border-top border-1">
453 <div class="p-3">
454 <label class="form-check-label" for="dwCookieNecessary"><span>@Translate("Necessary")</span></label>
455 <div class="form-check form-switch form-control-lg py-0">
456 <input class="form-check-input opacity-100" type="checkbox" id="dwCookieNecessary" checked disabled style="background-color: rgba(0,0,0,0.1);">
457 </div>
458 </div>
459 @foreach (var category in categories)
460 {
461 string border = categoriesCount < (totalCategories - 1) ? "" : "";
462
463 <div class="p-3 @(border)">
464 <label class="form-check-label" for="CookieCategory_@category"><span>@category</span></label>
465 <div class="form-check form-switch form-control-lg py-0">
466 <input class="form-check-input js-checkbox" type="checkbox" name="OptInCategory" value="@category" id="CookieCategory_@category" onchange="toggleAcceptSelected()" style="background-color: rgba(0,0,0,0.1);">
467 </div>
468 </div>
469 categoriesCount++;
470 }
471 </div>
472 </form>
473 }
474 </div>
475 </div>
476 </div>
477 </div>
478 }
479
480
481 <script>
482 async function setOptInCookie(optInLevel) {
483 let response = await fetch("/admin/public/CookieOptInLevelConfig.aspx?cmd=SetCookieOptInLevel&OptInLevel=" + optInLevel);
484
485 if (response.ok) {
486 if (document.querySelector("#dwCookieBanner")) {
487 document.querySelector("#dwCookieBanner").classList.add("d-none");
488 }
489 return false;
490 } else {
491 return false;
492 }
493 }
494
495 async function acceptCustomSetup() {
496 var form = document.querySelector("#dwCookieModalCustomForm");
497
498 let formData = new FormData(form);
499 var fetchOptions = {
500 method: 'POST',
501 body: formData
502 };
503
504 let response = await fetch(form.action, fetchOptions);
505
506 if (response.ok) {
507 if (document.querySelector("#dwCookieBanner")) {
508 document.querySelector("#dwCookieBanner").classList.add("d-none");
509 }
510 return false;
511 } else {
512 return false;
513 }
514 }
515
516 function toggleAcceptSelected() {
517 var cookieCalegoriesElement = document.querySelector("#dwCookieModalCustomForm");
518 var enableAcceptSelected = false;
519
520 cookieCalegoriesElement.querySelectorAll(".js-checkbox").forEach(function (field) {
521 if (field.checked == true) {
522 enableAcceptSelected = true;
523 }
524 });
525
526 if (enableAcceptSelected) {
527 document.querySelector("#dwCookieDeclineAll").classList.add("d-none");
528 document.querySelector("#dwCookieAcceptSelected").classList.remove("d-none");
529 } else {
530 document.querySelector("#dwCookieDeclineAll").classList.remove("d-none");
531 document.querySelector("#dwCookieAcceptSelected").classList.add("d-none");
532 }
533 }
534
535 function showCookieModal() {
536 var cookieModal = new bootstrap.Modal(document.querySelector('#dwCookieModal'), {
537 backdrop: 'static'
538 });
539 cookieModal.show();
540 }
541 </script>
542
543
544 }
545
546
547 <div class="container-xl">
548 <div class="cookie-btn-container position-fixed">
549 @*<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dwCookieModal">*@
550 <button type="button" class="btn" onclick="showCookieModal()">
551
552 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="30px" height="30px">
553 <path d="M184 192c0-13.25-10.75-24-24-24s-24 10.75-24 24s10.75 24 24 24S184 205.3 184 192zM288 232c-13.25 0-24 10.75-24 24s10.75 24 24 24s24-10.75 24-24S301.3 232 288 232zM192 328c-13.25 0-24 10.75-24 24s10.75 24 24 24s24-10.75 24-24S205.3 328 192 328zM352 328c-13.25 0-24 10.75-24 24s10.75 24 24 24s24-10.75 24-24S365.3 328 352 328zM494.6 255.9c-65.63-.8203-118.6-54.14-118.6-119.9c-65.74 0-119.1-52.97-119.8-118.6C250 16.47 243.7 16 237.5 16c-19.34 0-38.54 4.573-56 13.48L116.7 62.41C93.35 74.36 74.36 93.35 62.41 116.7L29.6 181.2C17.64 204.7 13.42 231.2 17.53 257.2l11.37 71.48c4.102 25.9 16.29 49.8 34.81 68.32l51.36 51.39c18.52 18.4 42.27 30.64 68.18 34.75l71.84 11.37C261.5 495.5 268 496 274.5 496c19.34 0 38.71-4.573 56.17-13.48l64.81-33.05c23.32-11.84 42.31-30.82 54.14-54.14l32.93-64.57C494.3 307.7 498.5 281.4 494.6 255.9zM454 316.2l-32.96 64.63c-8.703 17.15-22.94 31.38-40.14 40.12l-64.81 33.05C303.3 460.5 288.9 464 274.5 464c-5.004 0-9.811-.3711-14.45-1.131l-71.83-11.37c-19.23-3.045-36.75-11.96-50.56-25.68l-51.36-51.47c-13.83-13.83-22.76-31.36-25.83-50.72l-11.36-71.44C46.08 232.8 49.18 213.3 58.12 195.7l32.76-64.47C99.84 113.8 113.8 99.83 131.2 90.93l64.85-32.95c9.895-5.047 20.71-8.256 31.72-9.453c12.9 58.74 60.05 104.1 119.1 116.6c11.65 59 57.88 106.2 116.6 119.2C462.2 295.4 459.1 306.3 454 316.2z"></path>
554 </svg>
555 </button>
556 </div>
557 </div>
558 }
559
560
561 @* Render any offcanvas menu here *@
562 @RenderSnippet("offcanvas")
563
564 @{
565 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable();
566 }
567
568 @* Language selector modal *@
569 @if (languages.Count > 1 || ecomCountries.Count > 1 || ecomCurrencies.Count() > 1)
570 {
571 <div class="modal fade" id="PreferencesModal" tabindex="-1" aria-hidden="true">
572 <div class="modal-dialog modal-dialog-centered modal-sm" id="PreferencesModalContent">
573 @* The content here comes from an external request *@
574 </div>
575 </div>
576 }
577
578 @* Favorite toast *@
579 <div aria-live="polite" aria-atomic="true">
580 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
581 <div id="favoriteNotificationToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
582 <div class="toast-header">
583 <strong class="me-auto">@Translate("Favorite list updated")</strong>
584 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
585 </div>
586 <div class="toast-body d-flex gap-3">
587 <div id="favoriteNotificationToast_Image"></div>
588 <div id="favoriteNotificationToast_Text"></div>
589 </div>
590 </div>
591 </div>
592 </div>
593
594 @* Modal for dynamic content *@
595 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true">
596 <div class="modal-dialog modal-dialog-centered modal-md">
597 <div class="modal-content theme light" id="DynamicModalContent">
598 @* The content here comes from an external request *@
599 </div>
600 </div>
601 </div>
602
603 @* Offcanvas for dynamic content *@
604 <div class="offcanvas offcanvas-end theme light" tabindex="-1" id="DynamicOffcanvas" style="width: 30rem">
605 @* The content here comes from an external request *@
606 </div>
607
608 @if (isErpConnectionDown && Model.Area.Item.GetBoolean("ShowErpDownMessage"))
609 {
610 string erpDownMessageTheme = !string.IsNullOrWhiteSpace(Model.Area.Item.GetRawValueString("ErpDownMessageTheme")) ? " theme " + Model.Area.Item.GetRawValueString("ErpDownMessageTheme").Replace(" ", "").Trim().ToLower() : "theme light";
611
612 <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 1040">
613 <div class="toast fade show border-0 @erpDownMessageTheme" role="alert" aria-live="assertive" aria-atomic="true">
614 <div class="toast-header">
615 <strong class="me-auto">@Translate("Connection down")</strong>
616 <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
617 </div>
618 <div class="toast-body">
619 @Translate("We are experiencing some connectivity issues. Not all features may be available to you.")
620 </div>
621 </div>
622 </div>
623 }
624
625 </body>
626 </html>
627 @functions {
628 void SetMetaTags()
629 {
630 //Verification Tokens
631 string siteVerificationGoogle = Model.Area.Item.GetString("Google_Site_Verification") != null ? Model.Area.Item.GetString("Google_Site_Verification") : "";
632 //string siteVerificationYandex = Model.Area.Item.GetString("Yandex_Verification") != null ? Model.Area.Item.GetString("Yandex_Verification") : "";
633 //string siteVerificationMS = Model.Area.Item.GetString("Msvalidate_01") != null ? Model.Area.Item.GetString("Msvalidate_01") : "";
634 //string siteVerificationAlexa = Model.Area.Item.GetString("AlexaVerifyID") != null ? Model.Area.Item.GetString("AlexaVerifyID") : "";
635 //string siteVerificationPinterest = Model.Area.Item.GetString("P_domain_verify") != null ? Model.Area.Item.GetString("P_domain_verify") : "";
636 //string siteVerificationNorton = Model.Area.Item.GetString("Norton_safeweb_site_verification") != null ? Model.Area.Item.GetString("Norton_safeweb_site_verification") : "";
637
638 //Generic Site Values
639 string openGraphFacebookAppID = Model.Area.Item.GetString("Fb_app_id") != null ? Model.Area.Item.GetString("Fb_app_id") : "";
640 string openGraphType = Model.Area.Item.GetString("Open_Graph_Type") != null ? Model.Area.Item.GetString("Open_Graph_Type") : "";
641 string openGraphSiteName = Model.Area.Item.GetString("Open_Graph_Site_Name") != null ? Model.Area.Item.GetString("Open_Graph_Site_Name") : "";
642
643 string twitterCardSite = Model.Area.Item.GetString("Twitter_Site") != null ? Model.Area.Item.GetString("Twitter_Site") : "";
644
645 //Page specific values
646 string openGraphSiteTitle = Model.Area.Item.GetString("Open_Graph_Title") != null ? Model.Area.Item.GetString("Open_Graph_Title") : "";
647 FileViewModel openGraphImage = Model.Area.Item.GetFile("Open_Graph_Image");
648 string openGraphImageALT = Model.Area.Item.GetString("Open_Graph_Image_ALT") != null ? Model.Area.Item.GetString("Open_Graph_Image_ALT") : "";
649 string openGraphDescription = Model.Area.Item.GetString("Open_Graph_Description") != null ? Model.Area.Item.GetString("Open_Graph_Description") : "";
650
651 string twitterCardURL = Model.Area.Item.GetString("Twitter_URL") != null ? Model.Area.Item.GetString("Twitter_URL") : "";
652 string twitterCardTitle = Model.Area.Item.GetString("Twitter_Title") != null ? Model.Area.Item.GetString("Twitter_Title") : "";
653 string twitterCardDescription = Model.Area.Item.GetString("Twitter_Description") != null ? Model.Area.Item.GetString("Twitter_Description") : "";
654 FileViewModel twitterCardImage = Model.Area.Item.GetFile("Twitter_Image");
655 string twitterCardImageALT = Model.Area.Item.GetString("Twitter_Image_ALT") != null ? Model.Area.Item.GetString("Twitter_Image_ALT") : "";
656
657 if (!string.IsNullOrEmpty(siteVerificationGoogle))
658 {
659 Pageview.Meta.AddTag("google-site-verification", siteVerificationGoogle);
660 }
661
662 if (!string.IsNullOrEmpty(openGraphFacebookAppID))
663 {
664 Pageview.Meta.AddTag("fb:app_id", openGraphFacebookAppID);
665 }
666
667 if (!string.IsNullOrEmpty(openGraphType))
668 {
669 Pageview.Meta.AddTag("og:type", openGraphType);
670 }
671
672 if (!string.IsNullOrEmpty(openGraphSiteName))
673 {
674 Pageview.Meta.AddTag("og:site_name", openGraphSiteName);
675 }
676
677 if (!string.IsNullOrEmpty(Model.Title))
678 {
679 Pageview.Meta.AddTag("og:title", Model.Title);
680 }
681 else
682 {
683 Pageview.Meta.AddTag("og:title", openGraphSiteTitle);
684 }
685
686 if (!string.IsNullOrEmpty(Pageview.Page.TopImage) && openGraphImage == null)
687 {
688 Pageview.Meta.AddTag("og:image", Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + Pageview.Page.TopImage);
689 }
690
691 if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["ProductID"]))
692 {
693 if (!string.IsNullOrEmpty(Model.Description))
694 {
695 Pageview.Meta.AddTag("og:description", Model.Description);
696 }
697 else
698 {
699 Pageview.Meta.AddTag("og:description", openGraphDescription);
700 }
701 if (openGraphImage != null)
702 {
703 Pageview.Meta.AddTag("og:image", openGraphImage.Path);
704 }
705
706 if (!string.IsNullOrEmpty(openGraphImageALT))
707 {
708 Pageview.Meta.AddTag("og:image:alt", openGraphImageALT);
709 }
710 if (!string.IsNullOrEmpty(twitterCardDescription))
711 {
712 Pageview.Meta.AddTag("twitter:description", twitterCardDescription);
713 }
714
715 if (twitterCardImage != null)
716 {
717 Pageview.Meta.AddTag("twitter:image", twitterCardImage.Path);
718 }
719
720 if (!string.IsNullOrEmpty(twitterCardImageALT))
721 {
722 Pageview.Meta.AddTag("twitter:image:alt", twitterCardImageALT);
723 }
724 }
725
726 if (!string.IsNullOrEmpty(twitterCardSite))
727 {
728 Pageview.Meta.AddTag("twitter:site", twitterCardSite);
729 }
730
731 if (!string.IsNullOrEmpty(twitterCardURL))
732 {
733 Pageview.Meta.AddTag("twitter:url", twitterCardURL);
734 }
735
736 if (!string.IsNullOrEmpty(twitterCardTitle))
737 {
738 Pageview.Meta.AddTag("twitter:title", twitterCardTitle);
739 }
740 }
741 }
742