Une proposition d'offre?
Souhaitez-vous un devis ?
Souhaitez-vous plus d’informations ou un devis pour ce produit ? Cliquez sur le bouton ci-dessous pour demander une soumission gratuite.
Kit de sélection d'aiguilles
Lire la suiteKit de sélection d'aiguilles
Error executing template "Designs/ClientBase_generated/Paragraph/ProductDetailWidgetRecentlyViewedProducts.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_7c6b14fe70454335963c6c84f74c6d7f.<>c__DisplayClass0_0.<renderProductBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Bluedesk\viba.cloud.dynamicweb-cms.com\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetRecentlyViewedProducts.cshtml:line 120 at CompiledRazorTemplates.Dynamic.RazorEngine_7c6b14fe70454335963c6c84f74c6d7f.Execute() in D:\dynamicweb.net\Solutions\Bluedesk\viba.cloud.dynamicweb-cms.com\files\Templates\Designs\ClientBase_generated\Paragraph\ProductDetailWidgetRecentlyViewedProducts.cshtml:line 71 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.ParagraphViewModel> 2 @using System.Globalization; 3 @using Dynamicweb.Caching; 4 @using Dynamicweb.Ecommerce.Prices; 5 @using Dynamicweb.Ecommerce.ProductCatalog; 6 @using Dynamicweb.Ecommerce.Products; 7 @using Dynamicweb.Ecommerce.Specialized.RelatedProductListProviders; 8 @using Dynamicweb.Ecommerce.Extensibility.Provider; 9 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 10 @using Bluedesk.DynamicWeb.ItemTypes.Settings.Configuration; 11 12 @{ 13 string paragraphID = Pageview.CurrentParagraph.ID.ToString(); 14 ProductDetailWidgetRecentlyViewedProducts _data = Dynamicweb.Services.Items.GetItem("ProductDetailWidgetRecentlyViewedProducts", Model.ItemId).ToCodeFirstItem<ProductDetailWidgetRecentlyViewedProducts>() ?? new ProductDetailWidgetRecentlyViewedProducts(); 15 16 ProductViewModel product = new ProductViewModel(); 17 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 18 { 19 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 20 } 21 22 ProductViewModelSettings productSetting = new ProductViewModelSettings 23 { 24 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 25 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 26 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 27 ShopId = Pageview.Area.EcomShopId 28 }; 29 30 var seenProductsFromSession = Dynamicweb.Context.Current.Session["YouHaveSeenTheseProductsList"]; 31 List<string> recentlyViewedProductIds = null; 32 List<ProductViewModel> recentProducts = new List<ProductViewModel>(); 33 34 if(seenProductsFromSession != null && !string.IsNullOrWhiteSpace(seenProductsFromSession.ToString())) 35 { 36 string productId = string.IsNullOrWhiteSpace(product.VariantId) ? product.Id : $"{product.Id};{product.VariantId}"; 37 recentlyViewedProductIds = ((string[])seenProductsFromSession).Where(id => id != productId).Take(4).ToList(); 38 foreach (string id in recentlyViewedProductIds) 39 { 40 string prodId = id; 41 string variantId = ""; 42 if(id.Contains(";")) 43 { 44 prodId = id.Split(';')[0]; 45 variantId = id.Split(';')[1]; 46 } 47 48 ProductViewModel prod = ViewModelFactory.CreateView(productSetting, prodId, variantId); 49 if(prod != null) 50 { 51 recentProducts.Add(prod); 52 } 53 } 54 } 55 var index = 1; 56 string ClassIgniteCarousel = recentProducts.Count() > 4 ? "products-module__container--carousel" : ""; 57 var groupTitle = Translate("Productdetail.RecentlyViewedArticles", "Recently viewed articles"); 58 } 59 60 @if(recentProducts.Any()) 61 { 62 <section id="@paragraphID" class="pdp-paragraph pdp-related-products-widget @_data.CssClass"> 63 <section class="products-module__container @ClassIgniteCarousel"> 64 <div class="container"> 65 <header class="products-module__header"> 66 <h2 class="products-module__title">@groupTitle</h2> 67 </header> 68 <ul class="products-module__slider"> 69 @foreach (ProductViewModel prod in recentProducts) 70 { 71 @renderProductBlock(prod, "recently_viewed_articles", groupTitle, index); 72 index++; 73 } 74 </ul> 75 </div> 76 </section> 77 </section> 78 } 79 80 @helper renderProductBlock(Dynamicweb.Ecommerce.ProductCatalog.ProductViewModel product, string listId, string listName, int index) 81 { 82 var master_configuration = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "MasterConfiguration"); 83 MasterConfig mc = master_configuration.Item.ToCodeFirstItem<MasterConfig>(); 84 EcomConfig EcommerceConfiguration = mc.EcomConfiguration; 85 86 string productName = product.Name; 87 88 var relProdService = new Dynamicweb.Ecommerce.Products.ProductService(); 89 var relProd = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Pageview.Area.EcomLanguageId); 90 string productImage = Dynamicweb.Ecommerce.Services.ProductImages.GetImagePath(relProd); 91 92 if (string.IsNullOrWhiteSpace(productImage)) 93 { 94 try 95 { 96 var perfionImage = relProdService.GetProductFieldValue(relProd, "AdditionalImages"); 97 productImage = $"Files/" + perfionImage.ToString().Split(';')[0]; 98 } 99 catch (Exception) { } 100 } 101102 bool WithVATBool = Pageview.Area.EcomPricesWithVat == "True"; 103 bool pricesWithoutVatForUsers = EcommerceConfiguration.ShowPricesWithoutVatForUsers; 104 bool pricesWithoutVatForValidVat = EcommerceConfiguration.ShowPricesWithoutVatWhenValidVatNumber; 105 if(pricesWithoutVatForUsers && !pricesWithoutVatForValidVat && Pageview.User != null) { 106 WithVATBool = false; 107 } 108 if(pricesWithoutVatForValidVat && Pageview.User != null && !string.IsNullOrWhiteSpace(Pageview.User.VatRegNumber)) { 109 WithVATBool = false; 110 } 111112 int productDetailPageId = GetPageIdByNavigationTag("ProductOverview"); 113 string currentPageUrl = "/Default.aspx?ID=" + Pageview.Page.ID; 114 string specifier = "G"; 115 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 116117 string productNumber = product.Number; 118 string productId = product.Id; 119 string productVariantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : ""; 120 string productURL = $"Default.aspx?ID={productDetailPageId}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 121 productURL += !string.IsNullOrWhiteSpace(product.VariantId) ? "&VariantID=" + product.VariantId : ""; 122 string productManufacturer = product.Manufacturer?.Name ?? ""; 123124 bool isPriceZero = product.Price.Price <= 0; 125 bool hasDiscount = product.Discount.Price > 0; 126 string OriginalPrice = WithVATBool ? product.PriceBeforeDiscount.PriceWithVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 127 string Price = WithVATBool ? product.Price.PriceWithVatFormatted : product.Price.PriceWithoutVatFormatted; 128 string yourDiscount = WithVATBool ? product.Discount.PriceWithVatFormatted : product.Discount.PriceWithoutVatFormatted; 129 string gtmDiscount = WithVATBool ? Math.Round(product.Discount.PriceWithVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture) : Math.Round(product.Discount.PriceWithoutVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture); 130 string gtmPrice = WithVATBool ? Math.Round(product.PriceBeforeDiscount.PriceWithVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture) : Math.Round(product.PriceBeforeDiscount.PriceWithoutVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture); 131 string gtmValue = WithVATBool ? Math.Round(product.Price.PriceWithVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture) : Math.Round(product.Price.PriceWithoutVat, 2, MidpointRounding.AwayFromZero).ToString(specifier, culture); 132 string ProductdetailPriceSuffixWithVAT = Translate("Productdetail.Price.Suffix.WithVAT", "Incl. VAT"); 133 string ProductdetailPriceSuffixWithoutVAT = Translate("Productdetail.Price.Suffix.WithoutVAT", "Excl. VAT"); 134 string ProductdetailPriceSuffix = WithVATBool ? ProductdetailPriceSuffixWithVAT : ProductdetailPriceSuffixWithoutVAT; 135 string gtmBrand = !string.IsNullOrWhiteSpace(product.Manufacturer.Name) ? product.Manufacturer.Name.Replace("''", "\\\"").Replace("'", "") : ""; 136 string gtmCategoryName = product.PrimaryOrDefaultGroup?.Name?.Replace("''", "\\\"").Replace("'", ""); 137138 bool hideStockForGuests = EcommerceConfiguration.HideStockForGuests; 139 string stockFormat = EcommerceConfiguration.StockFormat; 140 bool enableProductStock = hideStockForGuests ? Pageview.User != null : true; 141 string stockText = product.StockStatus; 142 double stockSize = (double)product.StockLevel; 143 bool neverOutOfStock = product.NeverOutOfstock; 144 bool isInStock = stockSize > 0 || neverOutOfStock; 145 string stockClass = isInStock ? "products-module__product-stock-state--instock" : "products-module__product-stock-state--outofstock"; 146 string stockSizeFormatted = stockSize.ToString(stockSize % 1 == 0 ? "N0" : "N2", System.Globalization.CultureInfo.GetCultureInfo(Pageview.Area.CultureInfo.TwoLetterISOLanguageName)); 147148 bool hideZeroPrices = EcommerceConfiguration.HideZeroPrices; 149 bool hidePricesForGuests = EcommerceConfiguration.HidePricesForGuests; 150 bool hideShoppingCartForGuests = EcommerceConfiguration.HideShoppingCartForGuests; 151 bool enableAddToCartForZeroPrices = EcommerceConfiguration.AddToCartAllowZeroPrices; 152 bool enableAddToCartForOutOfStock = EcommerceConfiguration.AddToCartAllowOutOfStock; 153154 bool enableProductCompare = Pageview.Area.Item["ConfigModuleProductCompare"] != null ? (bool) Pageview.Area.Item["ConfigModuleProductCompare"] : false; 155 bool enableProductFavorites = Pageview.User == null ? false : Pageview.Area.Item["ConfigModuleFavoriteLists"] != null ? (bool)Pageview.Area.Item["ConfigModuleFavoriteLists"] : false; 156157 bool enableShoppingCart = hideShoppingCartForGuests && Pageview.User == null ? false : Pageview.Area.Item["ConfigModuleShoppingCart"] != null ? (bool)Pageview.Area.Item["ConfigModuleShoppingCart"] : false; 158 bool enableProductShoppingCart = enableShoppingCart; 159 if(!enableAddToCartForZeroPrices && isPriceZero) { 160 enableProductShoppingCart = false; 161 } 162163 if(!enableAddToCartForOutOfStock && !isInStock) { 164 enableProductShoppingCart = false; 165 } 166167 if(product.Discontinued) { 168 enableProductShoppingCart = false; 169 } 170171 bool displayPrice = hidePricesForGuests ? Pageview.User != null : true; 172 bool displayProductPrice = displayPrice; 173 if(hideZeroPrices && isPriceZero) { 174 displayProductPrice = false; 175 } 176177 string informativePrice = WithVATBool ? product.PriceInformative.PriceWithVatFormatted : product.PriceInformative.PriceWithoutVatFormatted; 178 if (EcommerceConfiguration.UseInformativePriceAsFromPrice && !string.IsNullOrWhiteSpace(informativePrice)) 179 { 180 double informativePriceValue = WithVATBool ? product.PriceInformative.PriceWithVat : product.PriceInformative.PriceWithoutVat; 181 double priceValue = WithVATBool ? product.Price.PriceWithVat : product.Price.PriceWithoutVat; 182 hasDiscount = priceValue < informativePriceValue; 183 if (hasDiscount) 184 { 185 OriginalPrice = informativePrice; 186 double yourProfitValue = informativePriceValue - priceValue; 187 yourDiscount = WithVATBool ? new PriceInfo { PriceWithVAT = yourProfitValue }.PriceWithVATFormatted : new PriceInfo { PriceWithoutVAT = yourProfitValue }.PriceWithoutVATFormatted; 188 } 189 } 190191 string retailPrice = ""; 192 bool displayRetailPrice = EcommerceConfiguration.DisplayRetailPrice; 193 if(EcommerceConfiguration.DisplayRetailPriceForUsers && Pageview.User == null) { 194 displayRetailPrice = false; 195 } 196 if(displayRetailPrice) { 197 string priceFieldName = EcommerceConfiguration.RetailPriceField; 198 if(EcommerceConfiguration.RetailPriceIsDbPrice) { 199 var prodService = new Dynamicweb.Ecommerce.Products.ProductService(); 200 var p = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Pageview.Area.EcomLanguageId); 201 PriceContext customerPriceContext = new PriceContext(Dynamicweb.Ecommerce.Common.Context.Currency, Dynamicweb.Ecommerce.Common.Context.Country, null, null, Dynamicweb.Ecommerce.Common.Context.ReverseChargeForVatEnabled, DateTime.Now); 202 var customerPrice = p?.GetPrice(customerPriceContext); 203 if(customerPrice.Price > 0) { 204 retailPrice = WithVATBool ? customerPrice.PriceWithVATFormatted : customerPrice.PriceWithoutVATFormatted; 205 } 206 } else if(!string.IsNullOrWhiteSpace(priceFieldName)) { 207 double customerPriceValue = 0.0; 208 if (product.ProductFields.TryGetValue(priceFieldName, out var fieldValue) && fieldValue.Value is double) { 209 customerPriceValue = (double)fieldValue.Value; 210 } 211 if(customerPriceValue > 0) { 212 retailPrice = WithVATBool ? new PriceInfo { PriceWithVAT = customerPriceValue }.PriceWithVATFormatted : new PriceInfo { PriceWithoutVAT = customerPriceValue }.PriceWithoutVATFormatted; 213 } 214 } 215 } 216217 string yourProfitLabel = Translate("Productdetail.YourProfitLabel", "Uw voordeel:"); 218219 Dynamicweb.Content.Commenting.CommentCollection comments = Dynamicweb.Content.Commenting.Comment.GetComments("ecomProduct", product.Id, Pageview.Area.EcomLanguageId); 220 double? productRating = product.Rating; 221 int productCommentCount = comments.Count; 222223 bool isVariant = product.VariantId != ""; 224 int variantCount = product?.VariantInfo?.VariantInfo?.Count ?? 0; 225 bool hasVariants = !isVariant ? variantCount > 0 : false; 226227 List<FieldOptionValueViewModel> productRibbons = null; 228 if (product.ProductFields["ProductRibbon"] != null) 229 { 230 productRibbons = (List<FieldOptionValueViewModel>)product.ProductFields["ProductRibbon"].Value; 231 } 232233 <li class="products-module__slider-cell"> 234 <div class="products-module products-module__slider-cell__innerwrapper"> 235236 @if(enableProductCompare || enableProductFavorites) 237 { 238 <div class="products-module__actions products-module__actions--showonhover"> 239 @if (enableProductCompare) 240 { 241 @renderProductCompareButton(productId, productName, productImage) 242 } 243 @if (enableProductFavorites) 244 { 245 @renderProductFavoriteButton(productId, productVariantId, productName, productNumber, gtmDiscount, gtmPrice, gtmValue, gtmCategoryName, productManufacturer, listId, listName) 246 } 247 </div> 248 } 249250 @foreach(var rib in productRibbons) { 251 <p class="products-module__ribbon"> 252 <span class="products-module__ribbon-text">@rib.Value</span> 253 </p> 254 } 255256 <figure class="products-module__image-container"> 257 @if(!string.IsNullOrWhiteSpace(productImage)) 258 { 259 <img src="/Admin/Public/GetImage.ashx?Image=@productImage&Crop=7&Format=webp&Quality=90&Compression=80&Height=200" alt="@productName" loading="lazy" height="200" width="300" /> 260 } 261 </figure> 262263 <h3 class="products-module__product-name"> 264 @if(!string.IsNullOrWhiteSpace(productManufacturer)) 265 { 266 <span class="products-module__product-name--manufacturer">@productManufacturer</span> 267 } 268 <span class="products-module__product-name--product">@productName</span> 269 </h3> 270271 @if(!string.IsNullOrWhiteSpace(productNumber)) 272 { 273 <p class="products-module__product-article-number">@productNumber</p> 274 } 275276 @if (productCommentCount > 0) 277 { 278 <div class="products-module__product-review-indicator"> 279 @renderReviewIndicator("#86C440", productRating, productCommentCount) 280 </div> 281 } 282283 <div class="products-module__product-spacer"></div> 284285 @if(hasVariants) 286 { 287 <div class="products-module__product-variant-info"> 288 @if(variantCount == 1) 289 { 290 <p>@string.Format(Translate("ProductBlockVariantInfo.VariantCount.Single", "{0} variant"), variantCount)</p> 291 } 292 else 293 { 294 <p>@string.Format(Translate("ProductBlockVariantInfo.VariantCount.Multiple", "{0} variants"), variantCount)</p> 295 } 296 </div> 297 } 298299 @if (displayPrice && displayProductPrice) 300 { 301 <div class="products-module__product-price-container"> 302 @if(hasVariants) 303 { 304 string minPrice = WithVATBool ? product.VariantInfo.PriceMin.PriceWithVatFormatted : product.VariantInfo.PriceMin.PriceWithoutVatFormatted; 305 string maxPrice = WithVATBool ? product.VariantInfo.PriceMax.PriceWithVatFormatted : product.VariantInfo.PriceMax.PriceWithoutVatFormatted; 306 if(minPrice != maxPrice) 307 { 308 <span class="products-module__product-price">@minPrice - @maxPrice</span> 309 } 310 else 311 { 312 <span class="products-module__product-price">@minPrice</span> 313 } 314 <span class="products-module__product-price-suffix">@ProductdetailPriceSuffix</span> 315 } 316 else 317 { 318 if (hasDiscount) 319 { 320 <span class="products-module__product-price-original">@OriginalPrice</span> 321 <span class="products-module__product-price">@Price</span> 322 } 323 else 324 { 325 <span class="products-module__product-price">@OriginalPrice</span> 326 } 327 <span class="products-module__product-price-suffix">@ProductdetailPriceSuffix</span> 328 if (!string.IsNullOrWhiteSpace(retailPrice)) 329 { 330 <p class="products-module__product-retail-price"> 331 @String.Format(Translate("ProductBlockTitle.RetailPrice", "Retail price: {0}"), retailPrice) 332 </p> 333 } 334 if (hasDiscount) 335 { 336 <p class="products-module__product-your-discount">@Translate("Productdetail.YourProfitLabel", "Uw voordeel:") @yourDiscount</p> 337 } 338 } 339 </div> 340 } 341342 <section class="products-module__product-actions"> 343 @if (enableProductStock && !string.IsNullOrWhiteSpace(stockFormat)) 344 { 345 if(stockFormat == "text") { 346 if (!string.IsNullOrWhiteSpace(stockText)) 347 { 348 <p class="products-module__product-stock-state @stockClass">@string.Format(stockText, stockSize)</p> 349 } 350 } 351 else 352 { 353 string translationTag = ""; 354 if(neverOutOfStock) 355 { 356 translationTag = Translate("ProductBlockStockInfo.AmountInStock", "In stock"); 357 } 358 else if(stockSize == 1) 359 { 360 translationTag = Translate("ProductBlockStockInfo.AmountInStockSingle", "{0} product in stock"); 361 } 362 else if(stockSize > 1) 363 { 364 translationTag = Translate("ProductBlockStockInfo.AmountInStockMultiple", "{0} products in stock"); 365 } 366 else if(!isInStock) 367 { 368 translationTag = Translate("ProductBlockStockInfo.AmountOutOfStock", "Out of stock"); 369 } 370 <p class="products-module__product-stock-state @stockClass">@string.Format(translationTag, stockSizeFormatted)</p> 371 } 372 } 373374 @if(!hasVariants && enableShoppingCart && enableProductShoppingCart) 375 { 376 <add-to-cart 377 class="app-addtocart" 378 data-prodid="@productId" 379 data-variantid="@productVariantId" 380 data-show-text="False" 381 data-min-quantity="@product.PurchaseMinimumQuantity" 382 data-step="@product.PurchaseQuantityStep" 383 data-list-id="@listId" 384 data-list-name="@listName"> 385 </add-to-cart> 386 } 387 else 388 { 389 <a href="@productURL" class="btn btn__primary products-module__more-infobtn"> 390 @if(hasVariants) 391 { 392 <span class="btn__text">@string.Format(Translate("ProductOverview.SeeAllVariants", "View variants"), variantCount)</span> 393 } 394 else 395 { 396 <span class="btn__text">@Translate("ProductOverview.MoreInformation", "More Information")</span> 397 } 398 <i class="btn__icon fal fa-arrow-right"></i> 399 </a> 400 } 401 </section> 402403 <a href="@productURL" class="products-module__link" data-id="@productId" data-variantid="@productVariantId" data-number="@productNumber" data-name='@productName.Replace("''", "\\\"").Replace("'", "")' data-position="@index" data-brand='@gtmBrand' data-category='@gtmCategoryName' data-listid="@listId" data-listname="@listName" data-gtmprice="@gtmPrice" data-gtmdiscount="@gtmDiscount" data-gtmvalue="@gtmValue" data-currencycode="@Dynamicweb.Ecommerce.Common.Context.Currency.Code" aria-label="@productName"></a> 404 </div> 405 </li> 406 } 407408 @helper renderReviewIndicator(string progressbarColor, double? value, int commentCount = 0) 409 { 410 string ratingPercentage = ((100 / 5) * value).ToString() + "%"; 411 string reviewTranslationKey = Translate("Reviews.Amount.Multiple", "{0} reviews"); 412 if(commentCount == 1) { 413 reviewTranslationKey = Translate("Reviews.Amount.Singular", "{0} review"); 414 } 415416 <section style="display: flex; flex-direction: row; position: relative; align-items: center;"> 417 <div class="reviews__indicator" style="display: flex; flex-direction: row;"> 418 <div class="reviews__indicator-progressbar" style="width: @ratingPercentage; background-color: @progressbarColor;"></div> 419 <ul class="reviews__indicator-star-list"> 420 <li class="reviews__indicator-star-list-item"></li> 421 <li class="reviews__indicator-star-list-item"></li> 422 <li class="reviews__indicator-star-list-item"></li> 423 <li class="reviews__indicator-star-list-item"></li> 424 <li class="reviews__indicator-star-list-item"></li> 425 </ul> 426 </div> 427 <span style="display: flex; position: relative; font-size: 12px; line-height: initial;"> 428 @value / 5 (@string.Format(reviewTranslationKey, commentCount)) 429 </span> 430 </section> 431 } 432433 @helper renderProductCompareButton(string productId, string name, string thumbnail) { 434 string title = Translate("ProductBlockAction.Compare", "Add to product compare"); 435436 <button class="products-module__action-btn po-block__action-btn--compare" aria-label="@title" title="@title" data-prodid="@productId" data-imgsmall="@thumbnail" data-prodname="@name"> 437 <i class="fas fa-exchange-alt"></i> 438 </button> 439 } 440441 @helper renderProductFavoriteButton(string productId, string variantId, string productName, string productNumber, string gtmDiscount, string gtmPrice, string gtmValue, string productCategoryName, string productManufacturer, string listId, string listName) { 442 if(string.IsNullOrWhiteSpace(variantId)) { 443 variantId = ""; 444 } 445446 string title = Translate("ProductBlockAction.Wishlist", "Add to wish list"); 447 bool isActive = Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.UserExtensions.IsProductInAnyFavoriteList(Pageview.User, productId, variantId); 448 string activeclass = isActive ? "po-block__action-btn--visible" : ""; 449450 <button class="products-module__action-btn po-block__action-btn--wishlist @activeclass" aria-label="@title" title="@title" data-productid="@productId" data-variantid="@variantId" data-offcanvas-target="favoritelist" data-productid="@productId" data-variantid="@variantId" data-number="@productNumber" data-name='@productName' data-position="1" data-brand='@productManufacturer' data-category='@productCategoryName' data-listid="@listId" data-listname="@listName" data-gtmprice="@gtmPrice" data-gtmdiscount="@gtmDiscount" data-gtmvalue="@gtmValue" data-currencycode="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 451 @if(isActive) { 452 <i class="fas fa-heart"></i> 453 } else { 454 <i class="far fa-heart"></i> 455 } 456 </button> 457 } 458