Jump to content

[SOLVED] Group Products by Subcategory on Category Page


Recommended Posts


I'm working with Prestashop 1.7 and I would like to have my products grouped by subcategory on a category page. So it should look something like this:


Pumps (main category title)

    A Series (subcategory)

        Product 1 thumb

        Product 2 thumb

        Product 3 thumb

   B Series (subcategory)

        Product 4 thumb

        Product 5 thumb



I figured out how to make a custom template by overriding the CategoryController. In the CategoryController, I created a function to build an array of products by subcategory (The array is called 'product_list' in the code below). This array gets passed to smarty, but it does not have all of the data (like images and features) that the original $listing variable has. 


    protected function getSubcategoryProducts($parent_id) {

    	$product_list = array();
    	$i = 0;

    	// get all subcategories
    	$subcategories = $this->category->getSubCategories($this->context->language->id);

    	// get products by subcategory
    	foreach ($subcategories as $subcategory) {
    		$product_list[$i] = Product::getProducts($this->context->language->id, 0,0, 'id_product', 'ASC', $subcategory['id_category'], true);

    	// add all other products not in categories
    	$product_list[$i] = Product::getProducts($this->context->language->id, 0,0, 'id_product', 'ASC', $parent_id, true);

		// make product_list available in smarty template
		$this->context->smarty->assign( 'product_list' , $product_list );



There are other posts that ask for similar organization of products but the solutions are for <=1.6. (ie. https://www.prestashop.com/forums/topic/61907-displaying-all-products-from-subcategories-on-the-category-page/#comment-1278016)

The problem I have is:

1. How do I create a variable like $listing (found in templates/catalog/listing/product-list.tpl) with all the image and feature data? Or how do I sort the $listing of products to group them by subcategory?

I'm afraid that using getProducts in the code above will not work when filters are applied. Any thoughts on this?




Edited by indigo380 (see edit history)
Link to comment
Share on other sites

So I decided to sort the product $listing variable by subcategory using array_multisort.

I'm sure there is a better way but this works for now. The code below was placed in override/controllers/front/listing/CategoryController.php.



class CategoryController extends CategoryControllerCore

    public function initContent()


        // sort products so they are grouped by category


    protected function sortProductsByCategory() {

    	// get product listing
        $listing = $this->context->smarty->getTemplateVars('listing');

        // find all categories in product listing
        $categories = array();
        foreach ($listing['products'] as $product) {
        	$categories[] = $product['id_category_default'];

        // sort product listing by categories
        array_multisort($categories, SORT_ASC, $listing['products']);

        // send listing variable back to smarty template
        $this->context->smarty->assign( 'listing' , $listing );




The problem with this solution is that it doesn't take into account the order of the subcategories. It is only sorting by ascending category id.

Edited by indigo380 (see edit history)
Link to comment
Share on other sites

  • 2 weeks later...

In the end, I simplified my categories and what I really needed was to group the products by brand (my subcategories are now brand names). I was able to set this sorting option in...

Shop Parameters > Product Settings

and set "Default order by" to "Brand". So I didn't need the custom function at all.


Also, I found out if you override the CategoryController to specify custom templates, then the template will not be used with faceted search nor with additional pages (?page=2). It reverts back to the original template. The way to get around this was to add this code to the top of 



{if $category.link_rewrite=='pumps' or $category.id_parent == 362}
    {include file='catalog/_partials/category/pumps.tpl' product=$product}

The new template (templates/catalog/_partials/category/pumps.tpl) was a modified version of template/catalog/_partials/products.tpl

Edited by indigo380 (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...