Jump to content
pwusr

Displaying products category-wise

Recommended Posts

I have 4 main categories. Each of them have 15 sub-categories and each sub category has around 20-25 products listed.

Please see this image-

post-42-0-65667900-1360639011_thumb.gif

I have created a Category template with just the Category name.

The main and sub categories pages are based on this template.

The product pages are based on the Product Template - with Product Name, Description, Image etc.

(Hope I have got it right)

What I am looking to accomplish:

When a user clicks on Main category, it should take him to a page showing all sub categories for that.

And when a sub category is clicked it should show all the products which comes under that along with its price etc.

On clicking a product it should show details like description, image etc.

Really appreciate any inputs on how to structure the template files to display this..

Thanks a lot.

Share this post


Link to post
Share on other sites

I think you've probably got it about right in terms of structure, unless your products need to have multiple categories/subcategories. I'd suggest using a different template for category and subcategory rather than the same one. You'd mentioned pretty different output needs between category and subcategory. Not to mention, structurally subcategory requires category as a parent, so you can enforce that with family settings if they are different templates. 

Share this post


Link to post
Share on other sites

On the principle that I have just been doing a template for a site that has 12,000 categories (!), the way I would do this is to list categories as pages under the menu but then create products separately, probably listed under a hidden parent called "products" or something nice!

Then create a page field for your product template called "category" and set it to only list pages that have the "category" template.

Now, when you create a product you can link it to one of your category pages - at any level.

In theory this means that each category can have both products and sub-categories.

Now, with your category template file, you need to do two things:

1. Check to see whether there are any children to the page (and if so, list them)

2. Check to see if there are any product pages where their "category" page field = the current page. And if so, list them.

Design wise, you could put products in the main area and shove sub-categories (children) in the side bar or something sweet like that.

You could also add another grouping called Manufacturers (create those under a hidden page as with the products) And throw those into the mix too.

I suggest a large piece of paper and a pencil!

Joss

  • Like 1

Share this post


Link to post
Share on other sites

I am working on something similar. @Joss: I think this is what you are getting at? I would be grateful if you can confirm.

I'm using screenshots to try to explain. I hope this works?

First I created a categories page structure:

post-564-0-12816800-1360754447_thumb.png

Then I created the products page structure:

post-564-0-48595300-1360754524_thumb.png

Then a field called categories of type 'page'.

The Basic settings

post-564-0-90980200-1360754631_thumb.png

The Details settings

post-564-0-39128400-1360754764_thumb.png

The Input settings

post-564-0-96649200-1360754786_thumb.png

Add the categories field to the product template, so that you can select the appropriate categories for that product.

post-564-0-23269700-1360755016_thumb.png

Some notes. I haven't yet sorted out the template structure for the hierachy. As Ryan said above, I probably need different templates for the categories and sub-categories.

I'm also at a point where I need some help displaying the categories. I'm ok with the parent page called 'Boys Nightware' that hold the children as products. If there's a better way to do it please let me know. This is the code in the template for Boys Nightware:

<?php 
   if ($page->children) {
            foreach($page->children as $product) {    
                $firstimage = $product->product_images->first();
                echo "<div class='product_section'>
                        <div class='img_ctr'><a href='{$product->url}'><img src='{$firstimage->url}' alt='{$firstimage->description}'></a></div>
                <h3><a href='{$product->url}'>{$product->product_name}</a></h3>
                <p style='text-align:center;font-size:90%;'><span class='product_attribute_label'>Size:</span> {$product->product_size}<span class='product_attribute_label' style='margin-left:1em;'>Price:</span> £{$product->sc_price}</p>
                
                </div>";    
        }}
    ?>
 

Which produces this layout where you click through to a single product page.

post-564-0-31867300-1360756178_thumb.png

I now need to work on the templates for the categories above that. Any guidance appreciated.

  • Like 1

Share this post


Link to post
Share on other sites

Hi

If I follow your picture story right, you are able to add more than one category to any one product?

I think you have gone slightly more complicated than I would have done.

The product Hierarchy is good for keeping things sorted in the back end, but I would not have necessarily used it in the front end, but rather just used the category structure to sort the products. This might be overly simple for what you want.

It depends how you want to have your products.

Try this:

Category 1

-- Category 1 1

--- Category 111

If you want to display just the products that appear in each category (and only that level), then you just need to get those products whose category field matches the current page. (I suggest matching by ID if possible so any name changes to categories does not cause problems.)

However, you could also work down the list so that on the Category 1 page you show products related to Category 1, Category 1 1, and Category 1 1 1,

On the category 11 page, you show products relating to category 1 1, and category 1 1 1.

Since category 1 1 1 has no children, you would only need to filter by just the current page.

Now, I admit I don't know how to code this, but effective you just need to recursively find all the child and sub-child (and so on) categories of the current category page and then match that array of categories to the product category field. (the starting point to do this is probably in the sitemap template, by the way)

Each product would only need to belong to one category - you are effectively making it a member of parent categories, if they exist.

You would only need the one category template this way to cover all your categories; you can test whether there are any child categories and if not, just use the current category. If that has no products either, then display something that says "no one here but us child categories!" - well, make it nicer than that!

Does that help, or am I making it more confused?

Share this post


Link to post
Share on other sites

Why have you categories tree, and then again a product tree which has the categories again? Do you really need that? Or do you need multiple categories? The way you have it now you already have the products categorized through structure.

In your example using page field you would do it like this.

// on $page Boys Nightware
$prods = $pages->find("template=product, categories=$page");
if (count($prods)) {
    foreach($prods as $product){
        // output prod
    }
}

Share this post


Link to post
Share on other sites

Soma,

How can you work you way down the category tree to get a list of all the categories in one branch, starting from the current category page?

I have suggested above that this should be used to get a list of the category page IDs and then to use that list to retrieve all products for the current category AND the sub categories (however far that tree extends)

In that way, the category tree works as a filter as well as a logical structure.

I agree about the product tree - not needed for the site to work, though it can be useful to just sort stuff out in the backend. But that structure can be ignored.

Share this post


Link to post
Share on other sites

Thanks both for your replies. Some food for thought there.

@Soma: 

    The part of the code categories=$page below I do not understand and including it returns a blank page. Maybe I have implemented it incorrectly?

   

$prods = $pages->find("template=product, categories=$page");
 

Share this post


Link to post
Share on other sites

I'm officially very confused of what you both trying to archive. It all doesn't make sense to me and it seems hard to explain. You guys seem to be wired very different :D

Either use categories structure you use as the navigation to navigate the categories, then show the products that has the current category selected.

OR use categories with the products already inside and simply render them out with $page->children(), which is what NooseLadder is doing and using this approach doesn't make sense to have categories separate again. (I don't see where they would come into play when he already renders them out from the structure which already holds the categories).

Share this post


Link to post
Share on other sites
which is what NooseLadder is doing and using this approach doesn't make sense to have categories separate again. (I don't see where they would come into play when he already renders them out from the structure which already holds the categories).

You are quite right Soma. When I started this I wasn't sure which way to do it so I created the categories field upfront.

Now I'm looking for guidance/best practise. So do I use page structure or categories field? 

Share this post


Link to post
Share on other sites

Thanks both for your replies. Some food for thought there.

@Soma: 

    The part of the code categories=$page below I do not understand and including it returns a blank page. Maybe I have implemented it incorrectly?

   

$prods = $pages->find("template=product, categories=$page");

My code example would be if you have the categories as the navigation/page structure to display the products assigned to them.

$page would be the category page and categories is the page field used to select the category on the products.

So in simple this find find all products that have the current category page selected.

I'm on category page:

Boys Nightware

show me all products that have Boys Nightware selected.

You are quite right Soma. When I started this I wasn't sure which way to do it so I created the categories field upfront.

Now I'm looking for guidance/best practise. So do I use page structure or categories field? 

The question you have to ask is do I need multiple categories or not.

  • Like 1

Share this post


Link to post
Share on other sites

Thank you Ryan & Joss for your replies.

I have added a different template for sub-category.

I've got this part working:

 

When a user clicks on Main category, it should take him to a page showing all sub categories for that.


And when a sub category is clicked it should show all the products which comes under that

Now I have a doubt,

In my Categories, sub categories or products templates I haven't used a Page type field anywhere.

Kindly let me know the significance of using a Page field type here for categories  (like Nooseladder has used) or products.

(I do not have multiple categories at the moment)

but then create products separately, probably listed under a hidden parent called "products"

@Joss,

I am sorry I couldn't understand this fully.. I would be grateful if you could elaborate a bit..

Thank you.

Share this post


Link to post
Share on other sites

Hi pwusr

Basically it is much as Soma said a couple of posts up.

You create your menu/site structure using pages that represent categories (as Ryan has said before, because of the page structure of PW, they can be seen as a hierarchical category structure)

But then you need to add products to each of these categories.

You can either make those child pages of the categories, or you can store them completely separately and add a Page field to them to select your "category"

For example. 

  • Create a page field (call it category)
  • Set it to the third option - single - on the details tab.
  • On the input tab, set Home as the parent (remembering all your categories are going to be children of the home page) and set the template as what ever your category template is.
  • At the end of the input tab, set the field type to "select" - you don't need anything more clever.
  • Now, add this field to your product template.

Now, when you create a product you can use this page field to select a "category"

Those product pages can be stored anywhere. However, you probably don't want them to appear on the main menu - you just want your category pages and any info pages there.

So,

  • create a template called "product-list" that has no file.
  • Once you have saved that, go to the Family tab and where it says "Allowed templates for children" choose you product template.
  • Go to pages and create a new page under Home.
  • Choose the product-list template. 
  • Save and then under settings make sure this page is Published and Hidden.

Now, any children of this page will not display on the main menu. So you can create all your products as children here. You can leave them as one long list, or split them up into manageable sub levels - up to you. It wont affect what is displayed on the front of the site since it is the category pages field that will do that job.

On your category template, you can now use the $pages->find (see cheat sheet) to bring up all the pages that have the template "product" and where their category pages field matches the current page, and then loop through them.

The final result is that the structure of the front end of the site is based around the category pages and how you have organised those, and the products are simply displayed because of the category they are related to.

As you can imagine, using the same principle, you can associate your pages in all kinds of ways - using tags, is a good example.

Sorry if I wasn't clear before - hopefully this is better! :)

Joss

  • Like 1

Share this post


Link to post
Share on other sites

 
On your category template, you can now use the $pages->find (see cheat sheet) to bring up all the pages that have the template "product" and where their category pages field matches the current page, and then loop through them.

That's a good explanation of the process Joss. A code example of above quote would make it complete. 

P.S. Note to forum admin: Can't seem to delete code wraps if inserted by mistake, like at the top of this post.

Share this post


Link to post
Share on other sites

If you look through this: http://processwire.com/api/selectors/

It has just about everything you could want about sorting stuff and finding stuff. 

So, assuming your current (category) page is in a variable called $currentpage,

then

$posts = $pages->find("template=post, category_field=$currentpage");

or something like that! You will get better information from the page about selectors than from me! :)

Share this post


Link to post
Share on other sites

My product structure is like this:

Main Category 1

-- Sub Category 1

---- Prod 1

---- Prod 2

-- Sub Category 2

---- Prod 1

---- Prod 2

etc.

In the method Joss outlined, do we need separate templates for main-categories  & sub-categories.

One of my Main Category is for Rental items (where there are weekly/daily rental charges) & other for Sales items (where I have to include Sales Price).

Please let me know if I need to have 2 differernt template files here.

Thank you very much in advance..

Share this post


Link to post
Share on other sites

Some of this you are talking about is more about what your post templates are up to - which fields they are using.

Some will be common - title, maybe a main image, a summary perhaps. But then you will have specifics like price.

Now, you will probably create different templates for each type of post, so that is not an issue.

In the category, you can do two things. You can either create specific category templates for each post type, or you can use just the one template and test to see if specific fields that you need to display on the category exist. If your price field exists, then display it. If it doesn't then dont. That sort of thing.

The main thing that will make you decide whether to have different category templates is if the layout for each subject matter needs to look very different - which is quite possible.

As to whether you need different category templates for top level or sublevel within any particular tree, I don't think you do, to be honest. 

I am sort of beginning to answer some of your questions with a profile I am working on.

It is a blog on steroids!

I only have one category template, but I am putting a few controls in it using fields.

(You have to bear in mind that I am using Bootstrap and my controls are aimed at that framework)

So, for instance, I can change how many columns in the category template the posts are listed over.

I have added a "featured category" checkbox on posts so I can have featured in each category that are always at the top of the page. (I also have a featured global which I will use for the home page - when I get there!)

All my main post types have common fields, so I can list any type of post within one category.

Because it is a blog, I can select whether in each category (or sub category - it is all the same) I make it look more like a blog layout or more magazine style.

And there are some other bits.

So, I can actually change some basic display elements on a category by category basis without changing the template.

I am mostly doing this to prove I can, to be honest, rather than for any amazing reason. This is me learning still.

Share this post


Link to post
Share on other sites

If it is any help, this is what I am doing at the moment. I have decided to use a product tree like this:

post-564-0-24903300-1361015490_thumb.png

The following I call sections and all these three levels have the same template detailed below called product_section_list:

Products

      -Girls

             -Girls Nightware

<?php // product_section_list    
if($page->children) {
       $sections = $page->children;
        
       foreach ($sections as $section) {
          $firstimage = $section->product_images->first();
           echo "<div class='product_section'>
           <div class='img_ctr'><a href='{$section->url}'><img src='{$firstimage->url}' alt='{$firstimage->description}'></a></div>
               <h3><a href='{$section->url}'>{$section->title}</a></h3>
            <!--<p style='text-align:center;font-size:90%;'><span class='product_attribute_label' style='margin-left:1em;'>Price:</span> £{$section->sc_price}</p>-->
            </div>";
       }} ?>
 

What this does is create a top-level product section list that links to each child of the section. So a view of the products page would be something like this (images are just for testing purposes):

post-564-0-18628400-1361016233_thumb.png

If you then view the section called Girls you get this:

post-564-0-87121100-1361016356_thumb.png

The section Girls Bedding uses a different template called product_item_list see below:

<?php // product_item_list
 $currentpage = $page->categories;  
 $prods = $pages->find("template=product_item, categories=$currentpage");
if (count($prods)) {
    foreach ($prods as $product) {
        $priceraw = $product->sc_price;
        $price = number_format($priceraw, 2, '.', ',');
        $firstimage = $product->product_images->first();
        echo "<div class='product_section'>
                        <div class='img_ctr'><a href='{$product->url}'><img src='{$firstimage->url}' alt='{$firstimage->description}'></a></div>
                <h3><a href='{$product->url}'>{$product->product_name}</a></h3>";
        if("$product->product_size") {    
                echo "<p style='text-align:center;font-size:90%;'><span class='product_attribute_label'>Size: </span>{$product->product_size}<span class='product_attribute_label' style='margin-left:1em;'>Price:</span> £{$price}</p>";
        } else {
        echo "<p style='text-align:center;font-size:90%;'><span class='product_attribute_label' style='margin-left:1em;'>Price:</span> £{$price}</p>";
        }
                if ($user->isLoggedin()) { echo "<p style='text-align:center;color:#c00;font-size:80%;'>Hierachy: {$product->product_hierachy}</p>
                <p style='text-align:center;color:#c00;font-size:80%;'>Category: {$product->categories->title} ({$product->categories})</p>"; }
                echo "</div>";
    }}

    ?>
 

This displays a list of the individual products under that section as below:

post-564-0-62164000-1361016658_thumb.png

The fields called Hierachy and Category in red on the page are only displayed if a user is logged in for admin purposes. That's the part of the code starting if ($user->isLoggedin()).

Each individual product is displayed using a template called product_item.

<?php //product_item
$firstimage = $page->product_images->first();
        $priceraw = $page->get("sc_price");
        $price = number_format($priceraw, 2, '.', ',');
        echo "<div class='product'>
                <div class='col_1'>";
                if ("$page->product_images") {
                    echo "<img id='image1' src='{$firstimage->url}' alt='{$firstimage->description}' />
                    <p>Rollover image to zoom</p>";
                } else {
                    echo "<img src='{$config->urls->templates}images/products/image_placeholder.jpg' alt='No image available' />";
                }
                echo "<!-- end .col_1--></div>
                <div class='col_2'>
                    <div class='product_title'>    
                        <h1>{$page->product_name}</h1>
                        <p><span class='product_attribute_label'>Price:</span> £{$price}</p>";
                if("$page->product_size") {        
                        echo "<p><span class='product_attribute_label'>Size:</span> {$page->product_size}</p>";
                }
                        echo "<p class='product_code'>Product code: {$page->product_code}</p>
                    <!-- end .product_title--></div>
                        <p class='product_description'>{$page->product_description}</p>
                        <div class='add_to_cart'>{$modules->get('ShoppingCart')->renderAddToCart($page)}</div>
                <!-- end .col_2--></div>
            <!-- end .product--></div>
            <div class='separator'></div> "; ?>
 

Which give the following layout:

post-564-0-72481200-1361017019_thumb.png

And BTW I am using Apeisa's Shopping Cart Module (Thanks Apeisa)

There are two main reasons I did it this way:

1. To give the client a product structure they can visually see.

2. I used to run an ecommerce site using Actinic and this is how it's product sections were structured.

Whether this is a good or bad way of doing it I don't know but it works for me.

            

  • Like 3

Share this post


Link to post
Share on other sites

Thanks a lot, Joss. I am sorry I couldn't check back earlier.

Thanks Nooseladder for posting your work. I am sure it will be of help.

Share this post


Link to post
Share on other sites

@Joss, If I add another manufacturer-list template with no file and the children of this has a 'manufacturer' template (with fields like manufacturer name etc) , do we have to add each manufacturer name manually as pages? Is there any other way? Kindly clarify. Thank you.

Share this post


Link to post
Share on other sites

Hi PWusr

If you are creating any select system, at some point you have to add the data!

Everything in PW should be stored as pages - so yes, you are going to have to add pages. But I can't think what other way you would be looking for.

There is a module somewhere for creating lots of pages in one go - it is in the module section somewhere.

For simple pages like this (where you are basically just using the Title field) it would speed things up.

Of course, if you are adding additional info like description, addresses, websites and so on, you are going to have to add it one by one. But that would be the same whatever system you use.

Share this post


Link to post
Share on other sites

Thanks a lot, Joss.

Sorry for not being clearer. I had a manufacturer name field in my product template.. the reason why I had the doubt.

Like you mentioned, as the manufacturer template, has manufacturer name, address etc, I will add it one by one.

Share this post


Link to post
Share on other sites

Don't worry, many the time I have wished for a program that you could say "just go and produce all my text for me - automatically."

Well, I suppose there used to be such a system. It was called a typing pool....

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...