Error parsing template "Designs/Junget2026/_parsed/PageShopList.parsed.cshtml"
Line 487: (486:1) - The if block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
2 @{
3 bool isLocalHost = Dynamicweb.Context.Current.Request.Url.Host.Contains("local.dynamicweb.dk");
4 string cultureName = Pageview.Area.Culture.Split('-')[0];
5 }
6 <!doctype html>
7 <html>
8 <head>
9 <script id="CookieConsent" src="https://policy.app.cookieinformation.com/uc.js"
10 data-culture="@cultureName.ToUpper()" data-gcm-version="2.0" type="text/javascript"></script>
11
12 @RenderPartial("/Designs/Junget2026/Master/Partials/Meta.cshtml")
13
14 @if (!isLocalHost)
15 {
16 var masterStyles = Dynamicweb.VestjyskMarketing.Helpers.Utilities.CacheBuster("/Assets/Junget2026/dist/main.css");
17 <link href="@masterStyles" rel="stylesheet">
18 }
19
20 @Pageview.Area.Item["HeaderScripts"]
21
22 <script async type="text/plain" data-cookieconsent="marketing"
23 src="https://static.klaviyo.com/onsite/js/klaviyo.js?company_id=W7NjJj"></script>
24
25 @RenderSnippet("GATracking")
26 </head>
27
28 <body class="@(Pageview.User != null ? "signed-in" : "")" data-url-prefix="@Pageview.Area.Culture">
29 @Pageview.Area.Item["AfterBodyScripts"]
30
31 <div id="MainContent" class="container-fluid bg-white">
32 @RenderPartial("/Designs/Junget2026/Master/Partials/LanguageRedirector.cshtml")
33
34 @RenderPartial("/Designs/Junget2026/Master/Partials/GlobalMessage.cshtml")
35 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
36 @using Dynamicweb.Frontend.Navigation;
37 @{
38 var mainUserInHeader = Pageview.User?.CurrentSecondaryUser != null ? Pageview.User.CurrentSecondaryUser : Pageview.User;
39
40 string webshopLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Webshop");
41 string logoPath = Model.Area.Item.GetString("Logo");
42 bool showLanguageSelector = Model.Area.Item.GetBoolean("ShowLanguageSelector");
43 string cartIconPath = "/Assets/Junget2026/Images/Icons/cart-shopping-sharp-light-full.svg";
44 string chevronDownIconPath = "/Assets/Junget2026/Images/Icons/chevron-down-sharp-light-full.svg";
45 var cartQty = Model.Cart.TotalProductsCount;
46 // Salespersons never see a quantity, but must still be able to open the cart aside
47 bool cartAlwaysClickable = mainUserInHeader != null && mainUserInHeader.HasGroup(24);
48 if (cartAlwaysClickable)
49 {
50 cartQty = 0;
51 }
52 string cartAlwaysClickableAttribute = cartAlwaysClickable ? "true" : "false";
53 string cartButtonStateClasses = cartQty > 0 || cartAlwaysClickable ? "cursor-pointer" : "pointer-events-none cursor-default";
54 string rootCultureName = Pageview.Area.Culture;
55 string cartLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CartPage");
56 var currentAreaId = Dynamicweb.Frontend.PageView.Current().AreaID;
57 var isJunget = new[] { 1, 14, 8, 13 }.Contains(currentAreaId);
58
59 var languages = isJunget
60 ? new[]
61 {
62 new { AreaId = 13, Url = "/", Flag = "da-dk", Label = Translate("Dansk") },
63 new { AreaId = 14, Url = "/en-gb", Flag = "en-gb", Label = Translate("Engelsk") },
64 new { AreaId = 8, Url = "/nb-no", Flag = "nb-no", Label = Translate("Norsk") },
65 }
66 : new[]
67 {
68 new { AreaId = 12, Url = "", Flag = "da-dk", Label = Translate("Dansk") },
69 new { AreaId = 11, Url = "", Flag = "en-gb", Label = Translate("Engelsk") },
70 new { AreaId = 9, Url = "", Flag = "nb-NO", Label = Translate("Norsk") },
71 new { AreaId = 10, Url = "", Flag = "sv-se", Label = Translate("Svensk") },
72 };
73
74 string myProfilePageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("MyJungetPage");
75
76 // Logo must point at the frontpage of the current language (Danish is the root "/")
77 var currentLanguage = languages.FirstOrDefault(l => l.AreaId == currentAreaId);
78 string logoLink = currentLanguage != null && !string.IsNullOrEmpty(currentLanguage.Url) ? currentLanguage.Url : "/";
79 }
80 <header class="overflow-hidden lg:overflow-visible lg:py-2">
81 <div class="container mx-auto">
82 <div class="flex h-[100px] items-center justify-between lg:h-[70px]">
83 <div class="m-auto flex-shrink-0 text-center lg:m-0 lg:text-left" data-name="Logo">
84 <a href="@logoLink" class="no-underline">
85 <img src="@logoPath" alt="@Translate("Logo")" class="h-[37px] w-[170px]" />
86 </a>
87 </div>
88
89 <!-- Search Bar. Typeahead results HTML in footer -->
90 <div class="mx-auto hidden max-w-[570px] flex-1 px-4 lg:block">
91 @RenderPartial("/Designs/Junget2026/Master/Partials/SearchInput.cshtml")
92 </div>
93
94 <!-- Top Right: Utility Links, Language, Cart -->
95 <div class="flex hidden items-center gap-4 lg:flex">
96
97 <div class="hidden items-center gap-5 md:flex">
98
99 @if (Model.Area.Item.GetLink("LoginLink") != null)
100 {
101 if (Pageview.User != null)
102 {
103 <a class="text-center font-light text-[12px] text-black"
104 href="@myProfilePageLink">@Translate("HeaderProfileButton", "Mit Junget")</a>
105 <a class="text-center font-light text-[12px] text-black"
106 href="/Admin/Public/ExtranetLogoff.aspx?ID=@Model.ID">@Translate("Log ud")</a>
107 }
108 else
109 {
110 bool showLoginAside = GetPageIdByNavigationTag("ForgotPassword") != Model.ID && GetPageIdByNavigationTag("CustomerPasswordCreate") != Model.ID;
111
112 if (showLoginAside)
113 {
114 <a href="javascript:void(0)" class="text-center font-light text-[12px] text-black"
115 data-aside-open="login-aside">@Translate("Log ind")</a>
116 }
117 else
118 {
119 string loginLink = "/Default.aspx?ID=" + Model.Area.Item.GetLink("LoginLink").PageId;
120
121 <a href="@loginLink"
122 class="text-center font-light text-[12px] text-black">@Translate("Log ind")</a>
123 }
124 }
125 }
126
127 @if (Model.Area.Item.GetItems("HeaderQuicklinks").Any())
128 {
129 foreach (var quickLink in Model.Area.Item.GetItems("HeaderQuicklinks"))
130 {
131 <a href="@quickLink.GetString("Link")" class="text-center font-light text-[12px] text-black">@quickLink.GetString("Name")</a>
132 }
133 }
134 </div>
135
136 @if (showLanguageSelector)
137 {
138 <div class="group relative">
139 <button class="flex cursor-pointer items-center gap-1.5 border-0 bg-transparent px-2 py-1 transition-opacity hover:opacity-80"
140 type="button"
141 id="languageDropdown"
142 aria-haspopup="true"
143 aria-expanded="false">
144 <img src="/Assets/Junget2026/Images/Icons/Flags/@(rootCultureName).svg" width="20" height="15" alt="@Translate("Sprog")" class="block" data-name="Flags" />
145 <img src="@chevronDownIconPath" alt="Dropdown" class="h-[12px] w-[12px]" />
146 </button>
147
148 <div class="absolute right-0 top-full h-2 w-full"></div>
149 <div class="invisible absolute right-0 top-full z-50 min-w-[150px] rounded border border-gold/20 bg-white py-2 pt-2 shadow-xl group-hover:visible hover:visible" aria-labelledby="languageDropdown">
150 @foreach (var lang in languages)
151 {
152 var area = new Dynamicweb.Content.AreaService().GetArea(lang.AreaId);
153 var domainLock = area?.DomainLock ?? "";
154 var href = !string.IsNullOrEmpty(domainLock)
155 ? "//" + domainLock
156 : (!string.IsNullOrEmpty(lang.Url) ? lang.Url : "#");
157 var isActive = Pageview.AreaID == lang.AreaId;
158 <a class="flex items-center px-4 py-2 transition-colors duration-200 hover:bg-gold/10 hover:text-gold @(isActive ? "text-gold font-medium" : "")"
159 href="@href">
160 <img width="20" height="15" src="/Assets/Junget2026/Images/Icons/Flags/@(lang.Flag).svg" alt="@lang.Label" class="mr-2" />
161 @lang.Label
162 </a>
163 }
164 </div>
165 </div>
166 }
167
168 </div>
169 </div>
170 </div>
171
172
173 <nav class="hidden bg-white lg:block">
174 <div class="container mx-auto">
175 <div class="flex h-[65px] items-center justify-between">
176
177 @{
178 var navigationSettings = new NavigationSettings()
179 {
180 StartLevel = 1,
181 StopLevel = 3,
182 ExpandMode = ExpandMode.All
183 };
184 var navigationTemplate = "Navigation/HeaderNav.cshtml";
185 }
186 @Navigation.RenderNavigation(navigationTemplate, navigationSettings)
187
188 <div class="flex items-center gap-3">
189 @if (GetPageIdByNavigationTag("Webshop") > 0)
190 {
191 <a href="@webshopLink" class="btn btn-gold btn-md">
192 @Translate("Webshop")
193 </a>
194 }
195 @if (GetPageIdByNavigationTag("minicartpageid") > 0)
196 {
197 <div class="relative">
198 <div class="pointer-events-none absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-[#948257] text-xs font-bold text-white @(cartQty > 0 ? "" : "hidden")" id="js-cart-count">
199 @cartQty
200 </div>
201 <button data-aside-open="cart-aside" data-cart-always-clickable="@cartAlwaysClickableAttribute" class="js-cart-button block leading-none no-underline @cartButtonStateClasses" aria-label="@Translate("Indkøbskurv")">
202 <img src="@cartIconPath" alt="@Translate("Indkøbskurv")" class="w-[22px]" />
203 </button>
204 </div>
205 }
206 </div>
207 </div>
208 </div>
209 </nav>
210 </header>
211
212
213 @if (Pageview.Page.ID == GetPageIdByNavigationTag("Frontpage") && !isLocalHost)
214 {
215 @RenderPartial("/Designs/Junget2026/Master/Partials/App.cshtml")
216 }
217
218
219 @using Dynamicweb.Frontend.Devices
220 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
221
222
223
224 @RenderPartial("/Designs/Junget2026/Partials/DeliveryBlock.cshtml", Model)
225
226 @if (string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"]))
227 {
228 @RenderPartial("/Designs/Junget2026/Partials/TopContent.cshtml", Model)
229 }
230
231 @Model.Placeholder("content", "Content")
232
233 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
234 @using Dynamicweb.Security.UserManagement
235 @using Dynamicweb.Frontend.Navigation;
236 @{
237 // Footer-specific URLs (reusing common ones from Header if they exist)
238 string footerProfileLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("MyJungetPage");
239 string footerContactLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("contactpage");
240
241 // Footer-specific icons (reusing common ones from Header if they exist)
242 string footerPhoneIconPath = "/Assets/Junget2026/Images/Icons/phone-sharp-light-full.svg";
243 string footerUserIconPath = "/Assets/Junget2026/Images/Icons/user-sharp-light-full.svg";
244 string footerBarsIconPath = "/Assets/Junget2026/Images/Icons/bars-sharp-light-full.svg";
245 string footerSearchIconPath = "/Assets/Junget2026/Images/Icons/magnifying-glass-sharp-light-full.svg";
246 string footerCartIconPath = "/Assets/Junget2026/Images/Icons/cart-shopping-sharp-light-full.svg";
247
248 string footerColOne = Model.Area.Item.GetString("FooterColumn1Text");
249 string footerColTwo = Model.Area.Item.GetString("FooterColumn2Text");
250 string footerColThree = Model.Area.Item.GetString("FooterColumn3Text");
251 var footerIcons = Model.Area.Item.GetItems("FooterSocialMediaLinks");
252 var paymentMethodPictures = Model.Area.Item.GetItems("Payment_Methods_Picture");
253
254 string co2NeutralPicture = Model.Area.Item.GetString("Co2_Neutralt_Picture");
255 string co2NeutralLink = Model.Area.Item.GetString("Co2_Neutralt_Link");
256 int miniCartParagraphId = 0;
257 if (Model.Area.Item.GetLink("MinicartLink") != null)
258 {
259 miniCartParagraphId = Model.Area.Item.GetLink("MinicartLink").ParagraphId;
260 }
261
262 User mainUserHeader = Pageview.User?.CurrentSecondaryUser != null ? Pageview.User.CurrentSecondaryUser : Pageview.User;
263 if (mainUserHeader != null && mainUserHeader.HasGroup(24) && Model.Area.Item.GetLink("SalesmanMiniCart") != null)
264 {
265 miniCartParagraphId = Model.Area.Item.GetLink("SalesmanMiniCart").ParagraphId;
266 }
267
268 int loginParagraphId = 0;
269
270 if (Model.Area.Item.GetLink("LoginLink") != null)
271 {
272 loginParagraphId = Model.Area.Item.GetLink("LoginLink").ParagraphId;
273 }
274
275 //Dont render login aside markup if already on login page
276 bool showLoginAsideMarkup = (GetPageIdByNavigationTag("ForgotPassword") != Model.ID && GetPageIdByNavigationTag("CustomerPasswordCreate") != Model.ID) && loginParagraphId > 0;
277
278 int favoriteServiceParagraphId = 0;
279
280
281 if (Model.Area.Item.GetLink("FavoriteService") != null)
282 {
283 favoriteServiceParagraphId = Model.Area.Item.GetLink("FavoriteService").ParagraphId;
284 }
285
286
287 }
288
289 @helper RenderFooterNavItem(string href, string iconPath, string label, bool isButton = false, string dataASide = "", string appendClasses = "")
290 {
291 appendClasses += " min-w-[40px]";
292 if (isButton)
293 {
294 <button type="button" class="js-mobile-menu-toggle flex cursor-pointer flex-col items-center justify-center border-0 bg-transparent py-2 text-white @appendClasses">
295 <img src="@iconPath" alt="@label" class="pointer-events-none mb-1 w-[20px] brightness-0 invert" />
296 <p class="footer-nav-label pointer-events-none">@label</p>
297 </button>
298 }
299 else
300 {
301 string dataASideAttr = (dataASide.Length > 0) ? "data-aside-open='" + dataASide + "' data-close-on-reclick='true'" : "";
302 if (dataASide.Length > 0)
303 {
304 href = "javascript:void(0)";
305 }
306
307 <a @dataASideAttr href="@href" class="flex flex-col items-center justify-center py-2 text-white no-underline @appendClasses">
308 <img src="@iconPath" alt="@label" class="pointer-events-none mb-1 w-[20px] brightness-0 invert" />
309 <p class="footer-nav-label pointer-events-none">@label</p>
310 </a>
311 }
312 }
313
314
315 <footer class="overflow-hidden bg-white">
316
317 <!-- Desktop Footer -->
318 <div class="rounded-t-default footer rounded-b-default relative mb-24 mt-8 bg-sand text-primary lg:mb-0 lg:block lg:rounded-b-none @(Model.Area.FirstPage.ID == Model.ID ? "hidden lg:block" : "")" ">
319 <div class="container mx-auto py-8 lg:py-16">
320 <div class="pointer-events-none absolute bottom-0 right-0 top-16 flex hidden w-[276px] items-center justify-center lg:block">
321 <div class="rotate-180">
322 <img src="/Assets/Junget2026/Images/Icons/circle.svg" alt="" class="h-[436px] w-[276px] object-contain" />
323 </div>
324 </div>
325
326 <div class="relative z-10 flex flex-col gap-10 lg: lg:flex-row lg:gap-14">
327 <div class="flex w-[250px] flex-col gap-6">
328 <div>
329 @footerColOne
330 </div>
331
332 <!-- Payment Logos -->
333 <div class="absolute bottom-0 flex items-center gap-2 lg:relative">
334 @if (paymentMethodPictures.Count > 0)
335 {
336 foreach (var paymentMethodPicture in paymentMethodPictures)
337 {
338 <a href="@paymentMethodPicture.GetString("Link")">
339 <img src="@paymentMethodPicture.GetString("Icon")" alt="@paymentMethodPicture.GetString("ImageAltTag")" class="h-[19px] object-contain" />
340 </a>
341 }
342 }
343 </div>
344 </div>
345
346 <div class="flex w-[250px] flex-col gap-8">
347 <div>
348 @footerColTwo
349 </div>
350
351 <div>
352 <h4>@Translate("Følg med")</h4>
353 <div class="leading-[20px] flex flex-col gap-2 text-[16px] lg:flex-row lg:gap-8">
354 @if (footerIcons.Count > 0)
355 {
356 foreach (var footerItem in footerIcons)
357 {
358 <a href="@footerItem.GetString("Link")" class="items flex items-center gap-2 text-primary hover:text-gold">
359 @if (footerItem.GetString("Icon").EndsWith("svg"))
360 {
361 @Dynamicweb.VestjyskMarketing.Helpers.ImageHelper.GetSVG(footerItem.GetString("Icon"), "w-[15px] fill-gold");
362 }
363 else
364 {
365 <img src="@footerItem.GetString("Icon")" alt="@footerItem.GetString("ImageAltTag")" class="h-[15px] w-[15px]" style="fill: #D4AF37;" />
366 }
367 <span>@footerItem.GetString("ImageAltTag")</span>
368 </a>
369 }
370 }
371 </div>
372 </div>
373 </div>
374
375 <div class="flex w-[270px] flex-col justify-between">
376 <div>
377 @footerColThree
378 </div>
379
380 <div class="mb-14 mt-8 lg:absolute lg:bottom-0 lg:right-0 lg:mb-0 lg:mt-auto">
381 <a href="@co2NeutralLink" target="_blank">
382 <img src="@co2NeutralPicture" alt="@Translate("CO2 neutralt website")"
383 class="w-[200px] object-contain" />
384 </a>
385 </div>
386 </div>
387 </div>
388 </div>
389 </div>
390
391 <!-- Mobile Menu Overlay -->
392 <div id="mobileMenu" class="js-mobile-menu-toggle z-[60] fixed inset-0 hidden bg-black bg-opacity-50 transition-opacity duration-300 lg:hidden">
393 <!-- Menu Panel -->
394 <div class="z-[60] fixed bottom-[70px] left-0 right-0 max-h-[80vh] translate-y-full transform overflow-y-auto rounded-t-[20px] border-t border-gold/20 bg-white shadow-2xl transition-transform duration-300"
395 id="mobileMenuPanel" onclick="event.stopPropagation()">
396 <div class="px-6 pb-8 pt-6">
397 <!-- Menu Header -->
398 <div class="mb-6 flex items-center justify-between">
399 <h2 class="text-[20px] text-primary">@Translate("Menu")</h2>
400 <button class="js-mobile-menu-toggle btn btn-gold-hover x-mark"></button>
401 </div>
402
403 @{
404 var footerSettings = new NavigationSettings()
405 {
406 StartLevel = 1,
407 StopLevel = 3,
408 ExpandMode = ExpandMode.All
409 };
410 }
411 @Navigation.RenderNavigation("Navigation/FooterNav.cshtml", footerSettings)
412 </div>
413 </div>
414 </div>
415
416
417 <!-- Bottom Navigation Bar -->
418 <div class="z-[70] fixed bottom-0 left-0 right-0 flex h-[70px] items-center justify-around bg-primary px-4 lg:hidden" data-node-id="61:1252">
419 <!-- Menu -->
420 @RenderFooterNavItem("#", footerBarsIconPath, Translate("Menu"), true, "")
421
422 <!-- Søg (Search) -->
423 @RenderFooterNavItem("javascript:void(0)", footerSearchIconPath, Translate("Søg"), false, "", "js-mobile-open-search")
424
425 <!-- Kontakt (Contact) - Highlighted Gold Button with Blue Circle -->
426 <div class="relative flex flex-col items-center justify-center" data-node-id="156:2045">
427 <!-- Blue outer circle -->
428 <div class="absolute -top-[35px] z-10 flex h-[60px] w-[60px] items-center justify-center rounded-full bg-primary" data-node-id="156:2046">
429 <!-- Gold inner circle -->
430 <div class="shadow-default flex h-[52px] w-[52px] items-center justify-center rounded-full bg-gold">
431 <a href="@footerContactLink" class="flex h-full w-full items-center justify-center no-underline" data-node-id="61:1261">
432 <img src="@footerPhoneIconPath" alt="@Translate("Kontakt")" class="w-[22px] brightness-0 invert" />
433 </a>
434 </div>
435 </div>
436 <p class="footer-nav-label mt-6">@Translate("Kontakt")</p>
437 </div>
438
439 <!-- Profil (Profile) -->
440 @if (loginParagraphId > 0)
441 {
442 if (Pageview.User != null)
443 {
444 @RenderFooterNavItem(footerProfileLink, footerUserIconPath, @Translate("HeaderProfileButton", "Mit Junget"), false)
445 }
446 else
447 {
448 @RenderFooterNavItem("", footerUserIconPath, Translate("Login"), false, "login-aside")
449 }
450 }
451
452 <!-- Kurv (Cart) -->
453 @if (miniCartParagraphId > 0)
454 {
455 @RenderFooterNavItem("", footerCartIconPath, Translate("Kurv"), false, "cart-aside")
456 }
457 </div>
458 </footer>
459
460 <!-- Typeahead search. used in header and mobile -->
461 <div class="js-typeahead-results container absolute left-0 right-0 z-50 mx-auto hidden bg-white pt-12 lg:rounded-default lg:mt-1 lg:border lg:border-gray-300 lg:pt-2 lg:shadow-xl">
462 <div class="lg:hidden">
463 @{
464 var searchInput = new Dictionary<string, object>();
465 searchInput.Add("isMobile", true);
466 @RenderPartial("/Designs/Junget2026/Master/Partials/SearchInput.cshtml", Model, searchInput);
467 }
468 </div>
469
470 <div class="js-typeahead-spinner flex hidden justify-center py-4">
471 <div class="h-10 w-10 animate-spin rounded-full border-2 border-gray-300 border-t-gray-600 lg:h-5 lg:w-5"></div>
472 </div>
473 <div class="js-typeahead-content grid grid-cols-1 gap-12 lg:grid-cols-2 lg:gap-0 lg:divide-x lg:divide-gray-200"></div>
474 </div>
475
476 <!-- Asides -->
477 @if (miniCartParagraphId > 0)
478 {
479 var modelAsideModel = new Website.CustomCode.ViewModels.Templates.AsideOverlayViewModel();
480 modelAsideModel.ClassesContent = "mt-12";
481 modelAsideModel.paragraphId = miniCartParagraphId;
482 modelAsideModel.AsideId = "cart-aside";
483 @RenderPartial("/Designs/Junget2026/Partials/AsideOverlay.cshtml", modelAsideModel);
484 }
485
486
487 @if (showLoginAsideMarkup)
488 {
489 var modelAsideModel = new Website.CustomCode.ViewModels.Templates.AsideOverlayViewModel();
490