Developer forum

Forum » Ecommerce - Standard features » List of products on product page

List of products on product page

Peter Gustafsson
Reply
I want to list products that are connected to the same group on the product page.
The listing should look exactly the same as the actual listing  on the listing page, so using the same template is actually ok if that is possible.
Is there a good way to do this?

Right now I am doing like this:
public class MyProductTemplateExtender : ProductTemplateExtender{
    public override void ExtendTemplate(Dynamicweb.Rendering.Template template) {
        
        ProductCollection combined = new ProductCollection();
        foreach (Group asgrp in Product.Groups)
        {
            if (asgrp.Products.Count>0)
                combined.AddRange(asgrp.Products, false);
        }
        Dynamicweb.Rendering.Template looptemp = template.GetLoop("testloop");
        if (looptemp!=null) {

            foreach (Product pr in combined)
            {
                looptemp.SetTag("temp", pr.Name);
                looptemp.CommitLoop();
            }
        }
}
}
But with this setup I have to recreate all the product tags manually.
Is there some better way to include such a listing?
Can I perhaps somehow use the function looptemp.SetTags(DataRow)? Is it possible to get the product's datarow and make DW automatically  create all the usual tags based on that datarow for a given product?

Replies

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hi there,

You can use the Renderer class to handle this. Something like this should work:
Dynamicweb.eCommerce.Frontend.Renderer renderer = new Dynamicweb.eCommerce.Frontend.Renderer();
renderer.RenderProduct(pr, true, loopTemp);

There's also a RenderProducts (plural) method available that accepts a ProductCollection and a template.

Hope this helps,
 

 

Imar
 
Peter Gustafsson
Reply
Are you sure it just renders all that tags that are otherwise available in a product so that I can use them in a template, (that it doesn't render the whole product, producing a single html string)?

In that case, how do I use it correctly? Right now it gives me StackOverflow exceptions, so I guess the same extender is called inside the RenderProducts as well. How do I prevent that? 

thanks.


Update:
I have tried to looptemp.SetTag() to some predefined value in the loop before I call RenderProduct, and then in the beginning of the extender routine check for that tag with template.TagExists(), and return directly if it does exist to prevent infinite recursion, but it still gives StackOverflow errors... What gives?
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
This post has been marked as an answer

Hi there,

Sorry for my slow response. Somehow I overlooked this thread.

The StackOverflow exception makes sense. When you render a product in the extender, you trigger the ProductTemplateExtender to be called again. This calls your render code which in turn causes the ProductTemplateExtender to be called again. And this continues until you run out of stack space.

The solution to this is simple, but may be a hard to find out. All of the extender code shares the same HttpContext. This object has a convenient Items collection you can use to determine if you're already inside the extender code. Something like this would work:
 

if (!HttpContext.Current.Items.Contains("SomeKey"))
{
  System.Web.HttpContext.Current.Items.Add("SomeKey", "SomeValue");
  // Your code goes here
  System.Web.HttpContext.Current.Items.Remove("SomeKey");
}
 
The names of the key (SomeKey) and the value (SomeValue) are irrelevant and you can make them up yourself. As long as the key you use to check whether there is a value or not is consistent with the one you set.

Now, when this code runs, Contains will return false. Then you add an item to the Items collection, and call Render which calls ExtendTemplate again. However, now there will be an item so Contains returns true and the code will exit. Then your original call of ExtendTemplate completes and removes the item from  the HttpContext so any other code for the next product can run successfully.

Hope this helps,

Imar

 
Votes for this answer: 0
 
Peter Gustafsson
Reply
Thank you, it now works.
It was just strange the template object sent to the RenderProduct function is not the same that the template extender routine gets. Anyway, thanks for your help. 

 

You must be logged in to post in the forum