v2.5 add small product image to Recently Viewed Products

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 years ago
Just had to do this and as there was a question about how to do this for 1.9 I thought I'd chuck the code up here for 2.5.

File: RecentlyViewedProductBlock.cshtml

add line
<img alt="@Model[i].DefaultPictureModel.AlternateText" src="@Model[i].DefaultPictureModel.ImageUrl" title="@Model[i].DefaultPictureModel.Title" />


like so;-

@model IList<Nop.Web.Models.Catalog.ProductModel>
@using Nop.Core;
@using Nop.Core.Infrastructure;
@using Nop.Web.Framework.UI;
@using Nop.Web.Models.Catalog;
@if (Model.Count > 0)
{
    <div class="block block-recently-viewed-products">
        <div class="title">
            @T("Products.RecentlyViewedProducts")
        </div>
        <div class="clear">
        </div>
        <div class="listbox">
            <ul>
                @for (int i = 0; i < Model.Count; i++)
                {
                    var product = Model[i];
                    
                    <li>
                        <img alt="@Model[i].DefaultPictureModel.AlternateText" src="@Model[i].DefaultPictureModel.ImageUrl" title="@Model[i].DefaultPictureModel.Title" />
                        <a href="@Url.RouteUrl("Product", new { productId = product.Id, SeName = product.SeName })">@product.Name</a>
                    </li>
                    if (i != Model.Count - 1)
                    {
                        <li class="separator">&nbsp;</li>
                    }
                }
            </ul>
        </div>
    </div>
}


File: CatalogController.cs

change line from
model.Add(PrepareProductOverviewModel(product, false, false, productThumbPictureSize));


to

model.Add(PrepareProductOverviewModel(product, false, true, 50));


essentially we need to tell the model to prepare the picture model and we set the thmbnail size to 50 instead of using the setting.

full code for method.

[ChildActionOnly]
        public ActionResult RecentlyViewedProductsBlock(int? productThumbPictureSize)
        {
            var model = new List<ProductModel>();
            if (_catalogSettings.RecentlyViewedProductsEnabled)
            {
                var products = _recentlyViewedProductsService.GetRecentlyViewedProducts(_catalogSettings.RecentlyViewedProductsNumber);
                foreach (var product in products)
                {
                    // DMB 19/04/2012 changed to get pictures displaying and fixed thumb size
                    //model.Add(PrepareProductOverviewModel(product, false, false, productThumbPictureSize));
                    model.Add(PrepareProductOverviewModel(product, false, true, 50));
                }
            }
            return PartialView(model);
        }


That's it

HTH

Dave
11 years ago
Hi Dave,

I am using 2.4 and i am not getting any images.

http://www.shop.tikisurf.co.uk/

any ideas?

Thanks
Mike
11 years ago
Hi Mike,

Bit busy atm but when I get a moment I'll fire up a copy of 2.4 and see what gives :)

Dave
11 years ago
sorry not going to get to it today
11 years ago
no worries just let me know when you can.

thanks
11 years ago
file locations are

Presentation\Nop.Web\Views\Catalog\RecentlyViewedProductsBlock.cshtml

Presentation\Nop.Web\Controllers\CatalogController.cs

there is another catalogcontroler in the admin side - don't add the code there

Other than that I just made the changes to 2.4 and it worked.
11 years ago
thats what i have changed

Recently view block page

@model IList<Nop.Web.Models.Catalog.ProductModel>
@using Nop.Core;
@using Nop.Core.Infrastructure;
@using Nop.Web.Framework.UI;
@using Nop.Web.Models.Catalog;
@if (Model.Count > 0)
{
    <div class="block block-recently-viewed-products">
        <div class="title">
            @T("Products.RecentlyViewedProducts")
        </div>
        <div class="clear">
        </div>
        <div class="listbox">
            <ul>
                @for (int i = 0; i < Model.Count; i++)
                {
                    var product = Model[i];
                    <li style="line-height:16px;">
          <img alt="@Model[i].DefaultPictureModel.AlternateText" src="@Model[i].DefaultPictureModel.ImageUrl" title="@Model[i].DefaultPictureModel.Title" />
          <a href="@Url.RouteUrl("Product", new { productId = product.Id, SeName = product.SeName })">@product.Name</a>
                    </li>
                    if (i != Model.Count - 1)
                    {
                        <li class="separator">&nbsp;</li>
                    }
                }
            </ul>
        </div>
    </div>
}

Catalogcontroller


using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.Orders;
using Nop.Services.Catalog;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Media;
using Nop.Services.Messages;
using Nop.Services.Orders;
using Nop.Services.Security;
using Nop.Services.Seo;
using Nop.Services.Tax;
using Nop.Web.Extensions;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Infrastructure.Cache;
using Nop.Web.Models.Catalog;
using Nop.Web.Models.Media;

namespace Nop.Web.Controllers
{
    public class CatalogController : BaseNopController
    {
    #region Fields

        private readonly ICategoryService _categoryService;
        private readonly IManufacturerService _manufacturerService;
        private readonly IProductService _productService;
        private readonly IProductTemplateService _productTemplateService;
        private readonly ICategoryTemplateService _categoryTemplateService;
        private readonly IManufacturerTemplateService _manufacturerTemplateService;
        private readonly IProductAttributeService _productAttributeService;
        private readonly IProductAttributeParser _productAttributeParser;
        private readonly IWorkContext _workContext;
        private readonly ITaxService _taxService;
        private readonly ICurrencyService _currencyService;
        private readonly IPictureService _pictureService;
        private readonly ILocalizationService _localizationService;
        private readonly IPriceCalculationService _priceCalculationService;
        private readonly IPriceFormatter _priceFormatter;
        private readonly IWebHelper _webHelper;
        private readonly ISpecificationAttributeService _specificationAttributeService;
        private readonly ICustomerContentService _customerContentService;
        private readonly IDateTimeHelper _dateTimeHelper;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IRecentlyViewedProductsService _recentlyViewedProductsService;
        private readonly ICompareProductsService _compareProductsService;
        private readonly IWorkflowMessageService _workflowMessageService;
        private readonly IProductTagService _productTagService;
        private readonly IOrderReportService _orderReportService;
        private readonly ICustomerService _customerService;
        private readonly IBackInStockSubscriptionService _backInStockSubscriptionService;
        private readonly IPermissionService _permissionService;

        private readonly MediaSettings _mediaSetting;
        private readonly CatalogSettings _catalogSettings;
        private readonly ShoppingCartSettings _shoppingCartSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly LocalizationSettings _localizationSettings;
        private readonly CustomerSettings _customerSettings;
        private readonly ICacheManager _cacheManager;
        
        #endregion

    #region Constructors

        public CatalogController(ICategoryService categoryService,
            IManufacturerService manufacturerService, IProductService productService,
            IProductTemplateService productTemplateService,
            ICategoryTemplateService categoryTemplateService,
            IManufacturerTemplateService manufacturerTemplateService,
            IProductAttributeService productAttributeService, IProductAttributeParser productAttributeParser,
            IWorkContext workContext, ITaxService taxService, ICurrencyService currencyService,
            IPictureService pictureService, ILocalizationService localizationService,
            IPriceCalculationService priceCalculationService, IPriceFormatter priceFormatter,
            IWebHelper webHelper, ISpecificationAttributeService specificationAttributeService,
            ICustomerContentService customerContentService, IDateTimeHelper dateTimeHelper,
            IShoppingCartService shoppingCartService,
            IRecentlyViewedProductsService recentlyViewedProductsService, ICompareProductsService compareProductsService,
            IWorkflowMessageService workflowMessageService, IProductTagService productTagService,
            IOrderReportService orderReportService, ICustomerService customerService,
            IBackInStockSubscriptionService backInStockSubscriptionService,
            IPermissionService permissionService,
            MediaSettings mediaSetting, CatalogSettings catalogSettings,
            ShoppingCartSettings shoppingCartSettings, StoreInformationSettings storeInformationSettings,
            LocalizationSettings localizationSettings, CustomerSettings customerSettings, ICacheManager cacheManager)
        {
            this._categoryService = categoryService;
            this._manufacturerService = manufacturerService;
            this._productService = productService;
            this._productTemplateService = productTemplateService;
            this._categoryTemplateService = categoryTemplateService;
            this._manufacturerTemplateService = manufacturerTemplateService;
            this._productAttributeService = productAttributeService;
            this._productAttributeParser = productAttributeParser;
            this._workContext = workContext;
            this._taxService = taxService;
            this._currencyService = currencyService;
            this._pictureService = pictureService;
            this._localizationService = localizationService;
            this._priceCalculationService = priceCalculationService;
            this._priceFormatter = priceFormatter;
            this._webHelper = webHelper;
            this._specificationAttributeService = specificationAttributeService;
            this._customerContentService = customerContentService;
            this._dateTimeHelper = dateTimeHelper;
            this._shoppingCartService = shoppingCartService;
            this._recentlyViewedProductsService = recentlyViewedProductsService;
            this._compareProductsService = compareProductsService;
            this._workflowMessageService = workflowMessageService;
            this._productTagService = productTagService;
            this._orderReportService = orderReportService;
            this._customerService = customerService;
            this._backInStockSubscriptionService = backInStockSubscriptionService;
            this._permissionService = permissionService;


            this._mediaSetting = mediaSetting;
            this._catalogSettings = catalogSettings;
            this._shoppingCartSettings = shoppingCartSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._localizationSettings = localizationSettings;
            this._customerSettings = customerSettings;

            this._cacheManager = cacheManager;
        }

        #endregion

        #region Utilities

        [NonAction]
        protected ProductVariant GetMinimalPriceProductVariant(IList<ProductVariant> variants)
        {
            if (variants == null)
                throw new ArgumentNullException("variants");

            if (variants.Count == 0)
                return null;

            var tmp1 = variants.ToList();
            tmp1.Sort(new GenericComparer<ProductVariant>("Price", GenericComparer<ProductVariant>.SortOrder.Ascending));
            return tmp1.Count > 0 ? tmp1[0] : null;
        }

        [NonAction]
        protected IList<Category> GetCategoryBreadCrumb(Category category)
        {
            if (category == null)
                throw new ArgumentNullException("category");

            var breadCrumb = new List<Category>();
            
            while (category != null && //category is not null
                !category.Deleted && //category is not deleted
                category.Published) //category is published
            {
                breadCrumb.Add(category);
                category = _categoryService.GetCategoryById(category.ParentCategoryId);
            }
            breadCrumb.Reverse();
            return breadCrumb;
        }

        [NonAction]
        protected ProductModel.ProductPriceModel PrepareProductPriceModel(Product product)
        {
            if (product == null)
                throw new ArgumentNullException("product");

            var model = new ProductModel.ProductPriceModel();
            var productVariants = _productService.GetProductVariantsByProductId(product.Id);

            switch (productVariants.Count)
            {
                case 0:
                    {
                        //no variants
                        model.OldPrice = null;
                        model.Price = null;
                    }
                    break;
                case 1:
                    {
                        //only one variant
                        var productVariant = productVariants[0];

                        if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                        {
                            if (!productVariant.CustomerEntersPrice)
                            {
                                if (productVariant.CallForPrice)
                                {
                                    model.OldPrice = null;
                                    model.Price = _localizationService.GetResource("Products.CallForPrice");
                                }
                                else
                                {
                                    decimal taxRate = decimal.Zero;
                                    decimal oldPriceBase = _taxService.GetProductPrice(productVariant, productVariant.OldPrice, out taxRate);
                                    decimal finalPriceBase = _taxService.GetProductPrice(productVariant, _priceCalculationService.GetFinalPrice(productVariant, true), out taxRate);

                                    decimal oldPrice = _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, _workContext.WorkingCurrency);
                                    decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, _workContext.WorkingCurrency);

                                    if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero)
                                    {
                                        model.OldPrice = _priceFormatter.FormatPrice(oldPrice);
                                        model.Price = _priceFormatter.FormatPrice(finalPrice);
                                    }
                                    else
                                    {
                                        model.OldPrice = null;
                                        model.Price = _priceFormatter.FormatPrice(finalPrice);
                                    }
                                }
                            }
                        }
                        else
                        {
                            model.OldPrice = null;
                            model.Price = null;
                        }
                    }
                    break;
                default:
                    {
                        //multiple variants
                        var productVariant = GetMinimalPriceProductVariant(productVariants);
                        if (productVariant != null)
                        {
                            if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                            {
                                if (!productVariant.CustomerEntersPrice)
                                {
                                    if (productVariant.CallForPrice)
                                    {
                                        model.OldPrice = null;
                                        model.Price = _localizationService.GetResource("Products.CallForPrice");
                                    }
                                    else
                                    {
                                        decimal taxRate = decimal.Zero;
                                        decimal fromPriceBase = _taxService.GetProductPrice(productVariant, _priceCalculationService.GetFinalPrice(productVariant, false), out taxRate);
                                        decimal fromPrice = _currencyService.ConvertFromPrimaryStoreCurrency(fromPriceBase, _workContext.WorkingCurrency);

                                        model.OldPrice = null;
                                        model.Price = String.Format(_localizationService.GetResource("Products.PriceRangeFrom"), _priceFormatter.FormatPrice(fromPrice));
                                    }
                                }
                            }
                            else
                            {
                                model.OldPrice = null;
                                model.Price = null;
                            }
                        }
                    }
                    break;
            }

            //'add to cart' button
            switch (productVariants.Count)
            {
                case 0:
                    {
                        // no variants
                        model.DisableBuyButton = true;
                    }
                    break;
                case 1:
                    {

                        //only one variant
                        var productVariant = productVariants[0];
                        model.DisableBuyButton = productVariant.DisableBuyButton || !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart);
                        if (!_permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                        {
                            model.DisableBuyButton = true;
                        }
                    }
                    break;
                default:
                    {
                        //multiple variants
                        model.DisableBuyButton = true;
                    }
                    break;
            }
            
            return model;
        }

        [NonAction]
        protected ProductModel PrepareProductOverviewModel(Product product, bool preparePriceModel = true, bool preparePictureModel = true, int? productThumbPictureSize = null)
        {
            if (product == null)
                throw new ArgumentNullException("product");

            var model = product.ToModel();
            //price
            if (preparePriceModel)
            {
                model.ProductPrice = PrepareProductPriceModel(product);
            }
            //picture
            if (preparePictureModel)
            {
                //If a size has been set in the view, we use it in priority
                int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : _mediaSetting.ProductThumbPictureSize;
                var picture = product.GetDefaultProductPicture(_pictureService);
                if (picture != null)
                {
                    model.DefaultPictureModel.ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize, true);
                    model.DefaultPictureModel.FullSizeImageUrl = _pictureService.GetPictureUrl(picture);
                }
                else
                {
                    model.DefaultPictureModel.ImageUrl = _pictureService.GetDefaultPictureUrl(pictureSize);
                    model.DefaultPictureModel.FullSizeImageUrl = _pictureService.GetDefaultPictureUrl();
                }
                model.DefaultPictureModel.Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name);
                model.DefaultPictureModel.AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name);
            }
            return model;
        }

        [NonAction]
        protected int GetNumberOfProducts(Category category, bool includeSubCategories)
        {
            var products = _productService.SearchProducts(category.Id,
                        0, null, null, null, 0, string.Empty, false, 0, null,
                        ProductSortingEnum.Position, 0, 1);

            var numberOfProducts = products.TotalCount;

            if (includeSubCategories)
            {
                var subCategories = _categoryService.GetAllCategoriesByParentCategoryId(category.Id);
                foreach (var subCategory in subCategories)
                    numberOfProducts += GetNumberOfProducts(subCategory, includeSubCategories);
            }
            return numberOfProducts;
        }

        [NonAction]
        protected IList<CategoryNavigationModel> GetChildCategoryNavigationModel(IList<Category> breadCrumb, int rootCategoryId, Category currentCategory, int level)
        {
            var result = new List<CategoryNavigationModel>();
            foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(rootCategoryId))
            {
                var model = new CategoryNavigationModel()
                {
                    Id = category.Id,
                    Name = category.GetLocalized(x => x.Name),
                    SeName = category.GetSeName(),
                    IsActive = currentCategory != null && currentCategory.Id == category.Id,
                    NumberOfParentCategories = level
                };

                if (_catalogSettings.ShowCategoryProductNumber)
                {
                    model.DisplayNumberOfProducts = true;
                    model.NumberOfProducts = GetNumberOfProducts(category, _catalogSettings.ShowCategoryProductNumberIncludingSubcategories);
                }
                result.Add(model);

                for (int i = 0; i <= breadCrumb.Count - 1; i++)
                    if (breadCrumb[i].Id == category.Id)
                        result.AddRange(GetChildCategoryNavigationModel(breadCrumb, category.Id, currentCategory, level + 1));
            }

            return result;
        }
        
        [NonAction]
        protected ProductModel PrepareProductDetailsPageModel(Product product)
        {
            if (product == null)
                throw new ArgumentNullException("product");

            var model = product.ToModel();

            //template

            var templateCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_TEMPLATE_MODEL_KEY, product.ProductTemplateId);
            model.ProductTemplateViewPath = _cacheManager.Get(templateCacheKey, () =>
            {
                var template = _productTemplateService.GetProductTemplateById(product.ProductTemplateId);
                if (template == null)
                    template = _productTemplateService.GetAllProductTemplates().FirstOrDefault();
                return template.ViewPath;
            });

            //pictures
            model.DefaultPictureZoomEnabled = _mediaSetting.DefaultPictureZoomEnabled;
            var pictures = _pictureService.GetPicturesByProductId(product.Id);
            if (pictures.Count > 0)
            {
                //default picture
                model.DefaultPictureModel = new PictureModel()
                {
                    ImageUrl = _pictureService.GetPictureUrl(pictures.FirstOrDefault(), _mediaSetting.ProductDetailsPictureSize),
                    FullSizeImageUrl = _pictureService.GetPictureUrl(pictures.FirstOrDefault()),
                    Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name),
                    AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name),
                };
                //all pictures
                foreach (var picture in pictures)
                {
                    model.PictureModels.Add(new PictureModel()
                    {
                        ImageUrl = _pictureService.GetPictureUrl(picture, _mediaSetting.ProductThumbPictureSizeOnProductDetailsPage),
                        FullSizeImageUrl = _pictureService.GetPictureUrl(picture),
                        Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name),
                        AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name),

                    });
                }
            }
            else
            {
                //no images. set the default one
                model.DefaultPictureModel = new PictureModel()
                {
                    ImageUrl = _pictureService.GetDefaultPictureUrl(_mediaSetting.ProductDetailsPictureSize),
                    FullSizeImageUrl = _pictureService.GetDefaultPictureUrl(),
                    Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name),
                    AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name),
                };
            }


            //product variants
            foreach (var variant in _productService.GetProductVariantsByProductId(product.Id))
                model.ProductVariantModels.Add(PrepareProductVariantModel(new ProductModel.ProductVariantModel(), variant));

            return model;
        }

        [NonAction]
        protected void PrepareProductReviewsModel(ProductReviewsModel model, Product product)
        {
            if (product == null)
                throw new ArgumentNullException("product");

            if (model == null)
                throw new ArgumentNullException("model");

            model.ProductId = product.Id;
            model.ProductName = product.GetLocalized(x => x.Name);
            model.ProductSeName = product.GetSeName();

            var productReviews = product.ProductReviews.Where(pr => pr.IsApproved).OrderBy(pr => pr.CreatedOnUtc);
            foreach (var pr in productReviews)
            {
                model.Items.Add(new ProductReviewModel()
                {
                    Id = pr.Id,
                    CustomerId = pr.CustomerId,
                    CustomerName = pr.Customer.FormatUserName(),
                    AllowViewingProfiles = _customerSettings.AllowViewingProfiles && pr.Customer != null && !pr.Customer.IsGuest(),
                    Title = pr.Title,
                    ReviewText = pr.ReviewText,
                    Rating = pr.Rating,
                    Helpfulness = new ProductReviewHelpfulnessModel()
                    {
                        ProductReviewId = pr.Id,
                        HelpfulYesTotal = pr.HelpfulYesTotal,
                        HelpfulNoTotal = pr.HelpfulNoTotal,
                    },
                    Writt
11 years ago
Just a minor suggestion but rather than try to post the entire 2602 lines of CatalogController.cs and thus failing to post the method where you should have made the change and I would be looking to see if it was correct.

How about you just copy and post that method i.e.
public ActionResult RecentlyViewedProductsBlock(int? productThumbPictureSize)


That way I don't have to scroll through a wall of text trying to find it when it isn't there. (Don't worry I used Find).

Also I can see you have made a few changes to the code you are posting.

Rather than have me try to figure out what you may have broken elsewhere I'd advise you make the changes to an unmodified copy of Nop 2.4. That way we can eliminate other factors causing this not to work.

HTH

Dave
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.