Vitajte!
Exception in template (Designs\Rapido\eCom/Product/Product_custom.cshtml): System.Data.SqlClient.SqlException (0x80131904): ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
   at Dynamicweb.Data.Database.CreateDataSet(IDbDataAdapter dataAdapter, Boolean withSchema)
   at Dynamicweb.Data.Database.CreateDataSet(String sql, IDbConnection connection, IDbTransaction transaction, Boolean withSchema, Dictionary`2 sqlParams)
   at Dynamicweb.Data.Database.CreateDataTable(String sql)
   at CompiledRazorTemplates.Dynamic.ccbccdceaabcf.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, DynamicViewBag viewBag, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:bb4e6345-0feb-48e3-b765-fc76c6946cf1
Error Number:145,State:1,Class:15
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using System.Web @using Dynamicweb.Extensibility @using Dynamicweb.Content @using System @using System.IO @using Dynamicweb.Core @using System.Web @using System.Globalization @using System.Web.UI.HtmlControls @using Dynamicweb.Rapido.Blocks @{ //canonical string url = "Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&ProductID="+ GetString("Ecom:Product.ID"); string canonicalURL = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(url); //canonicalURL = "https://www.allmedia.sk" + canonicalURL; canonicalURL = "<link rel=\"canonical\" href=\"" + canonicalURL+ "\">"; Pageview.Meta.AddTag("customCan", canonicalURL); } @functions { BlocksPage productsPage = BlocksPage.GetBlockPage("Product"); public static string ToPascalCase(string str) { return CultureInfo.InvariantCulture.TextInfo .ToTitleCase(str.ToLowerInvariant()) .Replace("-", "") .Replace("_", "") .Replace(" ", ""); } } @{ Block productTop = new Block() { Id = "Top", SortId = 10, Design = new Design { RenderType = RenderType.Row } }; productsPage.Add(productTop); Block productMainInfo = new Block() { Id = "MainInformation", SortId = 10, Design = new Design { Size = "auto", RenderType = RenderType.Column } }; productsPage.Add("Top", productMainInfo); if (!String.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("ProductPage").GetString("ImageSectionPosition"))) { productMainInfo.SortId = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue == "left-left" || Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue == "left-right" ? 2 : 1; } //Optional mini tabs block Block miniTabsBlock = new Block() { Id = "MiniTabs", SortId = 40, Template = RenderProductMiniTabs(), SkipRenderBlocksList = true }; productsPage.Add("MainInformation", miniTabsBlock); //----- Block productTabsBlock = new Block() { Id = "Tabs", SortId = 30, Template = RenderProductTabs(), SkipRenderBlocksList = true }; productsPage.Add(productTabsBlock); Block productDetailsBlock = new Block() { Id = "Section", SortId = 30 }; productsPage.Add(productDetailsBlock); Block productSnippetsBlock = new Block() { Id = "Snippets", SortId = 40 }; productsPage.Add(productSnippetsBlock); } @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ @using System.Text.RegularExpressions @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @*--- START: Base block renderers ---*@ @helper RenderBlockList(List<Block> blocks) { blocks = blocks.OrderBy(item => item.SortId).ToList(); foreach (Block item in blocks) { <!-- START: @item.Id --> if (item.Design == null) { @RenderBlock(item) } else if (item.Design.RenderType != RenderType.Hide) { if (item.Design.RenderType == RenderType.Row) { <div class="grid grid--align-content-start"> @RenderBlock(item) </div> } if (item.Design.RenderType == RenderType.Column) { string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; string size = item.Design.Size != null ? item.Design.Size : "12"; size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding" id="Block__@item.Id"> @RenderBlock(item) </div> } if (item.SkipRenderBlocksList == true) { @RenderBlock(item) } } <!-- END: @item.Id --> } } @helper RenderBlock(Block item) { if (item.Template != null) { @BlocksPage.RenderTemplate(item.Template) } if (item.BlocksList.Count > 0 && item.SkipRenderBlocksList == false) { @RenderBlockList(item.BlocksList) } } @*--- END: Base block renderers ---*@ @* Include the Blocks for the page *@ @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @functions { BlocksPage mainImagePage = BlocksPage.GetBlockPage("Product"); } @{ string imageBlockPosition = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ImageSectionPosition")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "right-right"; string imageBlockWidth = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("TopLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout").SelectedValue : "6"; imageBlockWidth = imageBlockPosition == "left-left" || imageBlockPosition == "left-right" ? Converter.ToString(12 - Converter.ToInt32(imageBlockWidth)) : imageBlockWidth; Block mainImageBlock = new Block() { Id = "MainImage", SortId = imageBlockPosition == "left-left" || imageBlockPosition == "left-right" ? 1 : 2, Template = RenderMainImageContainer(), Design = new Design { Size = imageBlockWidth, RenderType = RenderType.Column } }; mainImagePage.Add("Top", mainImageBlock); } @helper RenderModal() { string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; <!-- Trigger for the gallery modal --> <input type="checkbox" id="GalleryModalTrigger" class="modal-trigger" /> if (!String.IsNullOrEmpty(GetString("Ecom:Product.ImageLarge.Default.Clean"))) { <!-- Gallery modal --> <div class="modal-container"> <label for="GalleryModalTrigger" id="GalleryModalOverlay" class="modal-overlay"></label> <div class="modal modal--full" id="GalleryModal"> <div class="modal__body modal__body--full"> <div class="gallery-slider"> <div class="gallery-slider__image"> <img id="FullImage" src="@GetString("Ecom:Product.ImageLarge.Default.Clean")" class="modal--full__img js-gallery-image" alt="@GetString("Ecom:Product.Name")" /> </div> <div class="gallery-slider__image-counter" id="FullImage_counter"></div> <label class="gallery-slider__close-btn" for="GalleryModalTrigger"></label> <button class="gallery-slider__previous-btn" id="FullImage_prev" onclick="Gallery.prevImage('FullImage')"></button> <button class="gallery-slider__next-btn" id="FullImage_next" onclick="Gallery.nextImage('FullImage')"></button> </div> </div> </div> </div> } } @helper RenderMainImageContainer() { string imageBlockPosition = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ImageSectionPosition")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "right-right"; @RenderModal() <div class="grid grid--bleed"> @if (imageBlockPosition == "left-left" || imageBlockPosition == "right-left") { @RenderThumbnails() @RenderImage() } else { @RenderImage() @RenderThumbnails() } </div> } @helper RenderImage() { string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; string productId = GetString("Ecom:Product.ID"); bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly") && Pageview.User == null; <div class="grid__col-auto"> <div class="stickers-container dw-mod"> @{ if (Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetBoolean("Enable") && !pointShopOnly) { string contentType = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetString("ContentType"); string text = ""; var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); if(GetBoolean("Ecom:Product:Field.Sales.Value") ){ text = Translate("Sale!"); <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } switch (contentType) { case "Name": foreach (LoopItem discount in GetLoop("ProductDiscounts")) { text = discount.GetString("Ecom:Product.Discount.Name"); <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } break; case "Amount": if (GetLoop("ProductDiscounts").Count > 0) { text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, GetDouble("Ecom:Product.Discount.Price.Price") - GetDouble("Ecom:Product.Price.Price")); <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } break; case "Percents": double percents = 0; foreach (LoopItem discount in GetLoop("ProductDiscounts")) { percents += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); } if (percents > 0) { text = Math.Round(percents, 0) + "%"; <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } break; case "Amount and percents": double amount = 0; double percent = 0; foreach (LoopItem discount in GetLoop("ProductDiscounts")) { if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT") { percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); } else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT") { amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT"); } } if (percent > 0) { text = percent + "%"; <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } if (amount > 0) { text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } break; default: if (GetLoop("ProductDiscounts").Count > 0) { text = Translate("Sale!"); <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> } break; } } if (!pointShopOnly && Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable") && GetDate("Ecom:Product.Created").AddDays(Converter.ToDouble(Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetString("Expiration"))) > DateTime.Now) { <div class="stickers-container__tag stickers-container__tag--new dw-mod">@Translate("New!")</div> } if(!pointShopOnly && GetBoolean("Ecom:Product:Field.New.Value") && Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable")){ <div class="stickers-container__tag stickers-container__tag--new dw-mod">@Translate("New!")</div> } if(!pointShopOnly && GetBoolean("Ecom:Product:Field.Liquidation.Value") ){ <div class="stickers-container__tag stickers-container__tag--custom dw-mod">@Translate("Clearance!")</div> } if (!pointShopOnly && !String.IsNullOrEmpty(GetString("Ecom:Product:Field.CustomSticker.Value"))) { <div class="stickers-container__tag stickers-container__tag--custom dw-mod">@GetString("Ecom:Product:Field.CustomSticker.Value")</div> } } </div> <label for="GalleryModalTrigger" class="product__image-container"> <img class="thumb-image-view product__image-container__image dw-mod b-lazy" src="/Files/Images/placeholder.gif" data-src="@imagePrefix@GetString("Ecom:Product.ImageDefault.Default.Clean")" alt="@GetString("Ecom:Product.Name")" id="Image_@productId" data-for="FullImage" data-number="0" onclick="Gallery.openImageByNum(this)" /> </label> </div> } @helper RenderThumbnails() { <div class="grid__col-2 u-hidden-xxs dw-mod"> <div class="product__thumbs dw-mod"> <i class="fas fa-circle-notch fa-spin preloader js-remove-after-load"></i> <!--preloader--> <div class="carousel js-carousel-container carousel--hidden dw-mod" id="leftCarousel"> <div class="thumb-list carousel__container dw-mod"> @*Main image thumb*@ @RenderThumbnail(GetString("Ecom:Product.ImageDefault.Default.Clean")) @foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) { if (!String.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"))) { @RenderThumbnail(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image")) } } @foreach (LoopItem detail in GetLoop("Details")) { if (!String.IsNullOrEmpty(detail.GetString("Ecom:Product:Detail.Image.Clean"))) { string ext = Path.GetExtension(detail.GetString("Ecom:Product:Detail.Image.Clean")).ToLower(); if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png") { @RenderThumbnail(detail.GetString("Ecom:Product:Detail.Image.Clean")) } } } </div> <div class="js-carousel-data" data-carousel-slide-time="0" data-direction="vertical" data-sliding-type="items" data-slides-in-view="5"> <div class="carousel-prev-btn carousel-prev-btn--vertical dw-mod" onclick="Carousel.GetPreviousSlide('leftCarousel')"></div> <div class="carousel-next-btn carousel-next-btn--vertical dw-mod" onclick="Carousel.GetNextSlide('leftCarousel')"></div> </div> </div> </div> </div> } @helper RenderThumbnail(string image) { string productId = GetString("Ecom:Product.ID"); string thumbPrefix = "/Admin/Public/GetImage.ashx?width=200&amp;height=200&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; <div class="carousel__slide carousel__slide--vertical dw-mod"> <div class="thumb-list__item thumb-list__item--active dw-mod js-thumb js-gallery" data-for="Image_@productId" data-image="@imagePrefix@image" onmouseover="Gallery.openImage(this)"> <label for="GalleryModalTrigger"> <img src="@thumbPrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery" data-for="FullImage" data-image="@image" onclick="Gallery.openImage(this)"> </label> </div> </div> } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @using BrandFusion.Dw.AllMedia.Ecommerce @functions { bool useFacebookPixel; bool useGoogleTagManager; BlocksPage mainInfoPage = BlocksPage.GetBlockPage("Product"); } @{ bool mainInfoRenderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetString("RenderVariantsAsProductList") != null && GetInteger("Ecom:Product.VariantCount") > 1 ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") : false; bool mainInfoOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; string mainInfoVariantId = HttpContext.Current.Request.QueryString.Get("variantId") != null ? HttpContext.Current.Request.QueryString.Get("variantId") : ""; string mainInfoFeedId = GetGlobalValue("Global:Page.ID").ToString() + "&ProductID=" + GetString("Ecom:Product.ID") + "&VariantID=" + mainInfoVariantId + "&Feed=True&redirect=false"; string mainInfoCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetString("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); //string packageQuantity = GetDouble("Ecom:Product:Field.PackageQuantity.Value") > 1 ? GetString("Ecom:Product:Field.PackageQuantity.Value") : "1"; //double productStock = GetDouble("Ecom:Product.Stock"); //var maximumAvailable = GetDouble("Ecom:Product:Field.PackageQuantity.Value") > 1 ? Math.Floor(GetDouble("Ecom:Product.Stock")/GetDouble("Ecom:Product:Field.PackageQuantity.Value")) : 1; //packageQuantity = packageQuantity.Replace(",","."); //string productPackageQuantity = !string.IsNullOrEmpty(GetString("Ecom:Product:Field.PackageQuantity.Value")) && Double.Parse(GetString("Ecom:Product:Field.PackageQuantity.Value")) > 1.0 ? "data-multiplier=\""+GetString("Ecom:Product:Field.PackageQuantity.Value")+"\" data-message=\""+ Translate("minimumQuantityMessage{0}and{1}") + "\" data-maximum-available=\""+ maximumAvailable +"\"" : ""; Block mainInfoHeader = new Block() { Id = "MainInfoHeader", SortId = 10, Template = RenderMainInfoHeader() }; mainInfoPage.Add("MainInformation", mainInfoHeader); Block mainInfoDescription = new Block() { Id = "ShortDescription", SortId = 30, Template = RenderShortDescription() }; mainInfoPage.Add("MainInformation", mainInfoDescription); if (!mainInfoRenderVariantsAsProducts) { Block mainInfoVariants = new Block() { Id = "Variants", SortId = 50, Template = RenderMainInfoVariants() }; mainInfoPage.Add("MainInformation", mainInfoVariants); } Block mainInfoBOM = new Block() { Id = "BOM", SortId = 60, Template = RenderMainInfoBOM() }; mainInfoPage.Add("MainInformation", mainInfoBOM); if (!mainInfoRenderVariantsAsProducts) { Block mainInfoPrice = new Block() { Id = "Price", SortId = 70, Template = RenderMainInfoPrice() }; mainInfoPage.Add("MainInformation", mainInfoPrice); Block mainInfoBuy = new Block() { Id = "Buy", SortId = 80, Template = RenderMainInfoBuy() }; mainInfoPage.Add("MainInformation", mainInfoBuy); //Block stockAndShipping = new Block() //{ //Id = "StockAndShipping", //SortId = 90, //Template = RenderStockAndShipping() //}; //mainInfoPage.Add("MainInformation", stockAndShipping); } Block mainInfoActionIcons = new Block() { Id = "Icons", SortId = 85, Template = RenderMainInfoIcons() }; mainInfoPage.Add("MainInformation", mainInfoActionIcons); } @helper RenderMainInfoHeader() { bool renderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") != null && GetInteger("Ecom:Product.VariantCount") > 1 ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") : false; string pageId = GetGlobalValue("Global:Page.ID").ToString(); string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted"); bool hideProductNumber = false; <div> <div class="u-pull--left product__title dw-mod"> <h1 class="u-no-margin">@GetString("Ecom:Product.Name") @GetString("Ecom:Product.SelectedVariantComboName")</h1> @if (!hideProductNumber) { <div class="item-number dw-mod">@GetString("Ecom:Product.Number")</div> } </div> </div> } @helper RenderCompareLink(string productId, string variantId, string feedId){ string compareID = GetString("Ecom:Product.CompareID"); string compareIcon = "fas fa-balance-scale"; <div id="@compareID" class="favorites favorites--md u-pull--left js-favorite-btn dw-mod"> <div> <label for="CompareTrigger"> <!-- <i class="@compareIcon fa-1_5x"></i> --> <a class="addToCompare" data-add-compare='@Translate("Add to compare")' data-remove-compare='@Translate("Remove from compare")' data-url="/Default.aspx?ID=@feedId" data-variant-id="@variantId" data-id='@productId' data-img='/Admin/Public/GetImage.ashx?width=75&amp;height=75&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image=@GetString("Ecom:Product.ImageDefault.Default.Clean")' data-name='@GetString("Ecom:Product.Name")'><i class="fal fa-balance-scale fa-1_5x" data-tooltip='@Translate("compareProduct", "Compare Product")'></i></a> </label> </div> </div> } @helper RenderSimilarProducts(){ <div class="similarProductsIcon favorites--md"> <div> <label for="SimilarProducts"><i class="fal fa-sitemap fa-1_5x" data-tooltip='@Translate("similarProducts", "See Similar Products")'></i></label> </div> </div> } @helper RenderShare(){ string productName = GetString("Ecom:Product.Name"); string productIntro = GetString("Ecom:Product.ShortDescription"); string pageScheme = Pageview.GlobalTags.GetTagByName("Global:Request.Scheme").Value.ToString(); string requestHost = "://"+ Pageview.GlobalTags.GetTagByName("Global:Request.Host").Value.ToString(); string pageURL = Pageview.GlobalTags.GetTagByName("Global:Pageview.Url").Value.ToString(); string facebookShareLink = "https://www.facebook.com/sharer/sharer.php?u=" + pageScheme + requestHost + pageURL; string twitterShareLink = "https://twitter.com/home?status="+pageScheme+requestHost + pageURL; string linkedinShareLink = "https://www.linkedin.com/shareArticle?mini=true&url=" + pageScheme+requestHost+pageURL +"&title=" + HttpContext.Current.Server.UrlEncode(productName) + "&summary=" + HttpContext.Current.Server.UrlEncode(productIntro)+"&source="; <div class="shareParentIcon show-modal favorites--md "> <i class="fal fa-1_5x fa-share-alt tooltip-icon" data-tooltip='@Translate("share", "Share")'></i> <div id="shareIcons" class="shareIcons"> <div class="modal-overlay-custom u-hidden"> <div class="modal-content-custom"> <span class="modal-header-custom"> <h2>@Translate("share")</h2> <i class="fas fa-times"></i> </span> <ul> <li> <a target="_blank" href="@facebookShareLink"><span><i class="fa-facebook-square fab"></i> @Translate("shareFacebook", "Share facebook")</span></a> </li> <li> <a target="_blank" href="@twitterShareLink"><span><i class="fa-twitter-square fab"></i> @Translate("shareTwitter", "Share twitter")</span></a> </li> <li> <a target="_blank" href="@linkedinShareLink"><span><i class="fa-linkedin fab"></i> @Translate("shareLinkedin", "Share linkedin")</span></a> </li> </ul> </div> </div> </div> </div> } @helper RenderMainInfoNotifyBackInStock(){ bool notificationRegistered = GetBoolean("Ecom:Product.NotificationRegistered"); int productStock = GetInteger("Ecom:Product.Stock"); var username = GetGlobalValue("Global:Extranet.UserName"); string productPageID = GetString("Ecom:Product:Page.ID"); string productID = GetString("Ecom:Product.ID"); string variantID = GetString("Ecom:Product.VariantID"); string productLanguageID = GetString("Ecom:Product.LanguageID"); string createNotificationLink = "/default.aspx?id="+productPageID+"&productid="+productID+"&VariantID="+variantID+"&LanguageID="+productLanguageID+"&cartcmd=createnotificationforthisproduct"; string createNotificationText = Translate("createnotification", "Create notification"); string createNotificationEmailLabel = Translate("Email", "Email"); int variantCount = GetInteger("Ecom:Product.VariantCount"); if (productStock <= 0 && variantCount==0){ <div class="notifyParentIcon show-modal favorites--md "> @if (notificationRegistered != true) { <i class="fal fa-bell fa-1_5x tooltip-icon" data-tooltip='@Translate("Create Notification", "Create notification")'></i> <div class="notifyDialog "> <div class="modal-overlay-custom u-hidden "> <div class="modal-content-custom"> <span class="modal-header-custom"> <h2>@Translate("getNotification", "Find out when product is back on stock")</h2> <i class="fas fa-times"></i> </span> <div class="modal-body-custom"> <div class="grid__cell"> <form name="@productID" id="NotificationForm_@productID" method="post" class="u-margin-auto grid__col-auto-width" action="/Default.aspx?ID=@productPageID"> <input type="hidden" name="ProductID" id="ProductID" value="@productID" /> <input type="hidden" name="VariantID" id="VariantID" value="@variantID" /> <input type="hidden" name="LanguageID" id="LanguageID" value="@productLanguageID" /> <input type="hidden" name="CartCmd" id="CartCmd" value="createnotificationforthisproduct" /> <label for="NotificationEmail">@createNotificationEmailLabel</label> <input type="email" required="required" id="NotificationEmail" name="NotificationEmail" value=""/> <input type="submit" value="@createNotificationText" class="btn btn--primary btn--condensed u-no-margin dw-mod"/> </form> </div> </div> </div> </div> </div> }else { <i class="fas fa-bell fa-1_5x tooltip-icon" data-tooltip='@Translate("Notification created", "Notification created")'></i> } </div> } } @helper RenderFavoritesLink(){ bool renderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") != null && GetInteger("Ecom:Product.VariantCount") > 1 ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") : false; string favoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetString("FavoriteIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "fas fa-star"; string favoriteOutlineIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetString("FavoriteIcon") != null ? "far fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "far fa-star"; @* <div class="u-pull--right"> *@ if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) { string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); <div id="@favoriteId" class="favorites favorites--md u-pull--left js-favorite-btn dw-mod"> <div> @{ string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon; string AddToWishlist = "fbq('track', 'AddToWishlist', {" + "content_name: '" + GetString("Ecom:Product.Name") + "'," + "content_ids: ['" + GetString("Ecom:Product.Number") + "']," + "value: " + GetDouble("Ecom:Product.Price.Price") + "," + "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" + "});"; } <label for="FavoriteTrigger"><i class="@favorite fa-1_5x tooltip-icon" data-tooltip='@Translate("addToFavorites", "Add To Favorites")'></i> </label> </div> <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" /> <div class="dropdown"> <div class="dropdown__content dropdown__content--show-left dw-mod"> <div class="modal-content-custom-favorites modal--md"> <span class="modal__header modal-header-rapido"> <h2>@Translate("Add to favorites")</h2> <i class="fas fa-times" data-trigger="FavoriteTrigger"></i> </span> <span class="modal-body-custom"> <h6> @Translate("Choose list") </h6> <div class="product-wrapper"> <img src="/Admin/Public/GetImage.ashx?width=50&amp;height=50&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image=@GetString("Ecom:Product.ImageDefault.Default.Clean")" alt="productImage"> <h6 class="product-name">@GetString("Ecom:Product.Name")</h6> </div> @if (GetLoop("CustomerCenter.ListTypes").Count > 0) { foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) { foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) { string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction"); string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon; <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")</a> } } } else { string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites"); string isInListIcon = favoriteOutlineIcon; <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a> } </span> </div> </div> <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> </div> </div> } @* </div> *@ } @helper RenderStockAndShipping() { bool hideStockState = Pageview.AreaSettings.GetItem("ProductPage").GetString("HideStockState") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideStockState") : false; bool hideDelivery = Pageview.AreaSettings.GetItem("ProductPage").GetString("HideShipping") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideShipping") : false; bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; string stockText = GetString("Ecom:Product:Stock.Text"); string stockDeliveryText = GetString("Ecom:Product:Stock.DeliveryText"); var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); bool isB2B = currentUser.IsB2B(); string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "stock-icon--in" : "stock-icon--not"; //Boolean hasVariants = GetLoop("VariantGroups").Any() ? true : false; string pageId = GetGlobalValue("Global:Page.ID").ToString(); string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); string productId = GetString("Ecom:Product.ID"); string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; <div class="product__stock-delivery js-handlebars-root dw-mod" id="StockAndShipping" data-template="StockAndShippingTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div> //if (!onlyPreview && !isB2B) //{ @*<div class="product__stock-delivery dw-mod"> @if (!hideStockState) { <div> <label for="StockInfo"><i class="fal fa-box-check fa-1_5x productIconsInteraction @stockIcon u-no-margin dw-mod tooltip-icon" data-tooltip='@stockText'></i></label> </div> } </div>*@ //} } @helper RenderShortDescription() { if (!String.IsNullOrEmpty(GetString("Ecom:Product.ShortDescription"))) { <div class="introduction-text"> @GetString("Ecom:Product.ShortDescription") </div> } } @helper RenderMainInfoVariants() { string pageId = GetGlobalValue("Global:Page.ID").ToString(); string productId = GetString("Ecom:Product.ID"); string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : ""; string hideHelpText = ""; foreach (LoopItem variantgroup in GetLoop("VariantGroups")) { foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) { if (variantoption.GetBoolean("Ecom:VariantOption.Selected")) { hideHelpText = "u-hidden"; } } } if (GetLoop("VariantGroups").Count > 0) { var variantCombinationsObject = new List<Array>(); foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) { string[] combinations = variantcomb.GetString("Ecom:VariantStockCombination.VariantID").Split('.'); variantCombinationsObject.Add(combinations); } string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'"); var variantGroupsObject = new List<List<String>>(); foreach (LoopItem variantGroup in GetLoop("VariantGroups")) { var variantsObject = new List<String>(); foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) { variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID")); } variantGroupsObject.Add(variantsObject); } string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'"); <div> <div class="js-variants" data-total-variant-groups="@GetLoop("VariantGroups").Count" data-combinations="@combinationsJson" data-variants="@variantsJson" data-variant-selections="@variantSelection" data-selection-complete="UpdatePage" data-page-id="@pageId" data-product-id="@productId"> @foreach (LoopItem variantGroup in GetLoop("VariantGroups")) { string groupId = variantGroup.GetString("Ecom:VariantGroup.ID"); <div> <div class="u-bold">@variantGroup.GetString("Ecom:VariantGroup.Name")</div> <div> @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) { string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; if (!string.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean"))) { string variantImage = "/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/" + variantOption.GetString("Ecom: VariantOption.ImgSmall.Clean"); <img data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" src="@variantImage" onclick="MatchVariants.SelectThis(event)" alt="@variantOption.GetString("Ecom:VariantOption.Name")" title="@variantOption.GetString("Ecom:VariantOption.Name")" class="btn btn--tag @selected js-variant-option" data-check="@selected" /> } else { <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag @selected js-variant-option" data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</button> } } </div> </div> } </div> <small class="js-help-text help-text @hideHelpText">@Translate("Please select variant!")</small> </div> } } @helper RenderMainInfoBOM() { if (GetLoop("BOMProducts").Count > 0) { <h2 class="section-title">@Translate("Including products")</h2> foreach (LoopItem BOMProductItem in GetLoop("BOMProducts")) { string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : ""); <div class="grid__col--border grid"> <div class="grid__cell grid__cell--align-middle-left"> <a href="@link" class="u-pull--left u-margin-right"> <img src="/Admin/Public/GetImage.ashx?width=50&image=@BOMProductItem.GetString("Ecom:Product.ImageDefault.Default.Clean")&Compression=99" alt="@BOMProductItem.GetString("Ecom:Product.Name")" /> </a> <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a> </div> </div> } } } @helper RenderMainInfoPrice() { string pageId = GetGlobalValue("Global:Page.ID").ToString(); string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); string productId = GetString("Ecom:Product.ID"); string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; <div class="product__price-actions js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div> <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" /> } @helper RenderMainInfoBuy() { string pageId = GetGlobalValue("Global:Page.ID").ToString(); string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); string productId = GetString("Ecom:Product.ID"); string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; <div class="product__price-actions js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div> <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" /> } @helper RenderMainInfoIcons() { string pageId = GetGlobalValue("Global:Page.ID").ToString(); string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); string productId = GetString("Ecom:Product.ID"); string productLink = pageId + "&ProductID=" + productId + "&VariantID=" + variantId; <div id="product-detail-icons" class="product-detail-icons"> @RenderFavoritesLink() @RenderCompareLink(productId, variantId, productLink) @RenderShare() @RenderMainInfoNotifyBackInStock() @RenderStockAndShipping() </div> } @* Handlebars templates *@ <script id="PricesAndActionsTemplate" type="text/x-template"> {{#.}} @if (!mainInfoOnlyPreview) { <div class="product__price-actions__price dw-mod u-margin-bottom--lg"> {{#if hasDiscount}} <span class="before-price dw-mod">{{listPrice}}</span> <span class="price price--product-page dw-mod">{{price}}</span> {{else}} <span class="price price--product-page dw-mod">{{price}}</span> {{/if}} </div> <div class="buttons-collection buttons-collection--right product__price-actions__actions dw-mod"> {{#if unitOptions}} <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" /> <div class="dropdown u-w150px u-w80px--xs dw-mod {{hasUnits}}"> <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label> <div id="unitOptions" class="dropdown__content dw-mod"> {{#unitOptions}} {{>UnitOption}} {{/unitOptions}} </div> <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label> </div> {{else}} <div class="u-w150px u-w80px--xs dw-mod"> {{#if isB2B}} <span class="stock-information" > {{stock}} {{unitName}} <i class="fal fa-info-circle tooltip-icon"></i> <div class="stock-warehouses-container" id="stock-warehouses-{{variantid}}" style="display:none"> {{#if Warehouses}} <ul class="stock-warehouses__list"> {{#Warehouses}} <li class="stock-warehouses__warehouse">{{name}} : {{stock}}</li> {{/Warehouses}} </ul> {{/if}} {{#if deliveryDate}} <div>@Translate("Next delivery date"): {{deliveryDate}}</div> <div>@Translate("Next delivery quantity"): {{deliveryQuantity}}</div> {{/if}} </div> </span> {{else}} <span class="stock-information">{{unitName}}</span> {{/if}} </div> {{/if}} <input type="hidden" value="{{unitId}}" name="Unit" id="Unit_{{id}}" /> {{#if useMultiplier}} <input type="number" class="u-w70px" id="Quantity_{{id}}" name="Quantity" value="{{packageQuantity}}" min="{{packageQuantity}}" step="{{packageQuantity}}" data-multiplier="{{packageQuantity}}" data-message="{{multiplierMessage}}" data-maximum-available="{{multiplierMaximumAvailable}}"> {{else}} <input type="number" class="u-w70px" id="Quantity_{{id}}" name="Quantity" value="{{packageQuantity}}" min="{{packageQuantity}}" step="{{packageQuantity}}"> {{/if}} <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit" onclick="Cart.AddToCart(event, { id: '{{productId}}', unitId: '{{unitId}}', variantId: '{{variantid}}', quantity: document.getElementById('Quantity_{{id}}').value, productInfo: {{productInfo}} });"> <i class="@mainInfoCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> </button> </div> if (Pageview.User != null && Dynamicweb.Security.Licensing.LicenseManager.LicenseHasFeature("LoyaltyPoints")) { <text> {{#if canBePurchasedWithPoints}} <form method="post" role="form" class="u-no-margin u-margin-top"> <input type="hidden" name="ProductID" value="{{id}}" /> <button type="submit" onclick="UpdateCart();" class="btn btn--loyalty-points u-no-margin dw-mod pull-right u-no-margin" name="CartCmd" value="addWithPoints">@Translate("Buy for") {{points}} @Translate("points")</button> </form> {{/if}} </text> } } else { <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> } <span itemscope itemtype="http://schema.org/Product" class="microdata"> <meta itemprop="image" content="test.png"> <meta itemprop="name" content="{{name}}"> <meta itemprop="description" content="{{description}}"> <span itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <meta itemprop="price" content="{{price}}"> <meta itemprop="priceCurrency" content="USD"> </span> </span> {{/.}} </script> <script id="Units" type="text/x-template"> <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@mainInfoFeedId&UnitID={{value}}')">{{name}}</div> </script> <script id="UnitOption" type="text/x-template"> <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{name}}</div> </script> <script id="StockAndShippingTemplate" type="text/x-template"> {{#.}} @if (!mainInfoOnlyPreview) { string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "stock-icon--in" : "stock-icon--not"; <text> {{#unless isB2B}} {{#unless Combinations}} <div> <label for="StockInfo"><i class="fal fa-box-check fa-1_5x productIconsInteraction @stockIcon u-no-margin dw-mod tooltip-icon" data-tooltip='{{stockText}}'></i></label> </div> {{/unless}} {{/unless}} </text> } {{/.}} </script> <script> document.addEventListener("DOMContentLoaded", function () { if (document.getElementById("PriceAndActions")) { document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) { if (document.querySelector(".js-variants") != null) { MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing"); } }); } }); </script> @if (useGoogleTagManager) { var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); <script> // Measure a view of product details. This example assumes the detail view occurs on pageload, // and also tracks a standard pageview of the details page. dataLayer.push({ 'ecommerce': { 'detail': { 'actionField': {}, // 'detail' actions have an optional list property. 'products': [{ 'name': '@GetString("Ecom:Product.Name")', // Name or ID is required. 'id': '@GetString("Ecom:Product.ID")', 'price': '@(GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price"))', 'brand': '@GetString("Ecom:Product:Field.brand.Value")', 'category': '@(groupObject != null ? groupObject.Name : "")', 'variant': '@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))' }] } } }); </script> } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @functions { BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product"); } @{ string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section"; fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout; if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide") { Block detailsDescription = new Block() { Name = fullDesctiptionLayout != "MainInformation" ? Translate("Description") : "", Id = "FullDescription", SortId = 20, Template = RenderProductDescription(fullDesctiptionLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription); } } @helper RenderProductDescription(string layout) { string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="product__description center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Description")</h2> } @GetString("Ecom:Product.LongDescription") </div> </div> } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.IO; @using System.Web @using System.Globalization; @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @functions { BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product"); List<LoopItem> downloadDocuments = new List<LoopItem>(); DataTable getDownloadsList = new DataTable(); static string ConvertBytes(long bytes) { double size = bytes / 1024; //KB if (size > 1024) { size = (bytes / 1024f) / 1024f; //MB return string.Format("{0:n1} MB", size); } else { return string.Format("{0:n0} KB", size); } } static bool isImage(string path) { return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower()); } string getIconForFile(string fileName) { string ext = Path.GetExtension(fileName); string icon = ""; switch (ext.ToLower()) { case ".xls": case ".xlsx": icon = "fa-file-excel"; break; case ".ppt": case ".pptx": icon = "fa-file-powerpoint"; break; case ".doc": case ".docx": icon = "fa-file-word"; break; case ".dwg": icon = "fa-file-image"; break; case ".jpg": case ".jpeg": case ".png": case ".gif": case ".pdf": return "<img class='product__document-img' alt='" + fileName + "' src='/Admin/Public/GetImage.ashx?crop=5&height=70&width=120&Compression=75&DoNotUpscale=true&image=" + fileName + "' />"; default: icon = "fa-file"; break; } return "<i class='product__document-icon far " + icon + "'></i> "; } } @{ string downloadsProductID = GetString("Ecom:Product.ID"); string sqlDownloadsList = string.Format("SELECT Distinct FileTitle,[File], Category FROM [dbo].[ItemType_Download_Element] WHERE ( [Products] = 'p_{0}' OR [Products] Like '%p_{0}:%' OR [Products] Like '%p_{0},%') Order by Sort, FileTitle ASC", downloadsProductID); DataTable downloadsList = Database.CreateDataTable(sqlDownloadsList); getDownloadsList = downloadsList; foreach (LoopItem customField in GetLoop("CustomFieldValues")) { if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "Custom sticker") { if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) { downloadDocuments.Add(customField); } } } foreach (LoopItem customField in GetLoop("ProductCategories")) { foreach (LoopItem field in customField.GetLoop("ProductCategoryFields").Where(x=>x.GetString("Ecom:Product.Category.ID") == GetString("Ecom:Group.Category.ID"))) { if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value"))) { if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") { downloadDocuments.Add(field); } } } } string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section"; detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout; string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section"; categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout; string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section"; downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout; Boolean hasVariants = GetLoop("VariantGroups").Any() ? true : false; if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide") { Block detailsCustom = new Block() { Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "", Id = "CustomFields", SortId = 30, Template = RenderCustomData(detailFieldsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productFieldsPage.Add(detailFieldsLayout, detailsCustom); } if (categoryFieldsLayout != "hide") { foreach (LoopItem categoryGroup in GetLoop("ProductCategories")) { bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null; if (hasFields) { Block detailsCategoryFields = new Block() { Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "", Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")), SortId = 40, Template = RenderProductCategory(categoryGroup.GetString("Ecom:Product.Category.Name"), categoryGroup, categoryFieldsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields); } } } if (!hasVariants && categoryFieldsLayout != "hide") { Block unitInformation = new Block() { Name = categoryFieldsLayout != "MainInformation" ? Translate("Unit information") : "", Id = "UnitInformation", SortId = 41, Template = RenderUnitData(categoryFieldsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productFieldsPage.Add(categoryFieldsLayout, unitInformation); } if ((downloadDocuments.Count > 0 || getDownloadsList.Rows.Count > 0) && downloadsFieldsLayout != "hide") { Block detailsDownloads = new Block() { Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "", Id = "Downloads", SortId = 50, Template = RenderProductDownloads(downloadsFieldsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads); } } @helper RenderCustomData(string layout) { string viewType = Pageview.AreaSettings.GetItem("ProductPage").GetString("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid"; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Information")</h2> } @if (viewType != "table") { <div class="grid grid--external-bleed-x u-margin-bottom--lg"> @RenderCustomFields(GetLoop("CustomFieldValues"), viewType) </div> } else { string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; <div class="grid grid--external-bleed-x u-margin-bottom--lg"> <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table table-responsive"> <table class="table--no-top-border"> @RenderCustomFields(GetLoop("CustomFieldValues"), viewType) </table> </div> </div> } </div> </div> } @helper RenderUnitData(string layout) { string viewType = Pageview.AreaSettings.GetItem("ProductPage").GetString("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid"; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Unit information")</h2> } @if (viewType != "table") { <div class="grid grid--external-bleed-x u-margin-bottom--lg"> @RenderUnitRelatedInformation(viewType) </div> } else { string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; <div class="grid grid--external-bleed-x u-margin-bottom--lg"> <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> <table class="table--top-border table table-responsive"> @RenderUnitRelatedInformation(viewType) </table> </div> </div> } </div> </div> } @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType) { foreach (LoopItem customField in fieldsLoop) { string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; if (customField.GetLoop("Product.CustomField.Options").Count > 0) { fieldValue = customField.GetString("Product.CustomField.Label"); } if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker") { if (string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) { @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType); } } } } @helper RenderProductCategory(string name, LoopItem categoryGroup, string layout) { string viewType = Pageview.AreaSettings.GetItem("ProductPage").GetString("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid"; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@name</h2> } @if (viewType != "table") { <div class="grid grid--external-bleed-x u-margin-bottom--lg"> @RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), viewType) </div> } else { string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; <div class="grid grid--external-bleed-x u-margin-bottom--lg"> <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> <table class="table--top-border table table-responsive"> @RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), viewType) </table> </div> </div> } </div> </div> } @helper RenderUnitRelatedInformation(string viewType) { Boolean hasVariants = GetLoop("VariantGroups").Any() ? true : false; //adding unit information string defaultUnitID = GetString("Ecom:Product.DefaultUnitID"); var variantService = new Dynamicweb.Ecommerce.VariantOptionService(); string productLanguageID = GetString("Ecom:Product.LanguageID"); var defaultUnit = variantService.GetVariantOption(defaultUnitID,productLanguageID); string defaultUnitName = defaultUnit != null ? defaultUnit.Name : "KS"; //package quantity string packageQuantity = GetString("Ecom:Product:Field.PackageQuantity.Value") != "" ? GetString("Ecom:Product:Field.PackageQuantity.Value") : "1"; string packageCode = GetString("Ecom:Product:Field.PackageCode.Value"); if(!hasVariants){ <text>@RenderFieldItem(Translate("Unit"), packageQuantity.Replace(",00","") + " " + defaultUnitName, viewType)</text> } } @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType) { foreach (LoopItem categoryField in fieldsLoop) { string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value"); fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue)) { if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9") { if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15") { @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType,"split"); } else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8") { @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link"); } else { @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType); } } } } } @helper RenderProductDownloads(string layout) { string viewType = Pageview.AreaSettings.GetItem("ProductPage").GetString("DownloadsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsView").SelectedValue : "grid"; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Downloads")</h2> } @if (viewType != "table") { <div class="grid grid--external-bleed-x u-margin-bottom--lg"> @RenderProductDownloadsFields(downloadDocuments, viewType) @RenderProductDownloadsFieldsCustom(getDownloadsList, viewType) </div> } else { string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; <div class="grid grid--external-bleed-x u-margin-bottom--lg"> <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> <table class="table--no-top-border table table-responsive"> @RenderProductDownloadsFields(downloadDocuments, viewType) @RenderProductDownloadsFieldsCustom(getDownloadsList, viewType) </table> </div> </div> } </div> </div> } @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType) { foreach (LoopItem document in fieldsLoop) { string fieldValue; if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) { fieldValue = document.GetString("Product.CustomField.Value.Clean"); @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download") } if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") { fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); @RenderFieldItem(fieldValue, fieldValue, viewType, "download") } } } @helper RenderProductDownloadsFieldsCustom(DataTable downloadsList, string viewType) { if(downloadsList != null){ foreach(DataRow detailDownload in downloadsList.Rows){ var downloadFile = detailDownload["File"].ToString(); var downloadFileTitle = detailDownload["FileTitle"].ToString(); var downloadFileCategory = Translate("DownloadCategory" + detailDownload["Category"].ToString()); FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(downloadFile)); if (!string.IsNullOrEmpty(downloadFile) && info.Exists) { @RenderFieldItem(downloadFileTitle, downloadFile, viewType, "download", downloadFileCategory) } } } } @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean", string category="") { if (viewType != "table") { string fieldColumns = viewType == "list" ? "12" : "4"; <div class="grid__col-md-@fieldColumns u-margin-bottom"> @*<div class="u-bold"> @name </div>*@ <div> @RenderFieldItemContent(name, value, fieldType,category) </div> </div> } else { <tr> @if (fieldType == "download") { <td colspan="2"> @RenderFieldItemContent(name, value, fieldType,category) </td> } else { <td class="u-bold" width="30%">@name</td> <td> @RenderFieldItemContent(name, value, fieldType,category) </td> } </tr> } } @helper RenderFieldItemContent(string name, string value, string fieldType = "clean", string category="") { if (fieldType == "link") { <a target="_blank" href="@value"> @if (isImage(value)) { @getIconForFile(value) } else { @value } </a> } else if (fieldType == "download") { //value ="/Files/DigitalAssets/Downloads/ALLMEDIA okna a fasády_SK2017_web.pdf"; FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value)); if (info.Exists) { string downloadLink = "/Admin/Public/Download.aspx?ForceDownload=true&File=" + value; <div class="grid grid--no-wrap"> <a href="@downloadLink" download title="@Translate("Download")" alt="@Path.GetFileName(value)" class="product__document u-min-w120px u-ta-center dw-mod">@getIconForFile(value)</a> <div class="product__document-info dw-mod"> @*<a href="@name" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a>*@ <a href="@downloadLink" download title="@Translate("Download")" class="product__document dw-mod">@name</a> <p>@category</p> <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small> </div> </div> } } else if (fieldType == "split") { @value.Replace(",",", ").Replace(" "," ") } else{ @value } } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Data @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @using Dynamicweb.Data @functions{ BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product"); } @{ string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetString("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section"; videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout; string productID = GetString("Ecom:Product.ID"); string sqlVideoList = string.Format("SELECT Distinct VideoTitle,VideoLink,VideoDescription FROM [dbo].[ItemType_Video_Element] WHERE [ProductID] = N'{0}'", productID); DataTable getVideoList = Database.CreateDataTable(sqlVideoList); int videosCount = 0; foreach(var videoItem in getVideoList.Rows){ videosCount++; } foreach (LoopItem detailField in GetLoop("Details")) { if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1) { videosCount++; } if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) { videosCount++; } } if (videosCount > 0 && videosLayout != "hide") { Block detailsVideos = new Block() { Name = videosLayout != "MainInformation" ? Translate("Videos") : "", Id = "Videos", SortId = 60, Template = ProductVideos(videosCount, videosLayout,getVideoList), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productVideoPage.Add(videosLayout, detailsVideos); } } @helper ProductVideos(int videosCount, string layout, DataTable videoList) { string videoColumn = "12"; videoColumn = videosCount == 2 ? "6" : videoColumn; videoColumn = videosCount > 2 ? "4" : videoColumn; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Videos")</h2> } <div class="grid grid--external-bleed-x u-margin-bottom--lg"> @foreach (LoopItem detailField in GetLoop("Details")) { if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1 || detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) { <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> <div class="video-wrapper"> @detailField.GetString("Ecom:Product:Detail.Text") </div> </div> } } @if(videoList != null){ foreach(DataRow detailVideo in videoList.Rows){ var video = detailVideo["VideoLink"]; var videoTitle = detailVideo["VideoTitle"]; var videoDescription = detailVideo["VideoDescription"]; string videoEmbedCode = string.Format("<iframe width=\"560\" height=\"315\" src=\"{0}\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe>",video); <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> <h4>@videoTitle</h4> <div class="video-wrapper"> @videoEmbedCode </div> <p>@videoDescription</p> </div> } } </div> </div> </div> } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @functions{ BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product"); } @{ string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section"; relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout; string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetString("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; string gridViewColumns = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("Columns") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetList("Columns").SelectedValue : "4"; bool gridViewShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ShowStockAndShipping") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping") : true; bool relatedOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; bool relatedViewShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ShowAddToCartButton") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton") : true; bool relatedViewShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ShowViewButton") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton") : true; string cartButtonText = Converter.ToInt32(gridViewColumns) >= 4 ? Translate("Add to cart") : ""; string relatedViewMoreText = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View"; string viewMoreText = Translate("gridViewMoreText"); int relatedProductsPageSize = 4; int relatedProductsColumnWidth = 3; if (Pageview.Device.ToString() == "Mobile") { relatedProductsPageSize = 1; relatedProductsColumnWidth = 12; } if (Pageview.Device.ToString() == "Tablet") { relatedProductsPageSize = 3; relatedProductsColumnWidth = 4; } if (relatedProductsLayout != "hide") { foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups")) { string relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name")); string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID") + "&GroupName=" + relatedGroupId; string relatedGroupName = Translate("Related products");//relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : ""; Block detailsRelated = new Block() { Name = relatedGroupName, Id = relatedGroupId, SortId = 70, Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productRelatedPage.Add(relatedProductsLayout, detailsRelated); } } } @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout) { string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate(@name)</h2> @* Mi edit *@ } <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div> </div> </div> } @helper RenderRelatedProductsMini(string name, string groupId, string relatedFeedUrl) { <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainerMini" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div> } @* Script templates for related products *@ <script id="ProductPreRenderContainer" type="text/x-template"> <div class="u-h600px u-full-width"> <div class="grid"> <div class="grid__col-12"> <div class="pre-render-element pre-render-element--md"></div> </div> </div> </div> </script> <script id="ProductContainer" type="text/x-template"> {{#.}} <div class="u-min-h400px u-full-width"> <div class="grid"> <div class="grid__col-45px grid__col--bleed-x"> <div class="grid__cell grid__cell--align-middle-left"> <button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fas fa-chevron-left fa-2x"></i></button> </div> </div> <div class="grid__col-auto grid__col--bleed-x"> <div id="ProductsContainer" data-template="ProductGridItemContainer" class="grid product-list dw-mod" data-save-cookie="true"> {{#ProductsContainer}} <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item dw-mod"> {{#Product}} @if (useGoogleTagManager) { <text>{{{googleEnchantImpression 'Related products' currency googleImpression}}}</text> } <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> <div class="stickers-container dw-mod"> {{#Stickers}} {{>Sticker}} {{/Stickers}} </div> <a href="{{link}}" onclick="Scroll.SavePosition(event)"> <img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;fillcanvas=true&amp;image={{image}}" alt="{{name}}" /> </a> </div> <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}"><h6 class="u-condensed-text">{{name}}</h6></a> {{#if showProductNumber}} <div class="item-number dw-mod">{{number}}</div> {{/if}} @if (!relatedOnlyPreview) { <text> {{#if hasVariants}} {{#if hasDiscount}} <span class="before-price before-price--micro dw-mod">{{listPrice}}</span> {{/if}} <span class="price price--product-list dw-mod">@Translate("startingFrom","Starting from ") {{price}}</span> {{else}} {{#if hasDiscount}} <span class="before-price before-price--micro dw-mod">{{listPrice}}</span> {{/if}} <span class="price price--product-list dw-mod">{{price}}</span> {{/if}} </text> } </div> <div class="product-list__grid-item__footer dw-mod"> {{#Favorite}} {{>FavoriteTemplate}} {{/Favorite}} <a class="addToCompare tooltip-icon" data-tooltip="@Translate("Add to compare")" data-add-compare='@Translate("Add to compare")' data-remove-compare='@Translate("Remove from compare")' data-url="{{link}}" data-variant-id="{{variantid}}" data-id="{{productId}}" data-code="{{number}}" data-img="/Admin/Public/GetImage.ashx?width=75&amp;height=75&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{image}}" data-name="{{name}}"><i class="fal fa-balance-scale fa-1_5x"></i></a> @if (!relatedOnlyPreview && gridViewShowStock) { <div> <span class="stock-icon2 fal fa-box-check fa-1_5x {{stockState}} u-no-margin dw-mod tooltip-icon" data-tooltip="{{stockText}}"></span> </div> } @if (!relatedOnlyPreview && relatedViewShowCartButton) { <div class="u-ta-center u-inline-block"> <div class="buttons-collection {{hideBuyOptions}}"> <button type="button" id="CartButton_{{id}}" class="js-cart-btn btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod {{disabledBuyButton}}" name="submit" onclick="Cart.AddToCart(event, { id: '{{productId}}', variantId: '{{variantid}}', unitId: '{{unitId}}', quantity: document.getElementById('Quantity_{{id}}').value, productInfo: {{productInfo}} }); {{facebookPixelAction}}" {{disabledBuyButton}}> <i class="@relatedCartIcon fa-1_5x"></i><span class="u-hidden-xs u-hidden-xxs"> @cartButtonText</span> </button> <input type="number" class="u-w80px u-pull--right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> </div> </div> if (relatedViewShowViewButton) { <div class="u-ta-center {{hideViewMore}}"> <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary btn--full u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@viewMoreText">@viewMoreText</a> </div> } } else if (relatedViewShowViewButton) { <div class="u-ta-center"> <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--primary btn--condensed grid-view-show-products u-no-margin dw-mod tooltip-icon" data-tooltip="@viewMoreText" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}"><i class="fal fa-shopping-cart fa-1_5x"></i></a> </div> } </div> {{/Product}} </div> {{/ProductsContainer}} </div> </div> <div class="grid__col-45px grid__col--bleed-x"> <div class="grid__cell grid__cell--align-middle-right"> <button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fas fa-chevron-right fa-2x"></i></button> </div> </div> </div> </div> {{/.}} </script> <script id="ProductContainerMini" type="text/x-template"> {{#.}} <div class="u-full-width"> <div class="grid"> <div class="grid__col-45px grid__col--bleed-x"> <div class="grid__cell grid__cell--align-middle-left"> <button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fas fa-chevron-left fa-2x"></i></button> </div> </div> <div class="grid__col-auto grid__col--bleed-x"> <div id="ProductsContainer" class="grid product-list dw-mod"> {{#ProductsContainer}} <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item dw-mod"> {{#Product}} @if (useGoogleTagManager) { <text>{{{googleEnchantImpression 'Related products' currency googleImpression}}}</text> } <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> <div class="stickers-container dw-mod"> {{#Stickers}} {{>Sticker}} {{/Stickers}} </div> <a href="{{link}}" onclick="Scroll.SavePosition(event)"><img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{name}}" /></a> </div> <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}"><h6 class="u-condensed-text">{{name}}</h6></a> {{#if showProductNumber}} <div class="item-number dw-mod">{{number}}</div> {{/if}} @if (!relatedOnlyPreview) { <div>{{price}}</div> <div class="before-price {{onSale}} dw-mod">{{discount}}</div> } </div> {{/Product}} </div> {{/ProductsContainer}} </div> </div> <div class="grid__col-45px grid__col--bleed-x"> <div class="grid__cell grid__cell--align-middle-right"> <button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fas fa-chevron-right fa-2x"></i></button> </div> </div> </div> </div> {{/.}} </script> <script id="Sticker" type="text/x-template"> <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> </script> @* Favorites templates *@ <script id="FavoriteTemplate" type="text/x-template"> <div class="favorites-list u-ta-left"> <label for="FavoriteTrigger_{{id}}" class="u-no-margin"><i class="{{favoriteIcon}} fa-1_5x"></i></label> <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> <div class="dropdown dropdown--absolute-position"> <div class="dropdown__content dropdown__content--show-left dw-mod"> <div class="modal-content-custom-favorites modal--md"> <span class="modal__header modal-header-rapido"> <h2>@Translate("Add to favorites")</h2> <i class="fas fa-times" data-trigger="FavoriteTrigger_{{id}}"></i> </span> <span class="modal-body-custom"> <h6> @Translate("Choose list") </h6> <div class="product-wrapper"> <img src="/Admin/Public/GetImage.ashx?width=50&amp;height=50&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{productImage}}" alt="productImage"> <h6 class="product-name">{{productName}}</h6> </div> {{#FavoriteLists}} {{>FavoriteListItem}} {{/FavoriteLists}} </span> </div> </div> <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> </div> </div> </script> <script id="FavoriteListItem" type="text/x-template"> <li> <a href="{{link}}" class="list__link u-no-underline dw-mod" onclick="{{facebookPixelAction}}"><i class="{{favoriteIcon}}"></i> {{name}}</a> </li> </script> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @functions { BlocksPage productVariantsPage = BlocksPage.GetBlockPage("Product"); } @{ bool renderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetString("RenderVariantsAsProductList") != null && GetInteger("Ecom:Product.VariantCount") > 1 ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList") : false; bool variantsOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") != null ? HttpContext.Current.Request.QueryString.Get("PageSize") : "30"; string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetString("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; string productLanguageID = GetString("Ecom:Product.LanguageID"); var username = GetGlobalValue("Global:Extranet.UserName"); string productPageID = GetString("Ecom:Product:Page.ID"); string cartPageLink = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("CartPage")); string createNotificationText = Translate("createnotification", "Create notification"); string createNotificationCreated = Translate("Notification created", "Notification created"); string createNotificationEmailLabel = Translate("Email", "Email"); bool isB2B = false; bool priceWithoutVAT = false; var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); if(currentUser != null){ string customerNumber = currentUser.CustomerNumber; isB2B = !string.IsNullOrEmpty(customerNumber) ? true : false; priceWithoutVAT = true; } //string createNotificationLink = "/default.aspx?id="+productPageID+"&productid="+productID+"&VariantID="+variantID+"&LanguageID="+productLanguageID+"&cartcmd=createnotificationforthisproduct"; string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetString("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section"; variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout; //string productPackageQuantity = !string.IsNullOrEmpty(GetString("Ecom:Product:Field.PackageQuantity.Value")) && Double.Parse(GetString("Ecom:Product:Field.PackageQuantity.Value")) > 1.0 ? "data-multiplier=\""+GetString("Ecom:Product:Field.PackageQuantity.Value")+"\"" : ""; if (renderVariantsAsProducts && variantsListLayout != "hide") { Block detailsVariantsList = new Block() { Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "", Id = "VariantsList", SortId = 10, Template = RenderVariantsProductList(variantsListLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productVariantsPage.Add(variantsListLayout, detailsVariantsList); } } @helper RenderVariantsProductList(string layout) { string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") != null ? HttpContext.Current.Request.QueryString.Get("PageSize") : "30"; string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true&SortBy=ProductNumber_Search&SortOrder=ASC"; string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate("Variants")</h2> } <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div> </div> </div> } @* Script templates for variant products *@ <script id="VariantProductsContainer" type="text/x-template"> {{#.}} <div class=""> <form name="multiForm" id="multiForm" method="post" novalidate> <input type="hidden" name="CartCmd" id="CartCmd" value="addMulti" /> <input type="hidden" name="ID" value="5" /> <table id="VariantsProductsContainer" class="table-responsive table u-position-relative dw-mod"> <colgroup> <col class="col-group-1"> <col class="col-group-2"> <col class="col-group-3"> <col class="col-group-4"> <col class="col-group-5"> <col class="col-group-6"> <col class="col-group-7"> <col class="col-group-8"> <col class="col-group-9"> </colgroup> <thead> <tr> <td width="80">&nbsp;</td> <td> @Translate("Product")</td> {{#AvailableCustomFields}} {{>TableFieldNameTemplate}} {{/AvailableCustomFields}} @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) { foreach (LoopItem variantgroup in GetLoop("VariantGroups")) { <td>@variantgroup.GetString("Ecom:VariantGroup.Label")</td> } } <td class="u-ta-center"> @Translate("Unit") </td> <td> <div class="grid grid--align-center grid--justify-end"> <div class="u-margin-right--lg"> @Translate("Price") @if(isB2B){ <br/> <span>(@Translate("excl. VAT"))</span> } </div> </div> </td> <td> <div class="grid grid--align-center grid--justify-center"> <div class="u-margin-right--lg"> @Translate("Stock") </div> </div> </td> <td width="220"> <!-- <input type="submit" id="multiAddButton" class="btn btn--primary btn--condensed u-no-margin dw-mod u-pull--right" value="@Translate("Add all to cart")" onClick="document.getElementById('multiForm').submit();"/> --> <input type="submit" id="multiAddButton" class="btn btn--primary btn--condensed u-no-margin dw-mod u-pull--right" value="@Translate("Add all to cart")" /> </td> </tr> </thead> <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true"> {{#ProductsContainer}} {{>VariantProductItemContainer}} {{/ProductsContainer}} </tbody> </table> </form> </div> <div class="grid"> <div class="grid__col-12 grid__col--bleed-y"> <button type="button" id="LoadMoreButton" class="btn btn--primary btn--full {{nextdisabled}} dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="VariantProductListContainer" data-feed-url="@variantsFeedUrl{{loadMoreFeedParams}}" onclick="LoadMore.Next(this)" {{nextdisabled}}>@Translate("Load") @Translate("more")</button> </div> </div> {{/.}} </script> <script id="VariantProductItemContainer" type="text/x-template"> {{#.}} <tr id="VariantProduct{{id}}" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}"> {{#Product}} {{>VariantProductItem}} {{/Product}} </tr> {{/.}} </script> <script id="VariantProductItem" type="text/x-template"> {{#.}} <td width="80"> <div class="lightbox u-hidden-xxs"> <!-- <a href="{{link}}" onclick="Scroll.SavePosition(event)"> --> <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&amp;height=220&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{name}}" /> <div class="u-margin-right {{noImage}}"> <img src="/Admin/Public/GetImage.ashx?width=75&amp;height=55&amp;crop=5&FillCanvas=true&amp;Compression=75&amp;image={{image}}" alt="{{name}}" /> </div> <!-- </a> --> </div> </td> <td class="u-va-middle"> <h6 class="u-no-margin">{{name}}</h6> <div class="item-number item-number--compressed dw-mod"> {{number}} </div> <div class="favorites u-margin-right {{hasVariants}} dw-mod" {{hasVariants}}> {{#Favorite}} {{>FavoriteTemplate}} {{/Favorite}} </div> {{#if outOfStock}} <div class="notifyParentIcon show-modal favorites--md "> {{#if notificationRegistered}} <i class="far fa-bell tooltip-icon fa-1_5x" data-tooltip="@createNotificationCreated"></i> {{else}} <i class="far fa-bell tooltip-icon fa-1_5x remindeMe" data-tooltip="@createNotificationText" data-id="{{id}}" data-variantId="{{variantid}}"></i> {{/if}} </div> {{/if}} </td> {{#CustomFields}} {{>TableFieldValueTemplate}} {{/CustomFields}} @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) { <text> {{#VariantSelectionNames}} {{>TableFieldNameTemplate}} {{/VariantSelectionNames}} </text> } <td class="u-va-middle u-ta-center"> <div class="u-margin-right"> <div> <p>{{packageQuantity}} {{unitName}}</p> </div> </div> </td> @if (variantsOnlyPreview) { <td colspan="3" class="u-va-middle"> <div class="u-hidden-sm"> <div class="u-full-width u-ta-right u-padding-right"> <div class="before-price {{onSale}} before-price--micro u-margin-right dw-mod">{{discount}}</div> <div class="price price--product-list price--micro dw-mod">{{price}}</div> </div> </div> </td> } else { <td class="u-va-middle"> <div class="grid grid--align-center grid--justify-end"> <div class="u-hidden-xs u-hidden-xxs"> {{#if hasDiscount}} <div class="before-price before-price--micro u-margin-right dw-mod">{{listPrice}}</div> <div class="price price--condensed price--product-list dw-mod">{{price}}</div> {{else}} <div class="price price--condensed price--product-list dw-mod">{{price}}</div> {{/if}} </div> </div> </td> <td class="u-va-middle u-ta-center"> @if (isB2B) { <span class="stock-information" > {{stock}} <i class="fal fa-info-circle tooltip-icon" ></i> <div class="stock-warehouses-container" id="stock-warehouses-{{variantid}}" style="display:none"> {{#if Warehouses}} <ul class="stock-warehouses__list"> {{#Warehouses}} <li class="stock-warehouses__warehouse">{{name}} : {{stock}}</li> {{/Warehouses}} </ul> {{/if}} {{#if deliveryDate}} <div>@Translate("Next delivery date"): {{deliveryDate}}</div> <div>@Translate("Next delivery quantity"): {{deliveryQuantity}}</div> {{/if}} </div> </span> } else { <span> <span class="fal fa-box-check productIconsInteraction {{stockState}} u-no-margin dw-mod tooltip-icon" title="{{stockText}}" data-tooltip="{{stockText}}"></span> </span> } </td> <td width="220" class="u-va-middle"> <div class="grid grid--align-center grid--justify-end"> <div> {{#if useMultiplier}} <input type="number" class="u-w80px u-no-margin u-margin-right" id="Quantity{{id}}" name="Quantity{{id}}" value="0" min="0" step="{{packageQuantity}}" data-multiplier="{{packageQuantity}}" data-message="{{multiplierMessage}}" data-maximum-available="{{multiplierMaximumAvailable}}"> {{else}} <input type="number" class="u-w80px u-no-margin u-margin-right" id="Quantity{{id}}" name="Quantity{{id}}" value="0" min="0" > {{/if}} </div> <div> <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod {{hasVariants}}" name="submit" onclick="Cart.AddToCart(event, { id: '{{productId}}', variantId: '{{variantid}}', unitId: '{{unitId}}', quantity: document.getElementById('Quantity{{id}}').value, productInfo: {{productInfo}} });" {{hasVariants}}> <i class="@variantsCartIcon"></i> </button> <!--fields for multi add--> <!-- data-counter attribute is used to get product data for multi add --> <input type="hidden" name="ProductLoopCounter{{id}}" id="ProductLoopCounter{{id}}" value="{{id}}" data-counter="counter"/> <input type="hidden" name="ProductID{{id}}" id="ProductID{{id}}" value="{{productId}}" /> <input type="hidden" name="VariantID{{id}}" id="VariantID{{id}}" value="{{variantid}}" /> <input type="hidden" name="UnitID{{id}}" id="UnitID{{id}}" value="{{unitId}}" /> <input type="hidden" name="Info{{id}}" id="Info{{id}}" data-info="{{productInfo}}"> </div> </div> </td> } {{/.}} </script> <script id="TableFieldNameTemplate" type="text/x-template"> <td class="u-va-middle u-ta-center">{{name}}</td> </script> <script id="TableFieldValueTemplate" type="text/x-template"> <td class="u-va-middle u-ta-center">{{value}}</td> </script> <script id="MiniSticker" type="text/x-template"> <div class="stickers-container__tag stickers-container__tag--micro {{className}} dw-mod">{{text}}</div> </script> <!-- modals used on multi add variants --> <div id="allProductsAddedModal"> <div class="modal-overlay-custom u-hidden"> <div class="modal-content-custom modal--md"> <span class="modal-header-custom"> <h2>@Translate("Products are added to the cart")</h2> <i class="fas fa-times"></i> </span> <span class="modal-body-custom" ></span> <span class="modal-footer-custom"> <label class="btn btn--secondary u-pull--left u-no-margin dw-mod btn--sm">@Translate("Continue shopping")</label> <a href="@cartPageLink" class="btn btn--primary u-pull--right u-no-margin dw-mod btn--sm">@Translate("Proceed to checkout")</a> </span> </div> </div> </div> <!-- modals used on notify me when back in stock --> <div class="notifyDialog "> <div class="modal-overlay-custom u-hidden"> <div class="modal-content-custom"> <span class="modal-header-custom"> <h2>@Translate("getNotification", "Find out when product is back on stock")</h2> <i class="fas fa-times"></i> </span> <div class="modal-body-custom"> <div class="grid__cell"> <form name="" id="" method="post" class="u-margin-auto grid__col-auto-width" action="/Default.aspx?ID=@productPageID"> <input type="hidden" name="ProductID" id="NotificationProductID" value="@productID" /> <input type="hidden" name="VariantID" id="NotificationVariantID" value="" /> <input type="hidden" name="LanguageID" id="NotificationLanguageID" value="@productLanguageID" /> <input type="hidden" name="CartCmd" id="CartCmd" value="createnotificationforthisproduct" /> <label for="NotificationEmail">@createNotificationEmailLabel</label> <input type="email" required="required" id="NotificationEmail" name="NotificationEmail" value=""/> <input type="submit" value="@createNotificationText" class="btn btn--primary btn--condensed u-no-margin dw-mod"/> </form> </div> </div> </div> </div> </div> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Core @using System @using System.Web @using System.Collections.Generic @using Dynamicweb.Rapido.Blocks @{ BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product"); //string alsoBoughtProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section"; //alsoBoughtProductsLayout = alsoBoughtLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : alsoBoughtProductsLayout; //bool relatedOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; //int relatedProductsPageSize = 4; //int relatedProductsColumnWidth = 3; //if (Pageview.Device.ToString() == "Mobile") //{ //relatedProductsPageSize = 1; //relatedProductsColumnWidth = 12; //} //if (Pageview.Device.ToString() == "Tablet") //{ //relatedProductsPageSize = 3; //relatedProductsColumnWidth = 4; //} if (relatedProductsLayout != "hide") { string relatedGroupId = "1"; string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID") + "&GroupName=" + relatedGroupId; Block detailsAlsoBought = new Block() { Name = Translate("Other customers also bought"), Id = "detailsAlsoBought", SortId = 70, Template = RenderCustomersAlsoBought(Translate("Other customers also bought"),relatedFeed, relatedProductsLayout), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productRelatedPage.Add(relatedProductsLayout, detailsAlsoBought); } Block relatedArticles = new Block() { Name = Translate("Related articles"), Id = "relatedArticles", SortId = 70, Template = RenderRelatedArticles(GetString("Ecom:Product.ID")), Design = new Design { Size = "12", RenderType = RenderType.Column, HidePadding = true } }; productRelatedPage.Add(relatedProductsLayout, relatedArticles); } @helper RenderCustomersAlsoBought(string name, string relatedFeedUrl, string layout){ string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; string groupId = "alsobought"; <div class="product__section @ribbonClasses dw-mod"> <div class="center-container @ribbonSubClasses dw-mod"> @if (layout == "Section") { <h2>@Translate(@name)</h2> @* Mi edit *@ } <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div> </div> </div> } @helper RenderRelatedArticles(string productId) { var article_filter = "Related_Products contains 'p_" + productId + "'"; int currentArea = Pageview.Area.ID; //News Articles @RenderItemList(new { ItemType = "NewsArticle", ListSourceType = "Area", ListSourceArea = @currentArea.ToString(), ItemFieldsList = "*", ListTemplate = "ItemPublisher/List/RelatedArticles.cshtml", ListPageSize = 20, IncludeParagraphItems = "True", ListOrderBy = "Title", Filter = @article_filter }) //Blog Articles @RenderItemList(new { ItemType = "BlogArticle", ListSourceType = "Area", ListSourceArea = @currentArea.ToString(), ItemFieldsList = "*", ListTemplate = "ItemPublisher/List/RelatedArticles.cshtml", ListPageSize = 20, IncludeParagraphItems = "True", ListOrderBy = "Title", Filter = @article_filter }) } <div class="product__info dw-mod u-margin-bottom--lg js-product"> <div class="grid grid--align-content-start"> @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ @RenderBlockList(productsPage.BlocksRoot.BlocksList) </div> </div> @helper RenderProductMiniTabs() { List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList(); if (subBlocks.Count > 0) { <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod"> @{ bool firstTab = true; foreach (Block item in subBlocks) { string isChecked = firstTab ? "checked" : ""; firstTab = false; <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> } } <div class="tabs__list dw-mod"> @foreach (Block item in subBlocks) { <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> } </div> <div class="tabs__blocks dw-mod"> @foreach (Block item in subBlocks) { string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; if (item.Design.RenderType != RenderType.Hide) { <div class="tabs__block u-border dw-mod" id="Block__@item.Id"> <block class="product__block paragraph-container product__block--bordered dw-mod"> <div class="center-container u-padding--lg dw-mod"> @RenderBlock(item) </div> </block> </div> } } </div> </div> } } @helper RenderProductTabs() { List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList(); <div class="grid__col-12 product__info tabs u-no-padding dw-mod"> @{ bool firstTab = true; foreach (Block item in subBlocks) { string isChecked = firstTab ? "checked" : ""; firstTab = false; <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> } } <div class="tabs__list dw-mod"> @foreach (Block item in subBlocks) { <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> } </div> <div class="tabs__blocks dw-mod"> @foreach (Block item in subBlocks) { string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; if (item.Design.RenderType != RenderType.Hide) { <div class="tabs__block dw-mod" id="Block__@item.Id"> <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod"> <div class="center-container u-padding--lg dw-mod"> @RenderBlock(item) </div> </section> </div> } } </div> </div> }