Tuesday, February 10, 2015

How to add a new picture property to Category entity in nopCommerce?

I wrote a post about how to add a new property to Product entity in nopCommerce earlier, this is quite similar, but it still took me some time to figure out how to do. So I think it's good for me to write another post for this too.

Scenario: I'd like to add a top banner to the category page. When user clicks on it, it'll navigate to another page.

1. Go to Database and add new columns TopBannerId & TopBannerLink in Category table.

It's recommended to add a new column via SQL.
ALTER TABLE [dbname].[dbo].[Category] ADD [TopBannerId] INT NOT NULL DEFAULT '0'
ALTER TABLE [dbname].[dbo].[Category] ADD [TopBannerLink] NVARCHAR(500) NULL

2. Go to Libraries > Nop.Core > Domain > Catalog > Category.cs
Add this code:
public int TopBannerId { get; set; }
public string TopBannerLink { get; set; }

3. Go to Libraries > Nop.Data > Mapping > Catalog > CategoryMap.cs
Add this code:

this.Property(p => p.TopBannerLink).HasMaxLength(500).IsOptional();

4. Go to Presentation > Nop.Admin > Models > Catalog > CategoryModel.cs
Add these codes:

        [UIHint("Picture")]
        [NopResourceDisplayName("Admin.Catalog.Categories.Fields.TopBanner")]
        public int TopBannerId { get; set; }

        [NopResourceDisplayName("Admin.Catalog.Categories.Fields.TopBannerLink")]
        [AllowHtml]

        public string TopBannerLink { get; set; }

5. Go to Presentation > Nop.Admin > Validators > Catalog > CategoryValidator.cs
Add this code:

RuleFor(x => x.TopBannerLink).Length(0, 500);

6. Go to Presentation > Nop.Admin > Views > Category >  _CreateOrUpdate.Info.cshtml
Add these codes to where you want to edit the new property:

       
           
                @Html.NopLabelFor(model => model.TopBannerId)
           
           
                @Html.EditorFor(model => model.TopBannerId)
                @Html.ValidationMessageFor(model => model.TopBannerId)


       
           
                @Html.NopLabelFor(model => model.TopBannerLink):
           
           
                @Html.EditorFor(model => model.TopBannerLink)
                @Html.ValidationMessageFor(model => model.TopBannerLink)
           

       
           
       

5. Go to Presentation Nop.Admin > Controllers > CategoryController.cs
Add in these codes:

Method name: Edit(CategoryModel model, bool continueEditing)

This is to delete the old top banner when deleting or updating.
I just modified the codes from the Picture, and placed the codes just below it.

int prevTopBannerId = category.TopBannerId;

if (prevTopBannerId > 0 && prevTopBannerId != category.TopBannerId)
                {
                    var prevTopBanner = _pictureService.GetPictureById(prevTopBannerId);
                    if (prevTopBanner != null)
                        _pictureService.DeletePicture(prevTopBanner);
                }

6. Go to Presentation Nop.Web Models > CatalogCategoryModel.cs
Add in this code:

public PictureModel TopBannerModel { get; set; }
public string TopBannerLink { get; set; }

7. Go to Nop.Web > Infrastructure > Cache > ModelCacheEventConsumer.cs

Add these codes:
(I just modify the codes for CATEGORY_PICTURE_MODEL_KEY & CATEGORY_PICTURE_PATTERN_KEY)

        public const string CATEGORY_TOP_BANNER_MODEL_KEY = "Nop.pres.category.topbanner-{0}-{1}-{2}-{3}-{4}-{5}";
        public const string CATEGORY_TOP_BANNER_PATTERN_KEY = "Nop.pres.category.topbanner";

8. Go to Presentation Nop.Web Controllers CategoryController.cs

Method name: Category(CategoryModel model, bool continueEditing)
Place these codes after var model = category.ToModel();


int topBannerSize = _mediaSettings.MaximumImageSize;
            var categoryTopBannerCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_TOP_BANNER_MODEL_KEY, category.Id, topBannerSize, true, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured(), _storeContext.CurrentStore.Id);
            model.TopBannerModel = _cacheManager.Get(categoryTopBannerCacheKey, () =>
            {
                var topBanner = _pictureService.GetPictureById(category.TopBannerId);
                var topBannerModel = new PictureModel
                {
                    FullSizeImageUrl = _pictureService.GetPictureUrl(topBanner),
                    ImageUrl = _pictureService.GetPictureUrl(topBanner, topBannerSize),
                    Title = string.Format(_localizationService.GetResource("Media.Category.ImageLinkTitleFormat"), model.Name),
                    AlternateText = string.Format(_localizationService.GetResource("Media.Category.ImageAlternateTextFormat"), model.Name)
                };
                return topBannerModel;
            });

9. Go to Presentation Nop.Web ViewsCatalog > CategoryTemplate.ProductsInGridOrLines.cshtml

Add in these codes where you want to display the picture.

@Model.TopBannerModel.AlternateText
                     src="@Model.TopBannerModel.ImageUrl"
                     title="@Model.TopBannerModel.Title" />

10. Go to Admin > Configuration > Languages
Click on View string resouces for your language.
Add new record for the newly added field - The name of the resouce is the one we previously set in step 4.
[NopResourceDisplayName("Admin.Catalog.Categories.Fields.TopBanner")]

No comments:

Post a Comment