public ActionResult Category(int categoryId, CatalogSearchQuery query) { var category = _categoryService.GetCategoryById(categoryId); if (category == null || category.Deleted) { return(HttpNotFound()); } // Check whether the current user has a "Manage catalog" permission. // It allows him to preview a category before publishing. if (!category.Published && !Services.Permissions.Authorize(Permissions.Catalog.Category.Read)) { return(HttpNotFound()); } // ACL (access control list). if (!_aclService.Authorize(category)) { return(HttpNotFound()); } // Store mapping. if (!_storeMappingService.Authorize(category)) { return(HttpNotFound()); } var store = Services.StoreContext.CurrentStore; var customer = Services.WorkContext.CurrentCustomer; // 'Continue shopping' URL. if (!Services.WorkContext.CurrentCustomer.IsSystemAccount) { _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.LastContinueShoppingPage, Services.WebHelper.GetThisPageUrl(false), store.Id); } var model = category.ToModel(); if (query.IsSubPage && !_catalogSettings.ShowDescriptionInSubPages) { model.Description.ChangeValue(string.Empty); model.BottomDescription.ChangeValue(string.Empty); } Services.DisplayControl.Announce(category); // Category breadcrumb. if (_catalogSettings.CategoryBreadcrumbEnabled) { _helper.GetCategoryBreadcrumb(_breadcrumb, ControllerContext); } // Products. var catIds = new int[] { categoryId }; if (_catalogSettings.ShowProductsFromSubcategories) { // Include subcategories. catIds = catIds.Concat(_helper.GetChildCategoryIds(categoryId)).ToArray(); } query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? (bool?)null : false, catIds); var searchResult = _catalogSearchService.Search(query); model.SearchResult = searchResult; var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(query.GetViewMode()); model.Products = _helper.MapProductSummaryModel(searchResult.Hits, mappingSettings); model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType; var customerRolesIds = customer.CustomerRoleMappings .Select(x => x.CustomerRole) .Where(x => x.Active) .Select(x => x.Id) .ToList(); var pictureSize = _mediaSettings.CategoryThumbPictureSize; var fallbackType = _catalogSettings.HideCategoryDefaultPictures ? FallbackPictureType.NoFallback : FallbackPictureType.Entity; var hideSubCategories = _catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.Hide || (_catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.AboveProductList && query.IsSubPage && !_catalogSettings.ShowSubCategoriesInSubPages); var hideFeaturedProducts = _catalogSettings.IgnoreFeaturedProducts || (query.IsSubPage && !_catalogSettings.IncludeFeaturedProductsInSubPages); // Subcategories. if (!hideSubCategories) { var subCategories = _categoryService.GetAllCategoriesByParentCategoryId(categoryId); model.SubCategories = _helper.MapCategorySummaryModel(subCategories, pictureSize); } // Featured Products. if (!hideFeaturedProducts) { CatalogSearchResult featuredProductsResult = null; string cacheKey = ModelCacheEventConsumer.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customerRolesIds), store.Id); var hasFeaturedProductsCache = Services.Cache.Get <bool?>(cacheKey); var featuredProductsQuery = new CatalogSearchQuery() .VisibleOnly(customer) .WithVisibility(ProductVisibility.Full) .WithCategoryIds(true, categoryId) .HasStoreId(Services.StoreContext.CurrentStore.Id) .WithLanguage(Services.WorkContext.WorkingLanguage) .WithCurrency(Services.WorkContext.WorkingCurrency); if (!hasFeaturedProductsCache.HasValue) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0; Services.Cache.Put(cacheKey, hasFeaturedProductsCache, TimeSpan.FromHours(6)); } if (hasFeaturedProductsCache.Value && featuredProductsResult == null) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); } if (featuredProductsResult != null) { var featuredProductsmappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid); model.FeaturedProducts = _helper.MapProductSummaryModel(featuredProductsResult.Hits, featuredProductsmappingSettings); } } // Prepare paging/sorting/mode stuff. _helper.MapListActions(model.Products, category, _catalogSettings.DefaultPageSizeOptions); // Template. var templateCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId); var templateViewPath = Services.Cache.Get(templateCacheKey, () => { var template = _categoryTemplateService.GetCategoryTemplateById(category.CategoryTemplateId); if (template == null) { template = _categoryTemplateService.GetAllCategoryTemplates().FirstOrDefault(); } return(template.ViewPath); }); // Activity log. Services.CustomerActivity.InsertActivity("PublicStore.ViewCategory", T("ActivityLog.PublicStore.ViewCategory"), category.Name); return(View(templateViewPath, model)); }