Smøreudstyr
Vi forhandler manuelle, pneumatiske og elektriske fedtpressere (Lincoln PowerLuber) og flere forskellige fedtpumper til dit behov.
Her finder du også et udvalg af ekstra udstyr til Lincoln PowerLuber.
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&crop=5&DoNotUpscale=True&Compression=75&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