Error executing template "Designs/Swift/Navigation/MegaMenu.cshtml" System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Dynamicweb.Ecommerce.Products.GroupRelation.GetGroupRelationsByChildId(String childId) at Dynamicweb.Ecommerce.Products.Group.get_IsTopGroup() at Dynamicweb.Ecommerce.Shops.Shop.GetTopLevelGroups(String languageId) at Dynamicweb.Ecommerce.Frontend.Navigation.GroupNavigationTreeNodeProvider.GetGroupsBySettings(PageNavigationSettings ecomSettings) at Dynamicweb.Ecommerce.Frontend.Navigation.GroupNavigationTreeNodeProvider.GetGroups(NavigationTreeNode parent, Page page) at Dynamicweb.Ecommerce.Frontend.Navigation.GroupNavigationTreeNodeProvider.GetNodes(NavigationContext context, NavigationSettings settings, NavigationTreeNode parent) at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() at CompiledRazorTemplates.Dynamic.RazorEngine_01eae9d04bb3409d9901c5194504fbb9.<>c__DisplayClass0_0.<RenderFirstLevelNodes>b__0(TextWriter __razor_helper_writer) in E:\Solutions\JSKomponenter2024\Files\Templates\Designs\Swift\Navigation\MegaMenu.cshtml:line 53 at CompiledRazorTemplates.Dynamic.RazorEngine_01eae9d04bb3409d9901c5194504fbb9.Execute() in E:\Solutions\JSKomponenter2024\Files\Templates\Designs\Swift\Navigation\MegaMenu.cshtml:line 26 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()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.Navigation.NavigationTreeViewModel> 2 @using Dynamicweb 3 @using System.IO 4 @using Dynamicweb.Ecommerce.ProductCatalog 5 6 @{ 7 string theme = !string.IsNullOrEmpty(Model.Parameters["theme"].ToString()) ? Model.Parameters["theme"].ToString() : string.Empty; 8 string navAlignment = !string.IsNullOrEmpty(Model.Parameters["NavAlignment"].ToString()) ? Model.Parameters["NavAlignment"].ToString() : string.Empty; 9 string linkFontWeight = !string.IsNullOrEmpty(Model.Parameters["LinkFontWeight"].ToString()) ? Model.Parameters["LinkFontWeight"].ToString() : string.Empty; 10 string linkCasing = !string.IsNullOrEmpty(Model.Parameters["LinkCasing"].ToString()) ? Model.Parameters["LinkCasing"].ToString() : string.Empty; 11 string linkFontSize = !string.IsNullOrEmpty(Model.Parameters["LinkFontSize"].ToString()) ? Model.Parameters["LinkFontSize"].ToString() : string.Empty; 12 string layout = !string.IsNullOrEmpty(Model.Parameters["Layout"].ToString()) ? Model.Parameters["Layout"].ToString() : string.Empty; 13 string iconSize = "icon-3"; 14 15 if (linkFontSize == "fs-7") 16 { 17 iconSize = "icon-2"; 18 } 19 if (linkFontSize == "fs-5") 20 { 21 iconSize = "icon-4"; 22 } 23 } 24 25 <nav class="d-flex py-0 @navAlignment"> 26 @{@RenderFirstLevelNodes(Model.Nodes, theme, linkFontWeight, linkCasing, linkFontSize, iconSize, layout)} 27 </nav> 28 29 @helper RenderFirstLevelNodes(IEnumerable<Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel> nodes, string theme, string linkFontWeight, string linkCasing, string linkFontSize, string iconSize, string layout) 30 { 31 string dropdownAlignment = Model.Parameters["DropdownAlignment"] != null ? Model.Parameters["DropdownAlignment"].ToString() : string.Empty; 32 string dropdownLinkHeaderFontWeight = Model.Parameters["DropdownLinkHeaderFontWeight"] != null ? Model.Parameters["DropdownLinkHeaderFontWeight"].ToString() : string.Empty; 33 string dropdownLinkHeaderCasing = Model.Parameters["DropdownLinkHeaderCasing"] != null ? Model.Parameters["DropdownLinkHeaderCasing"].ToString() : string.Empty; 34 string dropdownLinkHeaderFontSize = Model.Parameters["DropdownLinkHeaderFontSize"] != null ? Model.Parameters["DropdownLinkHeaderFontSize"].ToString() : string.Empty; 35 string dropdownLinkFontWeight = Model.Parameters["DropdownLinkFontWeight"] != null ? Model.Parameters["DropdownLinkFontWeight"].ToString() : string.Empty; 36 string dropdownLinkCasing = Model.Parameters["DropdownLinkCasing"] != null ? Model.Parameters["DropdownLinkCasing"].ToString() : string.Empty; 37 string dropdownLinkFontSize = Model.Parameters["DropdownLinkFontSize"] != null ? Model.Parameters["DropdownLinkFontSize"].ToString() : string.Empty; 38 string productGroupImagePlacement = Model.Parameters["ProductGroupImagePlacement"] != null ? Model.Parameters["ProductGroupImagePlacement"].ToString() : string.Empty; 39 string imageAlignment = ""; 40 imageAlignment = dropdownAlignment == "justify-content-start text-start" && productGroupImagePlacement == "flex-row" ? "align-items-center" : imageAlignment; 41 imageAlignment = dropdownAlignment == "justify-content-start text-start" && productGroupImagePlacement == "flex-row-reverse" ? "align-items-center" : imageAlignment; 42 imageAlignment = dropdownAlignment == "justify-content-start text-start" && productGroupImagePlacement == "flex-column" ? "align-items-start" : imageAlignment; 43 imageAlignment = dropdownAlignment == "justify-content-center text-center" && productGroupImagePlacement == "flex-row" ? "align-items-center" : imageAlignment; 44 imageAlignment = dropdownAlignment == "justify-content-center text-center" && productGroupImagePlacement == "flex-row-reverse" ? "align-items-center" : imageAlignment; 45 imageAlignment = dropdownAlignment == "justify-content-center text-center" && productGroupImagePlacement == "flex-column" ? "align-items-center" : imageAlignment; 46 imageAlignment = dropdownAlignment == "justify-content-end text-end" && productGroupImagePlacement == "flex-row" ? "align-items-center" : imageAlignment; 47 imageAlignment = dropdownAlignment == "justify-content-end text-end" && productGroupImagePlacement == "flex-row-reverse" ? "align-items-center" : imageAlignment; 48 bool showProductGroupPromotionImage = Model.Parameters.ContainsKey("ShowProductGroupPromotionImage") ? Convert.ToBoolean(Model.Parameters["ShowProductGroupPromotionImage"].ToString()) : false; 49 string menuId = Model.Parameters.ContainsKey("menu-id") ? $"menu_{Model.Parameters["menu-id"].ToString().ToLower()}" : string.Empty; 50 int currentParagraphId = Pageview.CurrentParagraph.ID; 51 52 <ul class="nav flex-nowrap @menuId"> 53 @foreach (var node in nodes) 54 { 55 var page = Dynamicweb.Content.Services.Pages.GetPage(node.PageId); 56 var pageType = !string.IsNullOrEmpty(page.ItemType) ? page.ItemType : "Swift_Page"; 57 58 string submenuType = "auto"; 59 if (page.PropertyItem is object && page.PropertyItem.TryGetValue("SubmenuType", out object submenuTypeValue)) 60 { 61 submenuType = Dynamicweb.Core.Converter.ToString(submenuTypeValue); 62 } 63 string pageIcon = string.Empty; 64 if (page.PropertyItem is object && page.PropertyItem.TryGetValue("Icon", out object pageIconValue)) 65 { 66 pageIcon = Dynamicweb.Core.Converter.ToString(pageIconValue); 67 } 68 69 var hasChildren = node.Nodes.Count() > 0; 70 string dropdownAttributes = hasChildren ? " role=\"button\" aria-haspopup=\"true\" aria-expanded=\"false\" data-bs-toggle=\"dropdown\" data-bs-offset=\"0,0\"" : ""; 71 72 bool hasManyChildren = false; 73 foreach (var subnode in node.Nodes) 74 { 75 if (subnode.Nodes.Any()) 76 { 77 hasManyChildren = true; 78 } 79 } 80 81 submenuType = submenuType == "auto" && hasManyChildren ? "megamenu" : submenuType; 82 submenuType = submenuType == "auto" && !hasManyChildren ? "dropdown" : submenuType; 83 string submenuTypeCss = submenuType == "dropdown" ? " dropdown" : ""; 84 submenuTypeCss = submenuType == "megamenu" ? " dropdown position-static" : submenuTypeCss; 85 86 string nodeId = !string.IsNullOrEmpty(node.GroupId) ? "Megamenu_" + node.GroupId + "_" + currentParagraphId : "Megamenu_Page_" + node.PageId.ToString() + "_" + currentParagraphId; 87 string dataType = !string.IsNullOrEmpty(node.GroupId) ? "group" : "page"; 88 89 <li id="@(nodeId)" data-type="@dataType" class="nav-item@(node.IsActive ? " active" : "")@submenuTypeCss"> 90 @if (node.IsClickable) 91 { 92 <a class="nav-link p-2 text-decoration-underline-hover @linkFontWeight @linkCasing @linkFontSize@(node.IsActive ? " active" : "")@(hasChildren ? " dropdown-toggle" : "")" href="@node.Link" @dropdownAttributes id="NavLink_@nodeId"> 93 @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout)} 94 </a> 95 } 96 else 97 { 98 <span class="nav-link p-2 @linkFontWeight @linkCasing @linkFontSize @dropdownAlignment@(hasChildren ? " dropdown-toggle" : "")" @dropdownAttributes id="NavLink_@nodeId"> 99 @{@RenderNavigationItem(node, pageType, pageIcon, iconSize, layout)} 100 </span> 101 } 102 103 @if (hasChildren) 104 { 105 if (submenuType == "megamenu") 106 { 107 <div class="dropdown-menu megamenu py-4@(theme)" aria-labelledby="@nodeId" id="NavGroup@(nodeId)"> 108 <div class="container-xl"> 109 @if (showProductGroupPromotionImage && !string.IsNullOrEmpty(node.GroupId)) 110 { 111 <div class="grid gap-4"> 112 <div class="g-col-9 g-col-xxl-10"> 113 <div class="d-flex flex-wrap gap-3 mx-n2 mx-xxl-n3 @dropdownAlignment"> 114 @foreach (var subnode in node.Nodes) 115 { 116 nodeId = !string.IsNullOrEmpty(subnode.GroupId) ? "Megamenu_" + subnode.GroupId + "_" + currentParagraphId : "Megamenu_Page_" + subnode.PageId.ToString() + "_" + currentParagraphId; 117 dataType = !string.IsNullOrEmpty(subnode.GroupId) ? "group" : "page"; 118 119 <div class="col-4 col-xl-3 col-xxl-2"> 120 @if (subnode.IsClickable) 121 { 122 <a id="@(nodeId)" data-type="@dataType" href="@subnode.Link" class="nav-link text-decoration-underline-hover lh-sm text-break"> 123 @if (productGroupImagePlacement != "none") 124 { 125 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 126 @{@RenderGroupImage(subnode.GetProductGroup())} 127 <h6 class="m-0 w-100 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 128 </div> 129 } 130 else 131 { 132 <h6 class="m-0 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 133 } 134 </a> 135 } 136 else 137 { 138 <div id="@(nodeId)" data-type="@dataType" class="nav-link lh-sm text-break"> 139 @if (productGroupImagePlacement != "none") 140 { 141 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 142 @{@RenderGroupImage(subnode.GetProductGroup())} 143 <h6 class="m-0 w-100 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 144 </div> 145 } 146 else 147 { 148 <h6 class="m-0 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 149 } 150 </div> 151 } 152 153 @if (subnode.Nodes.Any()) 154 { 155 foreach (var subsubnode in subnode.Nodes) 156 { 157 nodeId = !string.IsNullOrEmpty(subsubnode.GroupId) ? "Megamenu_" + subsubnode.GroupId + "_" + currentParagraphId : "Megamenu_Page_" + subsubnode.PageId.ToString() + "_" + currentParagraphId; 158 dataType = !string.IsNullOrEmpty(subsubnode.GroupId) ? "group" : "page"; 159 160 if (subsubnode.IsClickable) 161 { 162 <a class="nav-link text-decoration-underline-hover lh-sm text-break" href="@subsubnode.Link" @(subnode.IsActive ? " aria-current='page'" : "")> 163 @if (productGroupImagePlacement != "none") 164 { 165 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 166 @{@RenderGroupImage(subsubnode.GetProductGroup())} 167 <span class="w-100 @dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 168 </div> 169 } 170 else 171 { 172 <span class="@dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 173 } 174 </a> 175 } 176 else 177 { 178 <div class="nav-link text-decoration-underline-hover lh-sm text-break" @(subnode.IsActive ? " aria-current='page'" : "")> 179 @if (productGroupImagePlacement != "none") 180 { 181 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 182 @{@RenderGroupImage(subsubnode.GetProductGroup())} 183 <span class="w-100 @dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 184 </div> 185 } 186 else 187 { 188 <span class="@dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 189 } 190 </div> 191 } 192 } 193 } 194 </div> 195 } 196 </div> 197 </div> 198 <div class="g-col-3 g-col-xxl-2" id="NavGroupPromotion@(nodeId)"> 199 @{@RenderProductGroupPromotionImage(node.GetProductGroup(), node.Link)} 200 </div> 201 </div> 202 } 203 else 204 { 205 <div class="d-flex flex-wrap mx-n2 mx-xxl-n3 @dropdownAlignment"> 206 @foreach (var subnode in node.Nodes) 207 { 208 nodeId = !string.IsNullOrEmpty(subnode.GroupId) ? "Megamenu_" + subnode.GroupId + "_" + currentParagraphId : "Megamenu_Page_" + subnode.PageId.ToString() + "_" + currentParagraphId; 209 dataType = !string.IsNullOrEmpty(subnode.GroupId) ? "group" : "page"; 210 211 <div class="col-4 col-xl-3 col-xxl-2"> 212 @if (subnode.IsClickable) 213 { 214 <a id="@(nodeId)" data-type="@dataType" href="@subnode.Link" class="nav-link text-decoration-underline-hover lh-sm text-break"> 215 @if (productGroupImagePlacement != "none") 216 { 217 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 218 @{@RenderGroupImage(subnode.GetProductGroup())} 219 <h6 class="m-0 w-100 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 220 </div> 221 } 222 else 223 { 224 <h6 class="m-0 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 225 } 226 </a> 227 } 228 else 229 { 230 <div id="@(nodeId)" data-type="@dataType" class="nav-link -sm text-break"> 231 @if (productGroupImagePlacement != "none") 232 { 233 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 234 @{@RenderGroupImage(subnode.GetProductGroup())} 235 <h6 class="m-0 w-100 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 236 </div> 237 } 238 else 239 { 240 <h6 class="m-0 @dropdownLinkHeaderFontWeight @dropdownLinkHeaderCasing @dropdownLinkHeaderFontSize">@subnode.Name</h6> 241 } 242 </div> 243 } 244 245 246 @if (subnode.Nodes.Any()) 247 { 248 foreach (var subsubnode in subnode.Nodes) 249 { 250 nodeId = !string.IsNullOrEmpty(subsubnode.GroupId) ? "Megamenu_" + subsubnode.GroupId + "_" + currentParagraphId : "Megamenu_Page_" + subsubnode.PageId.ToString() + "_" + currentParagraphId; 251 dataType = !string.IsNullOrEmpty(subsubnode.GroupId) ? "group" : "page"; 252 253 if (subsubnode.IsClickable) 254 { 255 <a id="@(nodeId)" data-type="@dataType" class="nav-link text-decoration-underline-hover lh-sm text-break" href="@subsubnode.Link" @(subnode.IsActive ? " aria-current='page'" : "")> 256 @if (productGroupImagePlacement != "none") 257 { 258 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 259 @{@RenderGroupImage(subsubnode.GetProductGroup())} 260 <span class="w-100 @dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 261 </div> 262 } 263 else 264 { 265 <span class="@dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 266 } 267 </a> 268 } 269 else 270 { 271 <div id="@(nodeId)" data-type="@dataType" class="nav-link lh-sm text-break" @(subnode.IsActive ? " aria-current='page'" : "")> 272 @if (productGroupImagePlacement != "none") 273 { 274 <div class="d-flex @productGroupImagePlacement @imageAlignment gap-3"> 275 @{@RenderGroupImage(subsubnode.GetProductGroup())} 276 <span class="w-100 @dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 277 </div> 278 } 279 else 280 { 281 <span class="@dropdownLinkFontWeight @dropdownLinkCasing @dropdownLinkFontSize">@subsubnode.Name</span> 282 } 283 </div> 284 } 285 } 286 } 287 </div> 288 } 289 </div> 290 } 291 </div> 292 </div> 293 } 294 else 295 { 296 <ul class="dropdown-menu@(theme)" aria-labelledby="@nodeId"> 297 @if (pageType == "Swift_SignIn") 298 { 299 if (Pageview.User == null) 300 { 301 <li> 302 <a href="@node.Link" class="px-3 py-2 dropdown-item text-decoration-underline-hover @linkFontWeight @linkCasing @linkFontSize" @(node.IsActive ? " aria-current='page'" : "")>@node.Name</a> 303 </li> 304 } 305 } 306 307 @foreach (var subnode in node.Nodes) 308 { 309 <li> 310 @if (subnode.IsClickable) 311 { 312 <a class="px-3 py-2 dropdown-item text-decoration-underline-hover @linkFontWeight @linkCasing @linkFontSize" href="@subnode.Link" @(node.IsActive ? " aria-current='page'" : "")>@subnode.Name</a> 313 } 314 else 315 { 316 <span class="px-3 py-2 dropdown-item @linkFontWeight @linkCasing @linkFontSize" @(node.IsActive ? " aria-current='page'" : "")>@subnode.Name</span> 317 } 318 </li> 319 } 320 321 @if (pageType == "Swift_SignIn") 322 { 323 if (Pageview.User != null) 324 { 325 string link = "/Admin/Public/ExtranetLogoff.aspx?redirect=no"; 326 327 <li><hr class="dropdown-divider"></li> 328 329 if (Dynamicweb.Security.UserManagement.User.GetCurrentSecondaryUser() != null) 330 { 331 <li> 332 <a href="Default.aspx?ID=@(Pageview.ID)&DwExtranetRemoveSecondaryUser=1" class="px-3 py-2 dropdown-item text-decoration-underline-hover swift_sign-out-as-customer-link @linkFontWeight @linkCasing @linkFontSize" @(node.IsActive ? " aria-current='page'" : "")>@Translate("Sign out as a customer")</a> 333 </li> 334 } 335 <li> 336 <a href="@link" class="px-3 py-2 dropdown-item text-decoration-underline-hover swift_sign-out-link @linkFontWeight @linkCasing @linkFontSize" @(node.IsActive ? " aria-current='page'" : "")>@Translate("Sign out")</a> 337 </li> 338 } 339 340 } 341 </ul> 342 } 343 } 344 </li> 345 } 346 </ul> 347 } 348 349 @helper RenderNavigationItem(Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel node, string pageType, string pageIcon, string iconSize, string layout) 350 { 351 if (pageType == "Swift_Cart") 352 { 353 double totalProducts = 0; 354 355 if (Dynamicweb.Ecommerce.Common.Context.Cart != null) 356 { 357 totalProducts = Dynamicweb.Ecommerce.Common.Context.Cart.GetParentProductLineQuantityCount(Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines); 358 } 359 360 switch (layout) 361 { 362 case "linksOnly": 363 <span>@node.Name</span> 364 <span class="js-cart-qty mini-cart-quantity">(@totalProducts)</span> 365 break; 366 case "iconsOnly": 367 {@RenderIcon(pageIcon, iconSize)} 368 <span class="js-cart-qty mini-cart-quantity">(@totalProducts)</span> 369 break; 370 case "iconsAndLinks": 371 {@RenderIcon(pageIcon, iconSize)} 372 <span class="js-cart-qty mini-cart-quantity">(@totalProducts)</span> 373 <span>@node.Name</span> 374 break; 375 case "linksAndIcons": 376 <span>@node.Name</span> 377 <span class="js-cart-qty mini-cart-quantity">(@totalProducts)</span> 378 {@RenderIcon(pageIcon, iconSize)} 379 break; 380 } 381 } 382 else 383 { 384 switch (layout) 385 { 386 case "linksOnly": 387 <span>@node.Name</span> 388 break; 389 case "iconsOnly": 390 {@RenderIcon(pageIcon, iconSize)} 391 break; 392 case "iconsAndLinks": 393 {@RenderIcon(pageIcon, iconSize)} 394 <span>@node.Name</span> 395 break; 396 case "linksAndIcons": 397 <span>@node.Name</span> 398 {@RenderIcon(pageIcon, iconSize)} 399 break; 400 } 401 } 402 } 403 404 @helper RenderIcon(string pageIcon, string iconSize) 405 { 406 if (pageIcon.EndsWith(".svg", StringComparison.OrdinalIgnoreCase) && !pageIcon.EndsWith("none.svg", StringComparison.OrdinalIgnoreCase)) 407 { 408 string iconPath = Dynamicweb.Context.Current.Server.MapPath(pageIcon); 409 410 <span class="@iconSize"> 411 @ReadFile(iconPath) 412 </span> 413 } 414 } 415 416 417 @helper RenderProductGroupPromotionImage(ProductGroupViewModel group, string link) 418 { 419 IList<FieldValueViewModel> groupFields = group.GroupFields != null ? group.GroupFields : null; 420 421 if (groupFields != null) 422 { 423 var groupName = group.Name; 424 string ratio = Model.Parameters["ImageAspectRatio"].ToString(); 425 ratio = ratio != "0" ? ratio : string.Empty; 426 string ratioCssClass = ratio != string.Empty ? " ratio" : ""; 427 string ratioVariable = ratio != "" ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : string.Empty; 428 string productGroupPromotionImage = string.Empty; 429 string productGroupPromotionImageSrc = string.Empty; 430 string productGroupPromotionImagePath = string.Empty; 431 string productGroupPromotionDescription = string.Empty; 432 string productGroupPromotionLinkLabel = string.Empty; 433 string productGroupPromotionLink = string.Empty; 434 string productGroupPromotionImageTheme = Model.Parameters.ContainsKey("ProductGroupPromotionImageTheme") ? Model.Parameters["ProductGroupPromotionImageTheme"].ToString().ToLower() : string.Empty; 435 string gridGap = !string.IsNullOrEmpty(productGroupPromotionImageTheme) ? "gap-0" : "gap-3"; 436 string themePadding = !string.IsNullOrEmpty(productGroupPromotionImageTheme) ? "p-3" : "p-0"; 437 438 foreach (FieldValueViewModel field in groupFields) 439 { 440 if (field.SystemName == "ProductGroupPromotionImage") 441 { 442 productGroupPromotionImage = field.Value != null ? field.Value.ToString() : string.Empty; 443 productGroupPromotionImageSrc = Dynamicweb.Context.Current.Server.UrlEncode("Files/Images/" + productGroupPromotionImage); 444 productGroupPromotionImagePath = $"/Admin/Public/GetImage.ashx?Image={productGroupPromotionImageSrc}&Width=480&Crop=0"; 445 } 446 if (field.SystemName == "ProductGroupPromotionDescription") 447 { 448 productGroupPromotionDescription = field.Value != null ? field.Value.ToString() : string.Empty; 449 } 450 if (field.SystemName == "ProductGroupPromotionLinkLabel") 451 { 452 productGroupPromotionLinkLabel = field.Value != null ? field.Value.ToString() : string.Empty; 453 } 454 if (field.SystemName == "ProductGroupPromotionLink") 455 { 456 productGroupPromotionLink = field.Value != null ? field.Value.ToString() : string.Empty; 457 } 458 } 459 460 <div class="grid grid-1 @gridGap@(productGroupPromotionImageTheme)"> 461 @if (productGroupPromotionImage != string.Empty) 462 { 463 productGroupPromotionLink = !string.IsNullOrEmpty(productGroupPromotionLink) ? productGroupPromotionLink : link; 464 465 <a href="@productGroupPromotionLink" title="@groupName" id="NavGroupPromotionFigureLink@(group.Id)"> 466 <figure class="m-0@(ratioCssClass)" @ratioVariable> 467 <img class="img-fluid" src="@productGroupPromotionImagePath" alt="@groupName" style="object-fit:cover" loading="lazy"> 468 </figure> 469 </a> 470 } 471 @if (!string.IsNullOrEmpty(productGroupPromotionDescription) || !string.IsNullOrEmpty(productGroupPromotionLinkLabel)) 472 { 473 <div class="grid grid-1 @themePadding "> 474 475 @if (!string.IsNullOrEmpty(productGroupPromotionDescription)) 476 { 477 <h6 class="m-0">@productGroupPromotionDescription</h6> 478 } 479 @if (!string.IsNullOrEmpty(productGroupPromotionLinkLabel)) 480 { 481 productGroupPromotionLink = !string.IsNullOrEmpty(productGroupPromotionLink) ? productGroupPromotionLink : link; 482 483 <a href="@productGroupPromotionLink" title="@productGroupPromotionLinkLabel" class="btn btn-link text-start border-0 p-0" id="NavGroupPromotionTextLink@(group.Id)">@productGroupPromotionLinkLabel</a> 484 } 485 </div> 486 } 487 </div> 488 } 489 } 490 491 @helper RenderGroupImage(ProductGroupViewModel group) 492 { 493 IList<FieldValueViewModel> groupFields = group.GroupFields; 494 495 if (groupFields != null) 496 { 497 foreach (FieldValueViewModel field in groupFields) 498 { 499 if (field.SystemName == "ProductGroupNavigationImage") 500 { 501 if (!string.IsNullOrEmpty(field.Value.ToString())) 502 { 503 string productGroupImageShape = Model.Parameters["ProductGroupImageShape"] != null ? Model.Parameters["ProductGroupImageShape"].ToString() : string.Empty; 504 string productGroupImageSize = Model.Parameters["ProductGroupImageSize"] != null ? Model.Parameters["ProductGroupImageSize"].ToString() : string.Empty; 505 string ratio = productGroupImageSize.Contains("%") ? Model.Parameters["ProductGroupImageSize"].ToString() : string.Empty; 506 string ratioCssClass = ratio != string.Empty ? "ratio" : string.Empty; 507 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : string.Empty; 508 var groupImage = field.Value.ToString(); 509 var groupName = group.Name; 510 511 if (Path.GetExtension(groupImage).ToLower() == ".svg") 512 { 513 if (!string.IsNullOrEmpty(ratio)) 514 { 515 <div class="@(ratioCssClass)" style="@ratioVariable"> 516 @ReadFile("/Files/Images/" + groupImage) 517 </div> 518 } 519 else 520 { 521 <div class="icon-auto" style="height: @(productGroupImageSize)px; width: @(productGroupImageSize)px;"> 522 @ReadFile("/Files/Images/" + groupImage) 523 </div> 524 } 525 526 } 527 else 528 { 529 if (!string.IsNullOrEmpty(ratio)) 530 { 531 var imagePath = Dynamicweb.Context.Current.Server.UrlEncode("/Files/Images/" + groupImage); 532 var imageSrc = $"/Admin/Public/GetImage.ashx?Image={imagePath}&Width=320"; 533 534 <figure class="@(ratioCssClass) m-0" style="@ratioVariable"> 535 <img loading="lazy" class="@productGroupImageShape" alt="@groupName" src="@imageSrc" style="object-fit: contain"> 536 </figure> 537 538 } 539 else 540 { 541 var imagePath = Dynamicweb.Context.Current.Server.UrlEncode("/Files/Images/" + groupImage); 542 var imageSrc = $"/Admin/Public/GetImage.ashx?Image={imagePath}&Width={productGroupImageSize}&Height={productGroupImageSize}&crop=0"; 543 544 <img loading="lazy" class="@productGroupImageShape" alt="@groupName" width="@productGroupImageSize" height="@productGroupImageSize" src="@imageSrc"> 545 } 546 } 547 } 548 } 549 } 550 } 551 } 552