zyON

Handling Categories on a Product Catalogue

Recommended Posts

haha. I'm sure I have many on that wall as well. :)

  • Like 1

Share this post


Link to post
Share on other sites

Renobird,

But is there a way to hide those pages (Brands and Collections) from the Page hierarchy? Because it's somewhat confusing to the user to see products listed under man or women but no products under any brand or collection. (Newbie mode now engaged).

zyON,

Check into the Page Fieldtype

Maybe something like this for organization:

Shoes

-- Men

---- Product A

---- Product B

---- Product C

-- Women

---- Product A

---- Product B

---- Product C

Brands (these are just the references, no products listed as children)

-- Brand 1

-- Brand 2

-- Brand 3

Collections (these are just the references, no products listed as children)

-- Collection A

-- Collection B

-- Collection C

Create page fields for Brand and Collection, and add them to your "Product" template.

Now you can associate brand and collection with each product.

Share this post


Link to post
Share on other sites

zyON,

If your client needs to add additional brands, collections, types, then they will need access to those pages.

To make it less confusing, you can set them up underneath a parent page.

Categories

-- Brands

---- Brand 1

---- Brand 2

---- Brand 3

-- Types

---- Type A

---- Type B

---- Type C

-- Collections

---- Collection 1

---- Collection 2

---- Collection 3

If you set the parent page /categories to hidden, then it will show as a lighter color in the page tree, and searches won't return any of those pages.

I tend to use something like /tools/ or /config/ to keep things like this all grouped in one nice location.

  • Like 1

Share this post


Link to post
Share on other sites

Renobird,

Yes, it makes sense. So for example, I could have something like:

- Shoes

-- Brands

--- Brand1

--- Brand2

-- Types

--- Type1

--- Type2

-- Collections

--- Collection1

--- Collection2

-- Man

--- Product1

--- product2

-- Woman

--- Product1

--- Product2

And then have a template setup for "Shoes" that will filter out the URL segments to handle addresses like:

site.com/catalogue/man/brand1/ or

site.com/catalogue/man/brand1/type2/collection2/

The only problem I see (other than the implementation of the actual template that will handle the "hard work") is that you need unique field values to display the products as they will all be under Man or Woman... so the client will not be able to have (or at least to visualize it on the list) products with the same value like "32" for a product that is a man shoe of type1 and from the collection1 and a man shoe of type1 from the collection2 (This actually happens, different collections having similar reference names for a specific product).

Of course we could implement an internal referencing system, that would not be a deal breaker.

zyON,

If your client needs to add additional brands, collections, types, then they will need access to those pages.

To make it less confusing, you can set them up underneath a parent page.

Categories

-- Brands

---- Brand 1

---- Brand 2

---- Brand 3

-- Types

---- Type A

---- Type B

---- Type C

-- Collections

---- Collection 1

---- Collection 2

---- Collection 3

If you set the parent page /categories to hidden, then it will show as a lighter color in the page tree, and searches won't return any of those pages.

I tend to use something like /tools/ or /config/ to keep things like this all grouped in one nice location.

Edited by zyON

Share this post


Link to post
Share on other sites

Hi zyON,

That is almost what I meant.

For your page tree:

Shoes

-- Men 

---- Product 1 (product template)

---- Product 2 (product template)

-- Women

---- Product 1 (product template)

---- Product 2 (product template)

Categories (these pages only a template with a title field)

-- Brands

---- Brand 1 (title only template)

---- Brand 2 (title only template)

-- Type

---- Type A (title only template)

---- Type B (title only template)

-- Collections

---- Collection A (title only template)

---- Collection B (title only template)

If your client needs to see additional information about each product in the page list, that's where you could use the Page List Better Label module

If they need even more detailed views, you might be able to make use of Diogo's Admin Custom Pages Module

Product Template:

<?php

include("./site/templates/head.inc);

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4");

       

    }

} else if ($input->urlSegment1){ // check if we are using URL segments
$products = $pages->find("parent=$page->path . $brand . $type . $collection");

} else {
// do something else for pages without URL segments
}

include("./site/templates/foot.inc);

Share this post


Link to post
Share on other sites

Hi zyON,

That is almost what I meant.

For your page tree:

Shoes

-- Men 

---- Product 1 (product template)

---- Product 2 (product template)

-- Women

---- Product 1 (product template)

---- Product 2 (product template)

Categories (these pages only a template with a title field)

-- Brands

---- Brand 1 (title only template)

---- Brand 2 (title only template)

-- Type

---- Type A (title only template)

---- Type B (title only template)

-- Collections

---- Collection A (title only template)

---- Collection B (title only template)

You client will only ever look at /categories if they need add new items. They will interact with it completely from the pageField in the product template.

If your client needs to see additional information about each product in the page list, that's where you could use the Page List Better Label module

If they need even more detailed views, you might be able to make use of Diogo's Admin Custom Pages Module

Product Template:

include("./site/templates/head.inc");

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4"); 
    echo $product->title;

    }

} else if ($input->urlSegment1){ // check if we are using URL segments
    $products = $pages->find("parent=$page->path . $brand . $type . $collection");
    foreach ($product as $p){
       echo $p->title;
    }

} else {
// do something else for pages without URL segments
}

include("./site/templates/foot.inc");
  • Like 1

Share this post


Link to post
Share on other sites

Wow. Thanks a lot. 

I'm trying to wrap my brain around the template concept as defined by PW, and what is still confusing me is if you define the template to handle the URL segments only at the product level, how will you handle the requests for example like this: site.com/catalogue/brand1? 

Hi zyON,

That is almost what I meant.

For your page tree:

Shoes

-- Men 

---- Product 1 (product template)

---- Product 2 (product template)

-- Women

---- Product 1 (product template)

---- Product 2 (product template)

Categories (these pages only a template with a title field)

-- Brands

---- Brand 1 (title only template)

---- Brand 2 (title only template)

-- Type

---- Type A (title only template)

---- Type B (title only template)

-- Collections

---- Collection A (title only template)

---- Collection B (title only template)

If your client needs to see additional information about each product in the page list, that's where you could use the Page List Better Label module

If they need even more detailed views, you might be able to make use of Diogo's Admin Custom Pages Module

Product Template:

<?php

include("./site/templates/head.inc);

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4");

     

    echo $product->title;

    }

} else if ($input->urlSegment1){ // check if we are using URL segments
    $products = $pages->find("parent=$page->path . $brand . $type . $collection");

    foreach ($product as $p){

       echo $p->title;

    }

} else {
// do something else for pages without URL segments
}

include("./site/templates/foot.inc);

Share this post


Link to post
Share on other sites

zyON,

I think this will all make sense if you start putting together a prototype.

Edit: sorry, posted at the same time as your question above.

Answering now...

:)

Share this post


Link to post
Share on other sites

zyON,

I'll have to get back to you on this—need to put my son to bed.

But, what your asking is possible - the simplest method is to create a page for /catalogue (no children) and give it a new template

that template can use different urlSegment logic to figure out what pages to display.

It's possible to do it without an actual page for /catalogue - using the same product template. That method gets a little more complicated.

I would need to revise my initial example some.

Share this post


Link to post
Share on other sites
I think this method will work even if you expand it out. I changed a few things up, but hopefully it makes sense.
Product pages use "template product", all other catalog pages use "template catalog".
 
Catalogue
-- Men 
---- Shoes 
------ Product 1
------ Product 2 
---- Hats 
------ Product 1
------ Product 2
 
-- Women
---- Shoes
------ Product 1
------ Product 2
---- Hats
------ Product 1
------ Product 2
 
Categories (these pages only a template with a title field)
-- Brands
---- Brand 1 (title only template)
---- Brand 2 (title only template)
-- Type
---- Type A (title only template)
---- Type B (title only template)
-- Collections
---- Collection A (title only template)
---- Collection B (title only template)
 
 
catalogue.php template & product.php template (same contents)
<?php

/* There might be a better way to accomplish this. The only reason to have 2 templates is to give find() a way      *  to only return the actual product pages, and not all the parent pages as well.
* 
* update: You may want to look into using the alternative template method:
* 
* 
* With this approach you would create a real file (product.php) for the product template,
* catalogue template would have no file associated, but point to product.php under the advanced settings tab.
*/

include("./site/templates/head.inc");
include("./site/templates/product-view.inc");
include("./site/templates/foot.inc");
 
product-view.inc
<?php

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4"); 
    echo $product->title;

} else if ($input->urlSegment1){ // check if we are using URL segments
    
    if ($input->urlSegment1 == "all"){
        $products = $pages->find("has_parent=$input->urlSegment2, template=product");
    } else {
        $products = $pages->find("has_parent=$page->path, template=product, . $brand . $type . $collection");
    }
    
    foreach ($products as $p){
       echo $p->title;
    }

} else {
    $products = $pages->find("has_parent=$page->path, template=product");
    foreach ($products as $p){
       echo $p->title;
    }
}
Looking at example URLS to see how the selector would get populated:
 
/catalogue/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1");
 
/catalogue/brand1/casual/
elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual");
/catalogue/brand1/casual/trendy/
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual, collection.name=trendy");
/catalogue/men/
$products = $pages->find("has_parent=men, template=product");
/catalogue/all/shoes/
$products = $pages->find("has_parent=shoes, template=product");
/catalogue/all/hats/
$products = $pages->find("has_parent=hats, template=product");
/catalogue/men/shoes/
no URL segment here, so the if/elseif are false, so we get:
$products = $pages->find("has_parent=/catalogue/men/shoes/, template=product");
/catalogue/men/shoes/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/men/shoes/, template=product, brand.name=brand1");
 
you get the idea. :)
 
Again, untested and coded in the browser — but hopefully thought out enough to get you started.
  • Like 7
  • Thanks 1

Share this post


Link to post
Share on other sites

renobird, 

Thanks, I wasn't really expecting such a compreehensive reply. It really helped me to understand the relationship between the pages, templates and url segments. 

Really put me into the right path. 

Again, brilliant piece of software, great community. Exciting.

I think this method will work even if you expand it out. I changed a few things up, but hopefully it makes sense.
Product pages use "template product", all other catalog pages use "template catalog".
 
Catalogue
-- Men 
---- Shoes 
------ Product 1
------ Product 2 
---- Hats 
------ Product 1
------ Product 2
 
-- Women
---- Shoes
------ Product 1
------ Product 2
---- Hats
------ Product 1
------ Product 2
 
Categories (these pages only a template with a title field)
-- Brands
---- Brand 1 (title only template)
---- Brand 2 (title only template)
-- Type
---- Type A (title only template)
---- Type B (title only template)
-- Collections
---- Collection A (title only template)
---- Collection B (title only template)
 
 
catalogue.php template & product.php template (same contents)
<?php

/* There might be a better way to accomplish this. The only reason to have 2 templates is to give find() a way      *  to only return the actual product pages, and not all the parent pages as well.
* 
* update: You may want to look into using the alternative template method:
* 
* 
* With this approach you would create a real file (product.php) for the product template,
* catalogue template would have no file associated, but point to product.php under the advanced settings tab.
*/

include("./site/templates/head.inc");
include("./site/templates/product-view.inc");
include("./site/templates/foot.inc");
 
product-view.inc
<?php

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4"); 
    echo $product->title;

} else if ($input->urlSegment1){ // check if we are using URL segments
    
    if ($input->urlSegment1 == "all"){
        $products = $pages->find("has_parent=$input->urlSegment2, template=product");
    } else {
        $products = $pages->find("has_parent=$page->path, template=product, . $brand . $type . $collection");
    }
    
    foreach ($products as $p){
       echo $p->title;
    }

} else {
    $products = $pages->find("has_parent=$page->path, template=product");
    foreach ($products as $p){
       echo $p->title;
    }
}
Looking at example URLS to see how the selector would get populated:
 
/catalogue/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1");
 
/catalogue/brand1/casual/
elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual");
/catalogue/brand1/casual/trendy/
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual, collection.name=trendy");
/catalogue/men/
$products = $pages->find("has_parent=men, template=product");
/catalogue/all/shoes/
$products = $pages->find("has_parent=shoes, template=product");
/catalogue/all/hats/
$products = $pages->find("has_parent=hats, template=product");
/catalogue/men/shoes/
no URL segment here, so the if/elseif are false, so we get:
$products = $pages->find("has_parent=/catalogue/men/shoes/, template=product");
/catalogue/men/shoes/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/men/shoes/, template=product, brand.name=brand1");
 
you get the idea. :)
 
Again, untested and coded in the browser — but hopefully thought out enough to get you started.
I think this method will work even if you expand it out. I changed a few things up, but hopefully it makes sense.
Product pages use "template product", all other catalog pages use "template catalog".
 
Catalogue
-- Men 
---- Shoes 
------ Product 1
------ Product 2 
---- Hats 
------ Product 1
------ Product 2
 
-- Women
---- Shoes
------ Product 1
------ Product 2
---- Hats
------ Product 1
------ Product 2
 
Categories (these pages only a template with a title field)
-- Brands
---- Brand 1 (title only template)
---- Brand 2 (title only template)
-- Type
---- Type A (title only template)
---- Type B (title only template)
-- Collections
---- Collection A (title only template)
---- Collection B (title only template)
 
 
catalogue.php template & product.php template (same contents)
<?php

/* There might be a better way to accomplish this. The only reason to have 2 templates is to give find() a way      *  to only return the actual product pages, and not all the parent pages as well.
* 
* update: You may want to look into using the alternative template method:
* 
* 
* With this approach you would create a real file (product.php) for the product template,
* catalogue template would have no file associated, but point to product.php under the advanced settings tab.
*/

include("./site/templates/head.inc");
include("./site/templates/product-view.inc");
include("./site/templates/foot.inc");
 
product-view.inc
<?php

$brand = "";
$type = "";
$collection = "";

if ($input->urlSegment1) $brand = ",brand.name=".$input->urlSegment1;
if ($input->urlSegment2) $type = ",type.name=".$input->urlSegment2;
if ($input->urlSegment3) $collection = ",collection.name=".$input->urlSegment3;

if ($input->urlSegment4) { // if Segment 4, then we know what page to get
    $product = $pages->get("name=$input->urlSegment4"); 
    echo $product->title;

} else if ($input->urlSegment1){ // check if we are using URL segments
    
    if ($input->urlSegment1 == "all"){
        $products = $pages->find("has_parent=$input->urlSegment2, template=product");
    } else {
        $products = $pages->find("has_parent=$page->path, template=product, . $brand . $type . $collection");
    }
    
    foreach ($products as $p){
       echo $p->title;
    }

} else {
    $products = $pages->find("has_parent=$page->path, template=product");
    foreach ($products as $p){
       echo $p->title;
    }
}
Looking at example URLS to see how the selector would get populated:
 
/catalogue/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1");
 
/catalogue/brand1/casual/
elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual");
/catalogue/brand1/casual/trendy/
$products = $pages->find("parent=/catalogue/, template=product, brand.name=brand1, type.name=casual, collection.name=trendy");
/catalogue/men/
$products = $pages->find("has_parent=men, template=product");
/catalogue/all/shoes/
$products = $pages->find("has_parent=shoes, template=product");
/catalogue/all/hats/
$products = $pages->find("has_parent=hats, template=product");
/catalogue/men/shoes/
no URL segment here, so the if/elseif are false, so we get:
$products = $pages->find("has_parent=/catalogue/men/shoes/, template=product");
/catalogue/men/shoes/brand1/
Brand1 is a url->segment1 so the elseif evaluates to true, and the selector gets populated to become:
$products = $pages->find("parent=/catalogue/men/shoes/, template=product, brand.name=brand1");
 
you get the idea. :)
 
Again, untested and coded in the browser — but hopefully thought out enough to get you started.
  • Like 1

Share this post


Link to post
Share on other sites
Again, brilliant piece of software, great community. Exciting.

Absolutely. :)

One thing to remember: there are lots of different ways to accomplish things with PW.

You might take this as a starting point and end up going a completely different (better) route.

:)

Share this post


Link to post
Share on other sites

Yes, I'm aware of that, but this was important to grasp the concepts in a real scenario.


One thing to remember: there are lots of different ways to accomplish things with PW.

You might take this as a starting point and end up going a completely different (better) route.

Share this post


Link to post
Share on other sites
Moved to this topic.

I've been working with ProcessWire in the last few weeks trying to come up with this kind of structure and getting used to the way PW works. 

I must say I'm pretty impressed with it... The flexibility and ease of use that it provides is mind boggling. 

Picking up on this example and the suggestions of how to structure all of this in PW, 

I've went with way of creating BRANDS and COLLECTIONS as stand alone pages that can be reused with Page selects within the PRODUCT templates.

Now, as I'm not defining BRANDS and COLLECTIONS as children of the Categories like MEN or WOMEN whats the best way to get the used BRANDS and COLLECTIONS within those Categories?

Ex: 

/catalogue/men/suits/

All the BRANDS and COLLECTIONS are available under:

/catalogue/brands

and

/catalogue/collections

How can I get the used BRANDS (brands that are assigned under /men/suits) and only those?

I guess I could use selectors to get 2 page arrays (one with the men suits and other with all the brands) and then compare and extract only the used ones, but that seems kind of costly... Is there another simple way to do it?

I know that I can also use straight SQL but before jumping on that I just wanted to get some opinions from the experts :).

Thanks.  

Edited by zyON

Share this post


Link to post
Share on other sites

If products are assigned directly to the brand or collection (rather than being assigned to the product) you could query it very easily…

$brands = $pages->find("template=brand, products.count>0"); 
// $brands now contains all brands that have at least 1 product 

…but I'm assuming that each page under /catalog/men/suits/ has a "brands" and "collections" page reference field (rather than brands and collections having a "products" field).  If that's the case, you can't query brands or collections directly since they don't have any field in their template that tracks what products they contain. You'd have to check them individually:

$brands = array(); 
foreach($pages->get("/catalogue/brands/")->children() as $brand) {
  $numProducts  = $pages->count("brands=$brand"); 
  if($numProducts > 0) $brands[] = $brand; 
}
// now the $brands array contains only brands that have products

Another, potentially more efficient way (depending on quantities) would be to compile the brands from the products:

$brands = new PageArray();
foreach($pages->find("template=product") as $product) {
  $brands->add($product->brands); 
}
// $brands now contains all brands that have at least 1 product

Lastly, I've solved this problem on the large scale by having an after(Pages::save) hook that calculates and stores (caches) the quantity directly in the brand, making it possible to query very easily. This is surprisingly easy to do, if you'd like more instructions let me know. 

  • Like 1

Share this post


Link to post
Share on other sites

Ryan,

That's exactly what I'm looking for. That's a clean and more efficient way (as mentioned in Soma's PW Cheatsheet, the count() method has less overhead as it doesn't load the pages).

You are right, each product under /catalog/men/suits/ has a brand and a collection as a page reference. 

Now about the after hook, that made me really curious and maybe it's a bit soon for my current level of PW hacking but if you can spare some time to give me some basic instructions or point me in the right direction I'll be really happy :).

Thanks.

If products are assigned directly to the brand or collection (rather than being assigned to the product) you could query it very easily…

$brands = $pages->find("template=brand, products.count>0"); 
// $brands now contains all brands that have at least 1 product 

…but I'm assuming that each page under /catalog/men/suits/ has a "brands" and "collections" page reference field (rather than brands and collections having a "products" field).  If that's the case, you can't query brands or collections directly since they don't have any field in their template that tracks what products they contain. You'd have to check them individually:

$brands = array(); 
foreach($pages->get("/catalogue/brands/")->children() as $brand) {
  $numProducts  = $pages->count("brands=$brand"); 
  if($numProducts > 0) $brands[] = $brand; 
}
// now the $brands array contains only brands that have products

Another, potentially more efficient way (depending on quantities) would be to compile the brands from the products:

$brands = new PageArray();
foreach($pages->find("template=product") as $product) {
  $brands->add($product->brands); 
}
// $brands now contains all brands that have at least 1 product

Lastly, I've solved this problem on the large scale by having an after(Pages::save) hook that calculates and stores (caches) the quantity directly in the brand, making it possible to query very easily. This is surprisingly easy to do, if you'd like more instructions let me know. 

Share this post


Link to post
Share on other sites
Now about the after hook, that made me really curious and maybe it's a bit soon for my current level of PW hacking but if you can spare some time to give me some basic instructions or point me in the right direction I'll be really happy

The way you do it is to first add a new integer field to your 'brand' template. Call it something like 'num_products'. You might choose to make it hidden, so that it doesn't appear in the editor (if you prefer that). Next edit your /site/templates/admin.php and add this above the include() line that's already there:

$pages->addHook('saveReady', null, 'updateBrandQuantities');
function updateBrandQuantities($event) {
  $page = $event->arguments(0); 
  if($page->template == 'brand') {
    // a 'brand' page is being saved
    $page->num_products = wire('pages')->count("template=product, brands=$page"); 
  } else if($page->template == 'product' && $page->isChanged('brands')) {
    // a 'product' page is being saved and 'brands' changed
    foreach($page->brands as $brand) $brand->save(); 
  }
} 

The trick is that if you already have a populated site, then you have to establish the quantities for the first time by saving all the 'brand' pages. You could temporarily add this code to one of your site's template files and view the page to populate them. After that, remove the code as it would no longer be needed.

foreach($pages->find("template=brand") as $brand) {
  $brand->save();   
}
  • Like 3

Share this post


Link to post
Share on other sites

@ryan,

Thanks a lot for the explanation and example. This should come in handy very soon...

Share this post


Link to post
Share on other sites

ryan,

I've successfully created the hook (not for updating the quantities, but to store the full url of the product, as it is composed of brands, collections, etc that don't belong directly to the hierarchy). It's working when you save the product in the admin but I can't seem to make it work to update the already created products by using the method you described. Can this be something related to the $page variable not being resolved somehow? 

The trick is that if you already have a populated site, then you have to establish the quantities for the first time by saving all the 'brand' pages. You could temporarily add this code to one of your site's template files and view the page to populate them. After that, remove the code as it would no longer be needed.

foreach($pages->find("template=brand") as $brand) {
  $brand->save();   
}

Share this post


Link to post
Share on other sites

It could be that it simply thinks nothing changed. You might need to give it a hint that something changed.

foreach($pages->find("template=brand") as $brand) {
  $brand->trackChange('num_products'); // add this line
  $brand->save();   
}

Share this post


Link to post
Share on other sites

Hmmm...

I'm getting this error now: 

Error: Exception: Can't save page 1152: /catalogo/bustos-torsos/homem/36b/: Call $page->setOutputFormatting(false) before getting/setting values that will be modified and saved.

I tried to add $page->setOutputFormatting(false) before the save, but then nothing happened, the value was not being updated.

Share this post


Link to post
Share on other sites

You need to set $brand not $page

$brand->of(false)

(Short version)

Share this post


Link to post
Share on other sites

Soma, yes, sorry I did not mention that I've changed the variable name like this:

foreach($pages->find("template=bustotorso-especial") as $page) {
  $page->of(false); // add this line
  $page->save();  

Still no luck :(

Share this post


Link to post
Share on other sites

Soma, yes, sorry I did not mention that I've changed the variable name like this:

foreach($pages->find("template=bustotorso-especial") as $page) {
  $page->of(false); // add this line
  $page->save();  

Still no luck :(

A little confused here...are you saying the above is the code you are using? $page is a unique keyword/variable in PW and I believe should not be used in the foreach as you have done?

Did you try this?

foreach($pages->find("template=bustotorso-especial") as $brand) {
  $brand->of(false); // add this line
  $brand->save(); 
Edited by kongondo
  • Like 1

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.