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.
Coating anti friction polymérisant à chaud
Lire la suiteBonne adhérence; peut être peint.
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_38dc47df8f204ffdbd788a6f0f7ecf96.<>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 119 at CompiledRazorTemplates.Dynamic.RazorEngine_38dc47df8f204ffdbd788a6f0f7ecf96.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, groupTitle, "recently_viewed_articles", index); 72 index++; 73 } 74 </ul> 75 </div> 76 </section> 77 @renderProductListEnhancedEcom(groupTitle, "recently_viewed_articles", recentProducts) 78 </section> 79 } 80 81 @helper renderProductBlock(Dynamicweb.Ecommerce.ProductCatalog.ProductViewModel product, string listId, string listName, int index) 82 { 83 var master_configuration = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "MasterConfiguration"); 84 MasterConfig mc = master_configuration.Item.ToCodeFirstItem<MasterConfig>(); 85 EcomConfig EcommerceConfiguration = mc.EcomConfiguration; 86 87 string productName = product.Name; 88 89 var relProdService = new Dynamicweb.Ecommerce.Products.ProductService(); 90 var relProd = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Pageview.Area.EcomLanguageId); 91 string productImage = Dynamicweb.Ecommerce.Services.ProductImages.GetImagePath(relProd); 92 93 if (string.IsNullOrWhiteSpace(productImage)) 94 { 95 try 96 { 97 var perfionImage = relProdService.GetProductFieldValue(relProd, "AdditionalImages"); 98 productImage = $"Files/" + perfionImage.ToString().Split(';')[0]; 99 } 100 catch (Exception) { } 101 } 102103 bool WithVATBool = Pageview.Area.EcomPricesWithVat == "True"; 104 bool pricesWithoutVatForUsers = EcommerceConfiguration.ShowPricesWithoutVatForUsers; 105 bool pricesWithoutVatForValidVat = EcommerceConfiguration.ShowPricesWithoutVatWhenValidVatNumber; 106 if(pricesWithoutVatForUsers && !pricesWithoutVatForValidVat && Pageview.User != null) { 107 WithVATBool = false; 108 } 109 if(pricesWithoutVatForValidVat && Pageview.User != null && !string.IsNullOrWhiteSpace(Pageview.User.VatRegNumber)) { 110 WithVATBool = false; 111 } 112113 int productDetailPageId = GetPageIdByNavigationTag("ProductOverview"); 114 string currentPageUrl = "/Default.aspx?ID=" + Pageview.Page.ID; 115116 string productNumber = product.Number; 117 string productId = product.Id; 118 string productVariantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : ""; 119 string productURL = $"Default.aspx?ID={productDetailPageId}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 120 productURL += !string.IsNullOrWhiteSpace(product.VariantId) ? "&VariantID=" + product.VariantId : ""; 121 string productManufacturer = product.Manufacturer?.Name ?? ""; 122123 bool isPriceZero = product.Price.Price <= 0; 124 bool hasDiscount = product.Discount.Price > 0; 125 string OriginalPrice = WithVATBool ? product.PriceBeforeDiscount.PriceWithVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 126 string Price = WithVATBool ? product.Price.PriceWithVatFormatted : product.Price.PriceWithoutVatFormatted; 127 string yourDiscount = WithVATBool ? product.Discount.PriceWithVatFormatted : product.Discount.PriceWithoutVatFormatted; 128 double gtmDiscount = WithVATBool ? product.Discount.PriceWithVat : product.Discount.PriceWithoutVat; 129 double gtmPrice = WithVATBool ? product.PriceBeforeDiscount.PriceWithVat : product.PriceBeforeDiscount.PriceWithoutVat; 130 double gtmValue = WithVATBool ? product.Price.PriceWithVat : product.Price.PriceWithoutVat; 131 string ProductdetailPriceSuffixWithVAT = Translate("Productdetail.Price.Suffix.WithVAT", "Incl. VAT"); 132 string ProductdetailPriceSuffixWithoutVAT = Translate("Productdetail.Price.Suffix.WithoutVAT", "Excl. VAT"); 133 string ProductdetailPriceSuffix = WithVATBool ? ProductdetailPriceSuffixWithVAT : ProductdetailPriceSuffixWithoutVAT; 134 string gtmBrand = !string.IsNullOrWhiteSpace(product.Manufacturer.Name) ? product.Manufacturer.Name.Replace("''", "\\\"").Replace("'", "") : ""; 135136 bool hideStockForGuests = EcommerceConfiguration.HideStockForGuests; 137 string stockFormat = EcommerceConfiguration.StockFormat; 138 bool enableProductStock = hideStockForGuests ? Pageview.User != null : true; 139 string stockText = product.StockStatus; 140 double stockSize = (double)product.StockLevel; 141 bool neverOutOfStock = product.NeverOutOfstock; 142 bool isInStock = stockSize > 0 || neverOutOfStock; 143 string stockClass = isInStock ? "products-module__product-stock-state--instock" : "products-module__product-stock-state--outofstock"; 144 string stockSizeFormatted = stockSize.ToString(stockSize % 1 == 0 ? "N0" : "N2", System.Globalization.CultureInfo.GetCultureInfo(Pageview.Area.CultureInfo.TwoLetterISOLanguageName)); 145146 bool hideZeroPrices = EcommerceConfiguration.HideZeroPrices; 147 bool hidePricesForGuests = EcommerceConfiguration.HidePricesForGuests; 148 bool hideShoppingCartForGuests = EcommerceConfiguration.HideShoppingCartForGuests; 149 bool enableAddToCartForZeroPrices = EcommerceConfiguration.AddToCartAllowZeroPrices; 150 bool enableAddToCartForOutOfStock = EcommerceConfiguration.AddToCartAllowOutOfStock; 151152 bool enableProductCompare = Pageview.Area.Item["ConfigModuleProductCompare"] != null ? (bool) Pageview.Area.Item["ConfigModuleProductCompare"] : false; 153 bool enableProductFavorites = Pageview.User == null ? false : Pageview.Area.Item["ConfigModuleFavoriteLists"] != null ? (bool)Pageview.Area.Item["ConfigModuleFavoriteLists"] : false; 154155 bool enableShoppingCart = hideShoppingCartForGuests && Pageview.User == null ? false : Pageview.Area.Item["ConfigModuleShoppingCart"] != null ? (bool)Pageview.Area.Item["ConfigModuleShoppingCart"] : false; 156 bool enableProductShoppingCart = enableShoppingCart; 157 if(!enableAddToCartForZeroPrices && isPriceZero) { 158 enableProductShoppingCart = false; 159 } 160161 if(!enableAddToCartForOutOfStock && !isInStock) { 162 enableProductShoppingCart = false; 163 } 164165 if(product.Discontinued) { 166 enableProductShoppingCart = false; 167 } 168169 bool displayPrice = hidePricesForGuests ? Pageview.User != null : true; 170 bool displayProductPrice = displayPrice; 171 if(hideZeroPrices && isPriceZero) { 172 displayProductPrice = false; 173 } 174175 string informativePrice = WithVATBool ? product.PriceInformative.PriceWithVatFormatted : product.PriceInformative.PriceWithoutVatFormatted; 176 if (EcommerceConfiguration.UseInformativePriceAsFromPrice && !string.IsNullOrWhiteSpace(informativePrice)) 177 { 178 double informativePriceValue = WithVATBool ? product.PriceInformative.PriceWithVat : product.PriceInformative.PriceWithoutVat; 179 hasDiscount = gtmValue < informativePriceValue; 180 if (hasDiscount) 181 { 182 OriginalPrice = informativePrice; 183 double yourProfitValue = informativePriceValue - gtmValue; 184 yourDiscount = WithVATBool ? new PriceInfo { PriceWithVAT = yourProfitValue }.PriceWithVATFormatted : new PriceInfo { PriceWithoutVAT = yourProfitValue }.PriceWithoutVATFormatted; 185 } 186 } 187188 string retailPrice = ""; 189 bool displayRetailPrice = EcommerceConfiguration.DisplayRetailPrice; 190 if(EcommerceConfiguration.DisplayRetailPriceForUsers && Pageview.User == null) { 191 displayRetailPrice = false; 192 } 193 if(displayRetailPrice) { 194 string priceFieldName = EcommerceConfiguration.RetailPriceField; 195 if(EcommerceConfiguration.RetailPriceIsDbPrice) { 196 var prodService = new Dynamicweb.Ecommerce.Products.ProductService(); 197 var p = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Pageview.Area.EcomLanguageId); 198 PriceContext customerPriceContext = new PriceContext(Dynamicweb.Ecommerce.Common.Context.Currency, Dynamicweb.Ecommerce.Common.Context.Country, null, null, Dynamicweb.Ecommerce.Common.Context.ReverseChargeForVatEnabled, DateTime.Now); 199 var customerPrice = p?.GetPrice(customerPriceContext); 200 if(customerPrice.Price > 0) { 201 retailPrice = WithVATBool ? customerPrice.PriceWithVATFormatted : customerPrice.PriceWithoutVATFormatted; 202 } 203 } else if(!string.IsNullOrWhiteSpace(priceFieldName)) { 204 double customerPriceValue = 0.0; 205 if (product.ProductFields.TryGetValue(priceFieldName, out var fieldValue) && fieldValue.Value is double) { 206 customerPriceValue = (double)fieldValue.Value; 207 } 208 if(customerPriceValue > 0) { 209 retailPrice = WithVATBool ? new PriceInfo { PriceWithVAT = customerPriceValue }.PriceWithVATFormatted : new PriceInfo { PriceWithoutVAT = customerPriceValue }.PriceWithoutVATFormatted; 210 } 211 } 212 } 213214 string yourProfitLabel = Translate("Productdetail.YourProfitLabel", "Uw voordeel:"); 215216 Dynamicweb.Content.Commenting.CommentCollection comments = Dynamicweb.Content.Commenting.Comment.GetComments("ecomProduct", product.Id, Pageview.Area.EcomLanguageId); 217 double? productRating = product.Rating; 218 int productCommentCount = comments.Count; 219220 bool isVariant = product.VariantId != ""; 221 int variantCount = product?.VariantInfo?.VariantInfo?.Count ?? 0; 222 bool hasVariants = !isVariant ? variantCount > 0 : false; 223224 List<FieldOptionValueViewModel> productRibbons = null; 225 if (product.ProductFields["ProductRibbon"] != null) 226 { 227 productRibbons = (List<FieldOptionValueViewModel>)product.ProductFields["ProductRibbon"].Value; 228 } 229230 <li class="products-module__slider-cell"> 231 <div class="products-module products-module__slider-cell__innerwrapper"> 232233 @if(enableProductCompare || enableProductFavorites) 234 { 235 <div class="products-module__actions products-module__actions--showonhover"> 236 @if (enableProductCompare) 237 { 238 @renderProductCompareButton(productId, productName, productImage) 239 } 240 @if (enableProductFavorites) 241 { 242 @renderProductFavoriteButton(productId, productVariantId, productName, productNumber, gtmDiscount, gtmPrice, gtmValue, "", productManufacturer, listId, listName) 243 } 244 </div> 245 } 246247 @foreach(var rib in productRibbons) { 248 <p class="products-module__ribbon"> 249 <span class="products-module__ribbon-text">@rib.Value</span> 250 </p> 251 } 252253 <figure class="products-module__image-container"> 254 @if(!string.IsNullOrWhiteSpace(productImage)) 255 { 256 <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" /> 257 } 258 </figure> 259260 <h3 class="products-module__product-name"> 261 @if(!string.IsNullOrWhiteSpace(productManufacturer)) 262 { 263 <span class="products-module__product-name--manufacturer">@productManufacturer</span> 264 } 265 <span class="products-module__product-name--product">@productName</span> 266 </h3> 267268 @if(!string.IsNullOrWhiteSpace(productNumber)) 269 { 270 <p class="products-module__product-article-number">@productNumber</p> 271 } 272273 @if (productCommentCount > 0) 274 { 275 <div class="products-module__product-review-indicator"> 276 @renderReviewIndicator("#86C440", productRating, productCommentCount) 277 </div> 278 } 279280 <div class="products-module__product-spacer"></div> 281282 @if(hasVariants) 283 { 284 <div class="products-module__product-variant-info"> 285 @if(variantCount == 1) 286 { 287 <p>@string.Format(Translate("ProductBlockVariantInfo.VariantCount.Single", "{0} variant"), variantCount)</p> 288 } 289 else 290 { 291 <p>@string.Format(Translate("ProductBlockVariantInfo.VariantCount.Multiple", "{0} variants"), variantCount)</p> 292 } 293 </div> 294 } 295296 @if (displayPrice && displayProductPrice) 297 { 298 <div class="products-module__product-price-container"> 299 @if(hasVariants) 300 { 301 string minPrice = WithVATBool ? product.VariantInfo.PriceMin.PriceWithVatFormatted : product.VariantInfo.PriceMin.PriceWithoutVatFormatted; 302 string maxPrice = WithVATBool ? product.VariantInfo.PriceMax.PriceWithVatFormatted : product.VariantInfo.PriceMax.PriceWithoutVatFormatted; 303 if(minPrice != maxPrice) 304 { 305 <span class="products-module__product-price">@minPrice - @maxPrice</span> 306 } 307 else 308 { 309 <span class="products-module__product-price">@minPrice</span> 310 } 311 <span class="products-module__product-price-suffix">@ProductdetailPriceSuffix</span> 312 } 313 else 314 { 315 if (hasDiscount) 316 { 317 <span class="products-module__product-price-original">@OriginalPrice</span> 318 <span class="products-module__product-price">@Price</span> 319 } 320 else 321 { 322 <span class="products-module__product-price">@OriginalPrice</span> 323 } 324 <span class="products-module__product-price-suffix">@ProductdetailPriceSuffix</span> 325 if (!string.IsNullOrWhiteSpace(retailPrice)) 326 { 327 <p class="products-module__product-retail-price"> 328 @String.Format(Translate("ProductBlockTitle.RetailPrice", "Retail price: {0}"), retailPrice) 329 </p> 330 } 331 if (hasDiscount) 332 { 333 <p class="products-module__product-your-discount">@Translate("Productdetail.YourProfitLabel", "Uw voordeel:") @yourDiscount</p> 334 } 335 } 336 </div> 337 } 338339 <section class="products-module__product-actions"> 340 @if (enableProductStock && !string.IsNullOrWhiteSpace(stockFormat)) 341 { 342 if(stockFormat == "text") { 343 if (!string.IsNullOrWhiteSpace(stockText)) 344 { 345 <p class="products-module__product-stock-state @stockClass">@string.Format(stockText, stockSize)</p> 346 } 347 } 348 else 349 { 350 string translationTag = ""; 351 if(neverOutOfStock) 352 { 353 translationTag = Translate("ProductBlockStockInfo.AmountInStock", "In stock"); 354 } 355 else if(stockSize == 1) 356 { 357 translationTag = Translate("ProductBlockStockInfo.AmountInStockSingle", "{0} product in stock"); 358 } 359 else if(stockSize > 1) 360 { 361 translationTag = Translate("ProductBlockStockInfo.AmountInStockMultiple", "{0} products in stock"); 362 } 363 else if(!isInStock) 364 { 365 translationTag = Translate("ProductBlockStockInfo.AmountOutOfStock", "Out of stock"); 366 } 367 <p class="products-module__product-stock-state @stockClass">@string.Format(translationTag, stockSizeFormatted)</p> 368 } 369 } 370371 @if(!hasVariants && enableShoppingCart && enableProductShoppingCart) 372 { 373 <add-to-cart 374 class="app-addtocart" 375 data-prodid="@productId" 376 data-variantid="@productVariantId" 377 data-show-text="False" 378 data-min-quantity="@product.PurchaseMinimumQuantity" 379 data-step="@product.PurchaseQuantityStep" 380 data-list-id="@listId" 381 data-list-name="@listName"> 382 </add-to-cart> 383 } 384 else 385 { 386 <a href="@productURL" class="btn btn__primary products-module__more-infobtn"> 387 @if(hasVariants) 388 { 389 <span class="btn__text">@string.Format(Translate("ProductOverview.SeeAllVariants", "View variants"), variantCount)</span> 390 } 391 else 392 { 393 <span class="btn__text">@Translate("ProductOverview.MoreInformation", "More Information")</span> 394 } 395 <i class="btn__icon fal fa-arrow-right"></i> 396 </a> 397 } 398 </section> 399400 <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='@product.PrimaryOrDefaultGroup.Name.Replace("''", "\\\"").Replace("'", "")' 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> 401 </div> 402 </li> 403 } 404405 @helper renderProductListEnhancedEcom(string listId, string listName, IEnumerable<ProductViewModel> products) 406 { 407 var index = 1; 408 string specifier = "G"; 409 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 410411 <text> 412 <script> 413 if(window.dataLayer) { 414 dataLayer.push({ 415 'event': 'view_item_list', 416 'ecommerce': { 417 'item_list_id': '@listId', 418 'item_list_name': '@listName', 419 'items': [ 420 @foreach (var product in products) { 421 string pName = product.Name.Replace("''", "\\\"").Replace("'", ""); 422 string pGroupName = product.PrimaryOrDefaultGroup?.Name?.Replace("''", "\\\"").Replace("'", ""); 423 string pBrand = product.Manufacturer?.Name?.Replace("''", "\\\"").Replace("'", ""); 424 <text> 425 { 426 'item_id': '@product.Id', 427 'item_name': '@pName', 428 'item_number': '@product.Number', 429 'discount': @product.Discount.Price.ToString(specifier, culture), 430 'index': @index, 431 'item_brand': '@pBrand', 432 'item_category': '@pGroupName', 433 'item_list_id': '@listId', 434 'item_list_name': '@listName', 435 'item_variant': '@product.VariantId', 436 'price': @product.Price.Price.ToString(specifier, culture), 437 'quantity': 1, 438 }, 439 </text> 440 index++; 441 } 442 ] 443 } 444 }); 445 } 446 </script> 447 </text> 448 } 449450 @helper renderReviewIndicator(string progressbarColor, double? value, int commentCount = 0) 451 { 452 string ratingPercentage = ((100 / 5) * value).ToString() + "%"; 453 string reviewTranslationKey = Translate("Reviews.Amount.Multiple", "{0} reviews"); 454 if(commentCount == 1) { 455 reviewTranslationKey = Translate("Reviews.Amount.Singular", "{0} review"); 456 } 457458 <section style="display: flex; flex-direction: row; position: relative; align-items: center;"> 459 <div class="reviews__indicator" style="display: flex; flex-direction: row;"> 460 <div class="reviews__indicator-progressbar" style="width: @ratingPercentage; background-color: @progressbarColor;"></div> 461 <ul class="reviews__indicator-star-list"> 462 <li class="reviews__indicator-star-list-item"></li> 463 <li class="reviews__indicator-star-list-item"></li> 464 <li class="reviews__indicator-star-list-item"></li> 465 <li class="reviews__indicator-star-list-item"></li> 466 <li class="reviews__indicator-star-list-item"></li> 467 </ul> 468 </div> 469 <span style="display: flex; position: relative; font-size: 12px; line-height: initial;"> 470 @value / 5 (@string.Format(reviewTranslationKey, commentCount)) 471 </span> 472 </section> 473 } 474475 @helper renderProductCompareButton(string productId, string name, string thumbnail) { 476 string title = Translate("ProductBlockAction.Compare", "Add to product compare"); 477478 <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"> 479 <i class="fas fa-exchange-alt"></i> 480 </button> 481 } 482483 @helper renderProductFavoriteButton(string productId, string variantId, string productName, string productNumber, double gtmDiscount, double gtmPrice, double gtmValue, string productCategoryName, string productManufacturer, string listId, string listName) { 484 if(string.IsNullOrWhiteSpace(variantId)) { 485 variantId = ""; 486 } 487488 string title = Translate("ProductBlockAction.Wishlist", "Add to wish list"); 489 bool isActive = Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.UserExtensions.IsProductInAnyFavoriteList(Pageview.User, productId, variantId); 490 string activeclass = isActive ? "po-block__action-btn--visible" : ""; 491492 <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"> 493 @if(isActive) { 494 <i class="fas fa-heart"></i> 495 } else { 496 <i class="far fa-heart"></i> 497 } 498 </button> 499 } 500