Developer forum

Forum » Templates » Related Groups loop

Related Groups loop


Reply

Hello,

A customers website has 2 relatedproducts groups, "Perfect match" and "BIG DEAL".
Both groups are showed on the product details pages.
I use the following loop:

<!--@LoopStart(ProductRelatedGroups)-->
 <!--@LoopStart(Products)-->
 <h2><!--@Ecom:Product.Number--></h2>
 <h1><!--@Ecom:Product.Name--></h1>  
 <a href="<!--@Ecom:Product.Link.Clean-->">
  <!--@Ecom:Product.ImageSmall.Default-->
 </a>
 <!--@LoopEnd(Products)-->
<!--@LoopEnd(ProductRelatedGroups)-->

The problem is that this loop shows both products groups.
Is there an way to create 2 loops, one for the "Perfect Match" products group and one for the "BIG DEAL" products group? So they can have different positions on the website.

Best Regards,

Roy


Replies

 
Reply
Hi Roy,

Just tried this out, but I can't find a way to do it ;-(

You could implement your own Related products List provider (http://engage.dynamicweb-cms.com/Admin/Public/Download.aspx?File=Files%2fFiler%2fDocumentation%2fDevelopment%2feCommerce%2f(en-US)+Related+Product+List+Providers.pdf) but that feels like a lot of work for something that should be built-in.

Alternatively, you can use CSS or JavaScript to change the appearance.

Maybe somebody from DW DK has a better idea?

Imar
 
Reply

Here is a few options...
 
1) CSS - Can be very difficult, especially if you need the display of products for each related group to be totally different (different data).

2) XSLT - Create an XSLT template to render each related group anywhere you want on the page.

3) .NET - Implement a ProductTemplateExtender and render separate loops named after the related groups.

Good luck :)

/Morten
 
Reply

Ha, yes, a ProductTemplateExtender. That would be relatively easy to do. Something like this should do (part of) the trick:

using System.Text.RegularExpressions;
using Dynamicweb.eCommerce.Frontend;
using Dynamicweb.eCommerce.Products;

namespace DeVierKoeden.DynamicwebSamples.Lib.TemplateExtenders.Ecom
{
  public class RenderRelatedProductsExtender : ProductTemplateExtender
  {
    const string defaultTag = "Ecom:Product.RelatedProducts.Groups.{0}";

    public override void ExtendTemplate(Dynamicweb.Templatev2.Template template)
    {
      foreach (ProductRelatedGroup group in Product.RelatedGroups)
      {
        string groupTagName = string.Format(defaultTag, GetValidName(group.Name));
        Dynamicweb.Templatev2.Template loopTemplate = template.GetLoop(groupTagName);
        foreach (Product product in group.Products)
        {
          new Renderer().RenderProduct(product, false, loopTemplate);
          loopTemplate.CommitLoop();
        }
      }
    }

    private static string GetValidName(string input)
    {
      return Regex.Replace(input, @"[^\w]", string.Empty);
    }
  }
}

Then you can use a tag like this where Testing is the name of the Related Products group:

<h1>Testing group</h1>
<!--@LoopStart(Ecom:Product.RelatedProducts.Groups.Testing)-->
  <h2><!--@Ecom:Product.Number--></h2>
  <h3><!--@Ecom:Product.Name--></h3
  <a href="<!--@Ecom:Product.Link.Clean-->">Click me</a>
<!--@LoopEnd(Ecom:Product.RelatedProducts.Groups.Testing)-->

Only problem is: the product link clean now links to Default.aspx?ID=0. Anyone any idea how to fix that?

Imar
 

 
Reply
Where would we be without Reflector... ;-)

The Renderer class has a ForcePageID method that you can use to assign the ID of the current (or any) page. Replace the contents of the inner foreach loop with this code"

Renderer renderer = new Renderer();
renderer.ForcePageID(Base.ChkInteger(Base.Request("ID")));
renderer.RenderProduct(product, false, loopTemplate);
loopTemplate.CommitLoop();

Now the page link works correctly and links to the same page with the product catalog as the current one.

Hope this helps,

Imar
 
Reply

This should work as well...
Renderer renderer = new Renderer(PageView.Current());

/Morten
 
Reply

Yep, that works as well. Here's the complete code again, with some optimizations to avoid related groups being rendered recursively (e.g. the related products for a product that's related to the one currently being displayed). I also added a LoopExists to avoid rendering the products when you haven't set up a tag. Since LoopExists returns true when you're using DwTemplateTags, the tag will always show up correctly:

using System.Text.RegularExpressions;
using System.Web;
using Dynamicweb.eCommerce.Frontend;
using Dynamicweb.eCommerce.Products;
using Dynamicweb.Frontend;

namespace DeVierKoeden.DynamicwebSamples.Lib.TemplateExtenders.Ecom
{
  public class RenderRelatedProductsExtender : ProductTemplateExtender
  {
    const string defaultTag = "Ecom:Product.RelatedProducts.Groups.{0}";
    const string httpContextKey = "RenderingRelatedProducts";

    public override void ExtendTemplate(Dynamicweb.Templatev2.Template template)
    {
      if (HttpContext.Current.Items.Contains(httpContextKey))
      {
        return;
      }
      HttpContext.Current.Items.Add(httpContextKey, true);
      foreach (ProductRelatedGroup group in Product.RelatedGroups)
      {
        string groupTagName = string.Format(defaultTag, GetValidName(group.Name));
        if (template.LoopExists(groupTagName))
        {
          Dynamicweb.Templatev2.Template loopTemplate = template.GetLoop(groupTagName);
          foreach (Product product in group.Products)
          {
            Renderer renderer = new Renderer(PageView.Current());
            renderer.RenderProduct(product, false, loopTemplate);
            loopTemplate.CommitLoop();
          }
        }
      }
      HttpContext.Current.Items.Remove(httpContextKey);
    }

    private static string GetValidName(string input)
    {
      return Regex.Replace(input, @"[^\w]", string.Empty);
    }
  }
}

You can then use the following template code. I added a HeaderStart to hide the heading when there are no related products.

<!--@LoopStart(Ecom:Product.RelatedProducts.Groups.Testing)-->
<!--@HeaderStart--><h1>Testing group</h1><!--@HeaderEnd-->
<h2><!--@Ecom:Product.Number--></h2>
<h3><!--@Ecom:Product.Name--></h3
<a href="<!--@Ecom:Product.Link.Clean-->">Click me</a>
<!--@LoopEnd(Ecom:Product.RelatedProducts.Groups.Testing)-->

Have fun!

Imar

 

 

You must be logged in to post in the forum