Vagttelefon: +45 70 24 45 18

Kundeservice: +45 70 20 04 11

Masytec A/S

Fittings

Masytec A/S forhandler et bredt udvalg i Lynfittings, Skæreringsfittings, Skotforskruninger, Vinkelforskruninger og Nippelmuffer. 

Mange forskellige varianter og størrelser. 

Error executing template "Designs/Swift-v2/Paragraph/Swift-v2_ProductGroupGrid.cshtml"
System.MissingMethodException: Method not found: 'System.Collections.Generic.IEnumerable`1<Dynamicweb.Ecommerce.Products.Group> Custom.Relewise.Services.ProductGroupRecommendationService.GetProductCategoryRecommendations(System.String, Int32, System.String, System.String, Int32, Int32, Double, Double, Double)'.
   at CompiledRazorTemplates.Dynamic.RazorEngine_e921f94e205647e1ac2fa96c03b61df6.GetGroups(String type)
   at CompiledRazorTemplates.Dynamic.RazorEngine_e921f94e205647e1ac2fa96c03b61df6.GetGroups(String type)
   at CompiledRazorTemplates.Dynamic.RazorEngine_e921f94e205647e1ac2fa96c03b61df6.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   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.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Frontend 5 6 @functions 7 { 8 private IList<ProductGroupViewModel> GetGroups(string type) 9 { 10 IList<ProductGroupViewModel> groupList = new List<ProductGroupViewModel> { }; 11 12 if (type == "subgroups") 13 { 14 IList<ProductGroupViewModel> groups = Model.Item.GetValue<IList<ProductGroupViewModel>>("Subgroups"); 15 if (groups != null) 16 { 17 foreach (var group in groups) 18 { 19 var subGroups = Services.ProductGroups.GetSubgroups(Services.ProductGroups.GetGroup(group.Id)); 20 21 foreach (var subGroup in subGroups) 22 { 23 var subGroupViewModel = ViewModelFactory.CreateView(new ProductGroupViewModelSettings(), subGroup); 24 groupList.Add(subGroupViewModel); 25 } 26 } 27 } 28 } 29 30 if (type == "selected-groups") 31 { 32 IList<ProductGroupViewModel> groups = Model.Item.GetValue<IList<ProductGroupViewModel>>("SelectedGroups"); 33 if (groups != null) 34 { 35 foreach (var group in groups) 36 { 37 groupList.Add(group); 38 } 39 } 40 } 41 42 if (type == "subgroups-current") 43 { 44 var currentGroupId = Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"); 45 46 //Custom: Only render groupgrid if productlist is not rendered as groups 47 @if (!string.IsNullOrEmpty(currentGroupId)) 48 { 49 string? searchQuery = Dynamicweb.Context.Current?.Request["q"]; 50 Custom.AVN.Facets.Helpers.ProductGroupHelper.RenderLayouts pageRenderLayout = Custom.AVN.Facets.Helpers.ProductGroupHelper.PageContainerRenderLayout(currentGroupId, Dynamicweb.Ecommerce.Common.Context.LanguageID, !string.IsNullOrEmpty(searchQuery)); 51 @if (pageRenderLayout != Custom.AVN.Facets.Helpers.ProductGroupHelper.RenderLayouts.GroupList) 52 { 53 var currentGroup = Services.ProductGroups.GetGroup(currentGroupId, Dynamicweb.Ecommerce.Common.Context.LanguageID); 54 var groups = currentGroup != null ? Services.ProductGroups.GetSubgroups(currentGroup) : null; 55 if (groups != null) 56 { 57 foreach (var group in groups) 58 { 59 var groupViewModel = ViewModelFactory.CreateView(new ProductGroupViewModelSettings(), group); 60 groupList.Add(groupViewModel); 61 } 62 } 63 } 64 } 65 66 } 67 68 if (type == "relewise") 69 { 70 string recommendationEndpoint = Model.Item.GetRawValueString("CustomRelewiseRecommendationEndpoint"); 71 Custom.Relewise.Services.ProductGroupRecommendationService productGroupRecommendationService = new(); 72 73 foreach (var group in productGroupRecommendationService.GetProductCategoryRecommendations(recommendationEndpoint, PageView.Current().ID, "", "", 8)) 74 { 75 var groupViewModel = ViewModelFactory.CreateView(new ProductGroupViewModelSettings(), group); 76 groupList.Add(groupViewModel); 77 } 78 } 79 80 return groupList; 81 } 82 83 private LinkViewModel GetLink(ProductGroupViewModel group) 84 { 85 string groupId = Dynamicweb.Context.Current.Server.UrlEncode(group.Id); 86 var url = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={groupId.Trim()}"; 87 //Custom keep filtration when selecting new group and filters available 88 var keepFiltration = Model.Item.GetBoolean("CustomKeepFiltration"); 89 90 if (keepFiltration) 91 { 92 var excludedParameters = !string.IsNullOrEmpty(Model.Item.GetList("CustomExcludedParameters")?.ToString()) ? Model.Item.GetList("CustomExcludedParameters")?.ToString() : ""; 93 94 var requestQueryString = Dynamicweb.Context.Current?.Request.QueryString; 95 96 if (requestQueryString != null && requestQueryString.HasKeys()) 97 { 98 foreach (var key in requestQueryString.Keys) 99 { 100 var keyStr = key.ToString(); 101 if (Custom.AVN.Facets.Helpers.QueryStringHelper.AlwaysExcludedParameters.Contains(keyStr) || excludedParameters.Contains(keyStr, StringComparison.InvariantCultureIgnoreCase)) continue; 102 103 url += $"&{keyStr}={requestQueryString.Get(keyStr)}"; 104 } 105 } 106 } 107 108 var link = new LinkViewModel() 109 { 110 Url = url, 111 IsExternal = false 112 }; 113 114 return link; 115 } 116 117 private string GetGroupImageMarkup(ProductGroupViewModel group, string imageShape) 118 { 119 string groupImage = Services.ProductGroups.GetGroup(group.Id)?.LargeImage; 120 if (groupImage.StartsWith("/") && !groupImage.StartsWith("/Files", StringComparison.OrdinalIgnoreCase)) 121 { 122 groupImage = $"/Files{groupImage}"; 123 } 124 125 126 string groupImageEncoded = Dynamicweb.Context.Current.Server.UrlEncode(groupImage); 127 string groupImagePath = $"/Admin/Public/GetImage.ashx?width=640&crop=0&image={groupImageEncoded}&format=webp"; 128 //Custom image fill 129 string imageFill = Model.Item.GetRawValueString("CustomImageFill", "contain"); 130 string groupImageMarkup = $"<img class=\"{imageShape}\" src=\"{groupImagePath}\" alt=\"{group.Name}\" style=\"object-fit:{imageFill}\">"; 131 132 return !string.IsNullOrEmpty(groupImage) ? groupImageMarkup : string.Empty; 133 } 134 135 private string GetImageShape() 136 { 137 string imageShape = Model.Item.GetRawValueString("ImageShape", "boxed"); 138 switch (imageShape) 139 { 140 case "boxed": 141 imageShape = "rounded-0"; 142 break; 143 case "rounded": 144 imageShape = "rounded-3"; 145 break; 146 case "circle": 147 imageShape = "rounded-pill"; 148 break; 149 } 150 return imageShape; 151 } 152 153 private string GetButtonAlignment() 154 { 155 string buttonAlignment = Model.Item.GetRawValueString("ButtonAlignment", "align-center-center"); 156 157 switch (buttonAlignment) 158 { 159 case "align-center-center": 160 return "text-center justify-content-center align-items-center"; 161 case "align-bottom-start": 162 return "text-start justify-content-start align-items-end"; 163 case "align-bottom-center": 164 return "text-center justify-content-center align-items-end"; 165 case "align-bottom-center-text-center": 166 return "text-center justify-content-center align-items-end"; 167 case "align-bottom-end": 168 return "text-end justify-content-end align-items-end"; 169 default: 170 return "align-center-center"; 171 } 172 } 173 174 private bool DisplayGroup(FacetViewModel facet, string groupId) { 175 if (facet == null || facet.OptionActiveCount == 2048) //2048 max facet count 176 return true; 177 178 return facet.Options.Any(o => o.Value == groupId && o.Count > 0); 179 } 180 } 181 182 @{ 183 ProductListViewModel productList = new ProductListViewModel(); 184 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 185 { 186 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 187 } 188 189 var customLimitGroupListFacet = productList.FacetGroups?.FirstOrDefault(g => g.Facets.Any(f => f.RenderType == "HideGroups"))?.Facets.FirstOrDefault(f => f.RenderType == "HideGroups"); 190 191 192 string groupType = Model.Item.GetRawValueString("GroupType", "subgroups"); 193 194 @* Custom code: Filter on ShowInMenu to hide EcomGroups where this setting is disabled *@ 195 var groups = GetGroups(groupType).Where(g => g.ShowInMenu).ToList(); 196 197 bool hideHeaders = (Model.Item?.GetBoolean("HideHeaders") ?? false); 198 string title = Model.Item?.GetString("Title", string.Empty); 199 string subtitle = Model.Item?.GetString("Subtitle", string.Empty); 200 bool groupsExist = groups is object && groups.Count != 0; 201 202 // Grid layout 203 string gridSize = Model.Item.GetRawValueString("GridSize", "3"); 204 string gridSizeMobile = Model.Item.GetRawValueString("GridSizeMobile", "1"); 205 gridSize = $"grid-{gridSizeMobile} grid-sm-3 grid-lg-{gridSize}"; 206 207 string itemsGap = $"gap-{Model.Item.GetRawValueString("GridItemsGap", "3")}"; 208 string layout = Model.Item.GetRawValueString("Layout", "overlay"); 209 210 // Styling 211 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", string.Empty); 212 ratio = ratio != "0" ? ratio : string.Empty; 213 string ratioCssClass = ratio != string.Empty ? "ratio" : string.Empty; 214 string ratioVariable = ratio != string.Empty ? "--bs-aspect-ratio: " + ratio : string.Empty; 215 216 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 217 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 218 string maxWidth = Model.Item.GetRawValueString("TextReadability", string.Empty); 219 maxWidth = maxWidth == "max-width-on" ? "mw-75ch" : string.Empty; 220 221 string buttonAlignment = GetButtonAlignment(); 222 223 string buttonStyle = Model.Item.GetRawValueString("ButtonStyle", "primary"); 224 225 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 226 buttonSize = buttonSize == "small" ? "btn btn-sm" : buttonSize; 227 buttonSize = buttonSize == "regular" ? "btn" : buttonSize; 228 buttonSize = buttonSize == "large" ? "btn btn-lg" : buttonSize; 229 230 string stretchedLink = "stretched-link"; 231 232 string imageShape = GetImageShape(); 233 string missingImageMarkup = $"<div class=\"bg-opacity-10 {imageShape}\" style=\"background-color:rgba(var(--swift-foreground-color-rgb),var(--bs-bg-opacity));\"></div>"; 234 } 235 236 @if (groupsExist) 237 { 238 <div class="grid gap-0 item_@(Model.Item.SystemName.ToLower())"> 239 @if (!hideHeaders) 240 { 241 <div class="g-col-12 pb-2 pb-lg-4"> 242 <div class="mb-0-last-child"> 243 @if (!string.IsNullOrEmpty(title)) 244 { 245 <h2 class="mt-0 @titleFontSize @maxWidth">@title</h2> 246 } 247 248 @if (!string.IsNullOrEmpty(subtitle)) 249 { 250 <p class="@subtitleFontSize @maxWidth">@subtitle</p> 251 } 252 </div> 253 </div> 254 } 255 256 <div class="g-col-12 grid @gridSize @itemsGap"> 257 @foreach (var group in groups.Where(g => DisplayGroup(customLimitGroupListFacet, g.Id))) 258 { 259 string groupImageMarkup = GetGroupImageMarkup(group, imageShape) ?? missingImageMarkup; 260 bool groupImage = !string.IsNullOrEmpty(groupImageMarkup); 261 262 <div class="d-flex flex-column h-100"> 263 @{ 264 switch (layout) 265 { 266 case "overlay": 267 <div class="card rounded-0 border-0 @(ratioCssClass)" style="@ratioVariable"> 268 269 @(groupImage ? groupImageMarkup : missingImageMarkup) 270 271 <div class="d-grid p-3 @buttonAlignment"> 272 @if (GetLink(group) is object) 273 { 274 bool openLinksInNewTab = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && GetLink(group).IsExternal; 275 string target = openLinksInNewTab ? "target=\"_blank\"" : string.Empty; 276 string rel = openLinksInNewTab ? "rel=\"noopener\"" : string.Empty; 277 278 <a href="@GetLink(group)" class="@(buttonSize) btn-@buttonStyle @(stretchedLink)" data-dw-button="@buttonStyle" @target @rel>@group.Name</a> 279 } 280 </div> 281 </div> 282 break; 283 case "below": 284 <div class="card rounded-0 border-0 gap-3"> 285 286 <div class="@(ratioCssClass)" style="@ratioVariable"> 287 288 @(groupImage ? groupImageMarkup : missingImageMarkup) 289 290 </div> 291 292 <div class="@(groupImage ? "h-100" : string.Empty) d-grid @buttonAlignment"> 293 294 @if (GetLink(group) is object) 295 { 296 bool openLinksInNewTab = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && GetLink(group).IsExternal; 297 string target = openLinksInNewTab ? "target=\"_blank\"" : string.Empty; 298 string rel = openLinksInNewTab ? "rel=\"noopener\"" : string.Empty; 299 300 <a href="@GetLink(group)" class="@(buttonSize) btn-@buttonStyle @(stretchedLink)" data-dw-button="@buttonStyle" @target @rel>@group.Name</a> 301 } 302 </div> 303 </div> 304 break; 305 } 306 } 307 </div> 308 } 309 </div> 310 </div> 311 } 312 else if (Pageview.IsVisualEditorMode) 313 { 314 <div class="alert alert-dark" role="alert"> 315 <span>@Translate("Group grid"): @Translate("Edit this column to configure")</span> 316 </div> 317 } 318
Error executing template "Designs/Swift-v2/Paragraph/Swift-v2_ProductListFacets.cshtml"
Dynamicweb.Extensibility.Dependencies.DependencyResolverException: The Dependency Locator was not initialized properly.
   at Dynamicweb.Extensibility.Dependencies.DependencyResolver.GetCurrent()
   at Dynamicweb.Ecommerce.Products.GroupService.GetGroup(String groupId, String languageId)
   at Custom.AVN.Facets.Helpers.ProductGroupHelper.GroupHasSubGroups(String groupId, String languageId)
   at Custom.AVN.Facets.Helpers.ProductGroupHelper.PageContainerRenderLayout(String groupId, String languageId, Boolean isSearchOrFavoriteList)
   at CompiledRazorTemplates.Dynamic.RazorEngine_de9a327bd834422380fdd669ee06450f.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   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.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Frontend.Navigation 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Core.Encoders 6 @using System.Text.RegularExpressions 7 8 @{ 9 ProductListViewModel productList = new ProductListViewModel(); 10 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 11 { 12 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 13 } 14 15 string url = Pageview.SearchFriendlyUrl; 16 url = url.LastIndexOf("?") != -1 ? url.Substring(0, url.LastIndexOf("?")) : url; 17 18 //Fix for non-friendly urls 19 if (Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") != null) 20 { 21 string groupId = Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"); 22 url += "?GroupID=" + groupId; 23 } 24 25 if (!url.Contains("LayoutTemplate")) 26 { 27 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift-v2/Swift-v2_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift-v2/Swift-v2_PageClean.cshtml"; 28 } 29 30 bool facetsFound = false; 31 int selectedFacetsCount = 0; 32 33 if (productList.FacetGroups != null) 34 { 35 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 36 { 37 foreach (FacetViewModel facet in facetGroup.Facets) 38 { 39 if (facet.Options.Count() > 0) 40 { 41 facetsFound = true; 42 43 foreach (FacetOptionViewModel option in facet.Options) 44 { 45 if (option.Selected) 46 { 47 selectedFacetsCount++; 48 } 49 } 50 } 51 } 52 } 53 } 54 55 bool enableSorting = Model.Item.GetBoolean("SortByNameAZ"); 56 enableSorting = Model.Item.GetBoolean("SortByNameZA") || enableSorting == true ? true : false; 57 enableSorting = Model.Item.GetBoolean("SortByNewest") || enableSorting == true ? true : false; 58 enableSorting = Model.Item.GetBoolean("SortByLowestPrice") || enableSorting == true ? true : false; 59 enableSorting = Model.Item.GetBoolean("SortByHighestPrice") || enableSorting == true ? true : false; 60 61 string layout = Model.Item.GetRawValueString("Layout", "vertical"); 62 63 var formFieldsParms = new Dictionary<string, object>(); 64 formFieldsParms.Add("DeviceType", "desktop"); 65 66 string? searchQuery = Dynamicweb.Context.Current?.Request["q"]; 67 var currentGroupId = Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"); 68 var pageRenderLayout = Custom.AVN.Facets.Helpers.ProductGroupHelper.PageContainerRenderLayout(currentGroupId, Dynamicweb.Ecommerce.Common.Context.LanguageID, !string.IsNullOrEmpty(searchQuery)); 69 } 70 71 @if (productList.TotalProductsCount > 0 && (facetsFound || Model.Item.GetBoolean("EnableGroupNavigation") || enableSorting) && pageRenderLayout != Custom.AVN.Facets.Helpers.ProductGroupHelper.RenderLayouts.NotSet) 72 { 73 string iconPath = "/Files/Images/Icons/"; 74 string selectedFacetsLabel = selectedFacetsCount > 0 ? "(" + selectedFacetsCount + ")" : string.Empty; 75 string formContainerCss = layout == "horizontal" ? $"d-lg-flex gap-3 flex-row flex-wrap" : $"d-lg-block h-100"; 76 77 //Desktop 78 if (layout == "horizontal") 79 { 80 @:<div class="h-100" data-dw-colorscheme="@Model.ColorScheme?.Id"> 81 } 82 83 <form method="post" action="@url" data-response-target-element="content" id="FacetsForm_Desktop_@Model.ID" class="d-none @formContainerCss item_@Model.Item.SystemName.ToLower()" data-dw-colorscheme="@Model.ColorScheme?.Id"> 84 @RenderPartial("Paragraph/ProductListFacets/FormFields.cshtml", Model, formFieldsParms) 85 @if (layout == "horizontal" && selectedFacetsCount > 0) 86 { 87 <button type="button" class="btn btn-sm me-sm-1 me-lg-2" onclick="swift.ProductList.ResetFacets(event)"><span class="icon-2">@ReadFile(iconPath + "rotate-ccw.svg")</span> @Translate("Clear filters")</button> 88 } 89 </form> 90 91 if (layout == "horizontal") 92 { 93 @:</div> 94 } 95 96 //Mobile 97 <div class="d-block d-lg-none mt-lg-0 FacetsForm_Mobile_@Model.Item.SystemName.ToLower()_@Model.ID" data-dw-colorscheme="@Model.ColorScheme?.Id"> 98 <button type="button" class="btn btn-primary w-100" data-dw-button="primary" data-bs-toggle="modal" data-bs-target="#FacetsModal"> 99 <span class="d-flex align-items-center"> 100 <span class="flex-grow-1 text-start"> 101 @Translate("Filter") @selectedFacetsLabel 102 </span> 103 <span class="icon-2"> 104 @ReadFile(iconPath + "sliders.svg") 105 </span> 106 </span> 107 </button> 108 109 <form method="post" action="@url" data-response-target-element="content" class="modal" id="FacetsModal" tabindex="-1" aria-hidden="false"> 110 <div class="modal-dialog modal-fullscreen"> 111 <div class="modal-content"> 112 <div class="modal-header"> 113 <h5 class="modal-title">@Translate("Filters and sorting")</h5> 114 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.querySelector('body').style = ''"></button> 115 </div> 116 <div class="modal-body"> 117 @{ 118 formFieldsParms["DeviceType"] = "mobile"; 119 } 120 @RenderPartial("Paragraph/ProductListFacets/FormFields.cshtml", Model, formFieldsParms) 121 </div> 122 <div class="modal-footer d-flex"> 123 @if (selectedFacetsCount != 0) 124 { 125 <button type="button" class="btn btn-secondary flex-fill" data-dw-button="secondary" onclick="swift.ProductList.ResetFacets(event)">@Translate("Clear") (@selectedFacetsCount)</button> 126 } 127 <button type="button" class="btn btn-primary flex-fill" data-dw-button="primary" onclick="location.reload();">@Translate("Update")</button> 128 </div> 129 </div> 130 </div> 131 </form> 132 </div> 133 @*Custom facetoption display logic*@ 134 <script> 135 document.addEventListener("DOMContentLoaded", () => { 136 swift.Facets.InitFacets(); 137 }); 138 139 document.addEventListener("afterSwap.swift.productlist", () => { 140 swift.Facets.InitFacets(); 141 }); 142 </script> 143 } 144 else if (Pageview.IsVisualEditorMode) 145 { 146 <div class="alert alert-dark m-0" role="alert"> 147 <span>@Translate("Facets: The facets selectors will be shown here, if any")</span> 148 </div> 149 } 150
Error executing template "Designs/Swift-v2/Paragraph/Swift-v2_ProductListItemRepeater.cshtml"
System.MissingMethodException: Method not found: 'System.Collections.Generic.List`1<Custom.Tracking.Ga4EcommerceItem> Custom.Tracking.Ga4EcommerceTracking.CreateProductItems(System.Collections.Generic.IEnumerable`1<Dynamicweb.Ecommerce.ProductCatalog.ProductViewModel>, System.String, System.String, System.String, System.String)'.
   at CompiledRazorTemplates.Dynamic.RazorEngine_e188a1be6424490598e590186192e6c1.ExecuteAsync()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e188a1be6424490598e590186192e6c1.ExecuteAsync()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e188a1be6424490598e590186192e6c1.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   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.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Core 4 @using Dynamicweb.Core.Encoders 5 @using Dynamicweb.Frontend 6 @using Custom.Tracking 7 8 @{ 9 int productsCount = 0; 10 int maxProductsCounter = 0; 11 12 ProductListViewModel? productList = null; 13 if (Dynamicweb.Context.Current is not null && Dynamicweb.Context.Current.Items.Contains("ProductList")) 14 { 15 productList = (ProductListViewModel?)Dynamicweb.Context.Current.Items["ProductList"]; 16 } 17 else if (Pageview.Page?.Item?["DummyProductGroup"] != null && Pageview.IsVisualEditorMode) 18 { 19 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 20 ProductListViewModel? groupList = pageViewModel.Item?.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 21 22 if (groupList?.Products is object) 23 { 24 productList = groupList; 25 } 26 } 27 } 28 29 @*Custom functions*@ 30 @functions { 31 private LinkViewModel GetLink(Dynamicweb.Ecommerce.Products.Group group) 32 { 33 var url = $"/Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={group.Id.Trim()}"; 34 35 //Custom keep filtration when selecting new group and filters available 36 var keepFiltration = Model.Item.GetBoolean("CustomKeepFiltration"); 37 38 if (keepFiltration) 39 { 40 var excludedParameters = !string.IsNullOrEmpty(Model.Item.GetList("CustomExcludedParameters")?.ToString()) ? Model.Item.GetList("CustomExcludedParameters")?.ToString() : ""; 41 42 var requestQueryString = Dynamicweb.Context.Current?.Request.QueryString; 43 44 if (requestQueryString != null && requestQueryString.HasKeys()) 45 { 46 foreach (var key in requestQueryString.Keys) 47 { 48 var keyStr = key.ToString(); 49 if (Custom.AVN.Facets.Helpers.QueryStringHelper.AlwaysExcludedParameters.Contains(keyStr) || excludedParameters.Contains(keyStr, StringComparison.InvariantCultureIgnoreCase)) continue; 50 51 url += $"&{keyStr}={requestQueryString.Get(keyStr)}"; 52 } 53 } 54 } 55 var link = new LinkViewModel() 56 { 57 Url = url, 58 IsExternal = false 59 }; 60 61 return link; 62 } 63 64 private int GetGroupProductsCount(string groupId, ProductListViewModel productList) 65 { 66 int count = 0; 67 68 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 69 { 70 foreach (FacetViewModel facet in facetGroup.Facets) 71 { 72 if (facet.Options.Count() > 0) 73 { 74 75 foreach (FacetOptionViewModel option in facet.Options.Where(p => p.Value == groupId)) 76 { 77 count += Converter.ToInt32(option.Count); 78 } 79 } 80 } 81 } 82 83 return count; 84 } 85 } 86 87 @if (productList is not null) 88 { 89 <div class="h-100 product-list" data-dw-colorscheme="@Model.ColorScheme?.Id"> 90 @{ 91 bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current?.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false; 92 93 string groupId = productList?.Group?.Id != null ? productList.Group.Id : ""; 94 95 if (productList?.TotalProductsCount > 0) 96 { 97 int pageSizeSetting = Converter.ToInt32(Dynamicweb.Context.Current?.Request.QueryString.Get("OriginalPageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("OriginalPageSize")) : productList.PageSize; 98 int pageNumber = Converter.ToInt32(Dynamicweb.Context.Current?.Request.QueryString.Get("PageNum")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageNum")) : productList.CurrentPage; 99 int pageSize = Converter.ToInt32(Dynamicweb.Context.Current?.Request.QueryString.Get("PageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) : productList.PageSize; 100 pageNumber = pageSize != pageSizeSetting ? (pageSize / pageSizeSetting) : pageNumber; 101 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : pageSizeSetting * pageNumber; 102 loadedProducts = loadedProducts > productList.TotalProductsCount ? productList.TotalProductsCount : loadedProducts; 103 104 pageNumber += 1; 105 106 string? searchQuery = Dynamicweb.Context.Current?.Request["q"]; 107 108 string? searchLayout = Dynamicweb.Context.Current?.Request.QueryString.Get("SearchLayout"); 109 110 @*Custom render group list if rendertype is GroupList*@ 111 var pageRenderLayout = Custom.AVN.Facets.Helpers.ProductGroupHelper.PageContainerRenderLayout(groupId, Dynamicweb.Ecommerce.Common.Context.LanguageID, !string.IsNullOrEmpty(searchQuery)); 112 @if (pageRenderLayout == Custom.AVN.Facets.Helpers.ProductGroupHelper.RenderLayouts.GroupList) 113 { 114 var subGroups = Dynamicweb.Ecommerce.Services.ProductGroups.GetSubgroups(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(groupId)); 115 @if (subGroups.Any()) 116 { 117 <div class="group-list"> 118 @foreach (var group in subGroups) 119 { 120 var count = GetGroupProductsCount(group.Id, productList); 121 if (count > 0) 122 { 123 var link = GetLink(group); 124 125 <div class="grid g-col-12 mb-3 gap-0"> 126 <div class="g-col-2 group-list__list-item__left-wrapper"> 127 <a href="@link" title=""> 128 <img class="object-fit-contain w-100" src="/Admin/Public/GetImage.ashx?width=680&height=314&amp;crop=5&amp;DoNotUpscale=True&amp;Compression=75&amp;image=@group.LargeImage" alt="@HtmlEncoder.HtmlAttributeEncode(group.Name)" /> 129 </a> 130 </div> 131 <div class="g-col-7 group-list__list-item__middle-wrapper dw-mod"> 132 <a class="text-decoration-none" href="@link" title="@HtmlEncoder.HtmlAttributeEncode(group.Name)"> 133 <h5>@group.Name</h5> 134 <p>@group.Description</p> 135 </a> 136 </div> 137 <div class="g-col-3 group-list__list-item__right-wrapper dw-mod"> 138 <a href="@link" class="btn btn-primary" data-swift-btn="primary" title="">@string.Format(Translate("Custom:ViewList.ListViewItem.GroupList.ShowProducts.", "Vis {0} produkter"), count)</a> 139 </div> 140 </div> 141 } 142 } 143 </div> 144 } 145 } 146 else if (pageRenderLayout == Custom.AVN.Facets.Helpers.ProductGroupHelper.RenderLayouts.ProductList) 147 { 148 int itemSourcePageId = Convert.ToInt32(Model.Item?.GetRawValueString("ListComponentSource", "0")); 149 itemSourcePageId = Dynamicweb.Content.Services.Pages.GetPageOrLanguage(itemSourcePageId, Pageview.AreaID)?.ID ?? itemSourcePageId; 150 151 var page = Dynamicweb.Content.Services.Pages.GetPage(itemSourcePageId); 152 153 if (page != null) 154 { 155 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page); 156 const string trackingItemListId = "product_list_item_repeater"; 157 const string trackingItemListName = "Product list (Item Repeater)"; 158 string trackingAffiliation = Pageview.Area?.Name; 159 string trackingCurrency = productList.Products.FirstOrDefault()?.Price?.CurrencyCode ?? string.Empty; 160 var trackingItems = Ga4EcommerceTracking.CreateProductItems( 161 productList.Products, 162 trackingAffiliation, 163 trackingItemListId, 164 trackingItemListName); 165 string viewItemListPayload = Ga4EcommerceTracking.EncodePayload(new 166 { 167 currency = trackingCurrency, 168 item_list_id = trackingItemListId, 169 item_list_name = trackingItemListName, 170 items = trackingItems 171 }); 172 173 string? gridColumnSize = Model.Item?.GetRawValueString("GridLayoutDesktop", "3-columns"); 174 gridColumnSize = gridColumnSize == "2-columns" ? "g-col-lg-6" : gridColumnSize; 175 gridColumnSize = gridColumnSize == "3-columns" ? "g-col-lg-4" : gridColumnSize; 176 gridColumnSize = gridColumnSize == "4-columns" ? "g-col-lg-3" : gridColumnSize; 177 gridColumnSize = gridColumnSize == "6-columns" ? "g-col-lg-2" : gridColumnSize; 178 gridColumnSize = gridColumnSize == "list" ? "g-col-lg-12" : gridColumnSize; 179 180 string? gridColumnMobileSize = Model.Item?.GetRawValueString("GridLayoutMobile", "2-columns"); 181 gridColumnMobileSize = gridColumnMobileSize == "list" ? "g-col-12" : gridColumnMobileSize; 182 gridColumnMobileSize = gridColumnMobileSize == "2-columns" ? "g-col-6" : gridColumnMobileSize; 183 184 <div class="grid pb-3"> 185 <script> 186 window.avnTracking.pushEncodedEcommerceEvent( 187 "view_item_list", 188 "@viewItemListPayload" 189 ); 190 </script> 191 192 @foreach (ProductViewModel product in productList.Products) 193 { 194 if (maxProductsCounter == 0 || (productsCount < maxProductsCounter)) 195 { 196 string link = string.Empty; 197 var currentGroupID = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : string.Empty; 198 199 if (product.Groups.Any(g => g.Id.Equals(currentGroupID, StringComparison.InvariantCultureIgnoreCase))) 200 { 201 link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"), false); 202 } 203 else if (product.PrimaryOrDefaultGroup != null && product.Groups.Any(g => g.Id.Equals(product.PrimaryOrDefaultGroup.Id, StringComparison.InvariantCultureIgnoreCase))) { 204 link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), product.PrimaryOrDefaultGroup.Id, false); 205 } 206 else 207 { 208 link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 209 } 210 211 var keepFiltration = Model.Item.GetBoolean("CustomKeepFiltration"); 212 213 if (keepFiltration) 214 { 215 var excludedParameters = !string.IsNullOrEmpty(Model.Item.GetList("CustomExcludedParameters")?.ToString()) ? Model.Item.GetList("CustomExcludedParameters")?.ToString() : ""; 216 217 var requestQueryString = Dynamicweb.Context.Current?.Request.QueryString; 218 219 if (requestQueryString != null && requestQueryString.HasKeys()) 220 { 221 foreach (var key in requestQueryString.Keys) 222 { 223 var keyStr = key.ToString(); 224 if (Custom.AVN.Facets.Helpers.QueryStringHelper.AlwaysExcludedParameters.Contains(keyStr) || excludedParameters.Contains(keyStr, StringComparison.InvariantCultureIgnoreCase)) continue; 225 226 link += $"&{keyStr}={requestQueryString.Get(keyStr)}"; 227 } 228 } 229 } 230 231 if (Dynamicweb.Context.Current?.Items.Contains("ProductDetails") != null) 232 { 233 Dynamicweb.Context.Current.Items["ProductDetails"] = product; 234 } 235 else 236 { 237 Dynamicweb.Context.Current?.Items.Add("ProductDetails", product); 238 } 239 240 if (Model.Item?.GetString("ListComponentSource") != null) 241 { 242 var selectItem = Ga4EcommerceTracking.CreateProductItem( 243 product, 244 trackingAffiliation, 245 trackingItemListId, 246 trackingItemListName, 247 productsCount); 248 string selectItemPayload = Ga4EcommerceTracking.EncodePayload(new 249 { 250 currency = product.Price.CurrencyCode, 251 item_list_id = trackingItemListId, 252 item_list_name = trackingItemListName, 253 items = new[] { selectItem } 254 }); 255 256 <article class="@gridColumnMobileSize @gridColumnSize d-flex flex-column position-relative product js-product" data-product-id="@product.Id" data-variant-id="@product.VariantId" itemscope itemtype="https://schema.org/Product"> 257 <a href="@link" 258 class="stretched-link" 259 data-ga4-ecommerce="@HtmlEncoder.HtmlAttributeEncode(selectItemPayload)" 260 onclick="window.avnTracking.pushEncodedEcommerceEvent('select_item', this.dataset.ga4Ecommerce)" 261 onmouseover="swift.Image.swapImage(event)" 262 onmouseout="swift.Image.swapImage(event)"> 263 <span class="visually-hidden">@product.Name</span> 264 </a> 265 266 @RenderGrid(itemSourcePageId) 267 </article> 268 } 269 270 productsCount++; 271 } 272 } 273 </div> 274 275 <div class="my-3" id="ProductListLoadMore"> 276 <div class="text-center"> 277 <div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div> 278 @if (productList.PageCount != 1 && maxProductsCounter == 0 && loadedProducts < productList.TotalProductsCount) 279 { 280 string? sortBySelection = Dynamicweb.Context.Current?.Request.Form["SortBy"] ?? ""; 281 sortBySelection = Dynamicweb.Context.Current?.Request.QueryString.Get("SortBy") ?? sortBySelection; 282 string? mainProductId = Dynamicweb.Context.Current?.Request.QueryString.Get("MainProductID"); 283 284 <form method="get" data-response-target-element=".product-list" data-swap="afterend" class="w-100"> 285 @if (productList?.FacetGroups != null) 286 { 287 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 288 { 289 foreach (FacetViewModel facetItem in facetGroup.Facets) 290 { 291 foreach (FacetOptionViewModel facetOption in facetItem.Options) 292 { 293 if (facetOption.Selected) 294 { 295 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]"> 296 } 297 } 298 } 299 } 300 } 301 302 @if (!string.IsNullOrEmpty(searchQuery)) 303 { 304 <input type="hidden" name="q" value="@searchQuery"> 305 <input type="hidden" name="SearchLayout" value="@searchLayout"> 306 } 307 308 @if (!string.IsNullOrEmpty(mainProductId)) 309 { 310 <input type="hidden" name="MainProductID" value="@mainProductId"> 311 } 312 313 @if (productList?.Group?.Id != null) 314 { 315 <input type="hidden" name="GroupId" value="@groupId"> 316 } 317 318 <input type="hidden" name="OriginalPageSize" value="@pageSizeSetting"> 319 <input type="hidden" name="PageSize" value="@(loadedProducts + pageSizeSetting)"> 320 <input type="hidden" name="PageNum" value="@pageNumber"> 321 <input type="hidden" name="SortBy" value="@sortBySelection"> 322 <input type="hidden" name="RequestType" value="UpdateList"> 323 <input type="hidden" name="ParagraphID" value="@Model.ID"> 324 325 @if (productList?.FacetGroups is object) 326 { 327 string nextPageLink = $"/Default.aspx?ID={Model.PageID}&PageNum={pageNumber}&SortBy={sortBySelection}"; 328 329 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 330 { 331 foreach (FacetViewModel facetItem in facetGroup.Facets) 332 { 333 foreach (FacetOptionViewModel facetOption in facetItem.Options) 334 { 335 if (facetOption.Selected) 336 { 337 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]"; 338 } 339 } 340 } 341 } 342 343 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : ""; 344 345 <a href="@nextPageLink" class="btn btn-primary swift_load_more_button" data-dw-button="primary" onclick="swift.ProductList.Update(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a> 346 } 347 </form> 348 } 349 </div> 350 </div> 351 352 <script> 353 function switchVariantProduct(id, price, imagesrc) { 354 var productImageElement = document.querySelector("#ProductImage_" + id); 355 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price"); 356 357 if (productPriceElement) { 358 productPriceElement.innerText = price; 359 } 360 361 if (productImageElement) { 362 productImageElement.src = imagesrc; 363 364 var imageSrcset = productImageElement.srcset; 365 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&"); 366 367 productImageElement.srcset = imageSrcset; 368 } 369 } 370 </script> 371 } 372 else if (Pageview.IsVisualEditorMode) 373 { 374 <div class="alert alert-dark m-0" role="alert"> 375 <span>@Translate("The selected component does not exist anymore")</span> 376 </div> 377 } 378 379 } 380 } 381 else 382 { 383 string? noProductsFoundMessage = Model.Item?.GetString("NoProductsFoundMessage") ?? Translate("We did not find anything matching your search result"); 384 bool hasSubgroups = false; 385 386 if (productList?.SubGroups != null) 387 { 388 hasSubgroups = productList.SubGroups.Any(); 389 } 390 391 if (Model.Item is not null && !Model.Item.GetBoolean("HideNoProductsFoundMessage")) 392 { 393 if (!isVisualEditor) 394 { 395 <div class="alert alert-dark m-0" role="alert"> 396 @noProductsFoundMessage 397 </div> 398 } 399 else 400 { 401 <div class="alert alert-dark m-0" role="alert"> 402 @Translate("Product list: The list will be shown here, if any") 403 </div> 404 } 405 } 406 else if (!hasSubgroups) 407 { 408 <div class="alert alert-dark m-0" role="alert"> 409 @noProductsFoundMessage 410 </div> 411 } 412 } 413 } 414 </div> 415 } 416 else if (Pageview.IsVisualEditorMode) 417 { 418 <div class="alert alert-dark m-0" role="alert"> 419 <span>@Translate("Product list item repeater: The repeater paragraph will be shown here, if any products are available")</span> 420 </div> 421 } 422