display items from different categories

Topics: General, Visual editor, XSLT
Aug 1, 2011 at 10:02 AM

Hi,

I have the following situation: i have a datatype "Category" and a datatype "Products". So in category i have defined different categories and the products from the datatype are related to these categories. I want to create a function to display something like this:

Category 1 name:

Product 1, 2, ,3 , 4 (first 4 products)

-----------------------

Category 2 name:

Product 1, 2, ,3 , 4 (first 4 products)

-----------------------

If i'm using a basic functionality to display products from all the categories ordered by category ID i'm getting all the products in a row and i don't know how to put a break when the items from one category fisished and the others from the next category start.

Please advice!

Thank you!

Aug 1, 2011 at 11:49 AM

Hello,

Below is en example of one of the XSLT grouping technique:

For example, you have XSLT with GetProductXML function call, make sure that Selected fields contains @Category, @Category.Name fields. Then the XSLT Template will be something like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
 
  <xsl:variable name="products" select="/in:inputs/in:result[@name='GetProductXml']" />
 
  <xsl:key name="by-category" match="Product" use="@Category.Name" />
 
  <xsl:template match="/">
    <html>
      <head>
        <!-- markup placed here will be shown in the head section of the rendered page --></head>
      <body>
        <div>
          <xsl:for-each select="$products/Product[generate-id(.)=generate-id(key('by-category',@Category.Name))]/@Category.Name">
           <xsl:sort />
            <h2>
              <xsl:value-of select="." />
            </h2>
            <ul>
              <xsl:for-each select="key('by-category', .)[position()&lt;5]">
               <li>
                  <xsl:value-of select="@Name" />
                </li>
              </xsl:for-each>
            </ul>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Aug 2, 2011 at 10:59 AM

Hi Inna,

And thank you very much for your help. I tried the function you sent me but the output is empty.

This is my function:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
 
  <xsl:variable name="products" select="/in:inputs/in:result[@name='GetKIVideoDBXml']" />
 
  <xsl:key name="by-category" match="Product" use="@categoryDetailed.name" />
 
  <xsl:template match="/">
    <html>
      <head>
        <!-- markup placed here will be shown in the head section of the rendered page --></head>
      <body>
       
        <div>
          <xsl:for-each select="$products/Product[generate-id(.)=generate-id(key('by-category',@categoryDetailed.name))]/@categoryDetailed.name">
           <xsl:sort />
            <h2>
              <xsl:value-of select="." />
            </h2>
            <ul>
              <xsl:for-each select="key('by-category', .)[position()&lt;5]">
               <li>
                  <xsl:value-of select="@name" />
                </li>
              </xsl:for-each>
            </ul>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

I uploaded a printscreen with my function call...

 

Thank you

<!--?xml version="1.0" encoding="UTF-8"?-->

 
  
 
  
 
  
    
      
        <!-- markup placed here will be shown in the head section of the rendered page -->
      
       
        

Aug 2, 2011 at 11:00 AM

the link for the print screen HERE

Aug 2, 2011 at 11:10 AM

Hello,

Show me also the screenshot of the Preview tab, I just want the see the result of the /in:inputs/in:result[@name='GetKIVideoDBXml'] call.

Aug 2, 2011 at 12:12 PM

Hi Inna,

I uploaded 2 printscreens for the Preview tab : picture1, picture2

Thanks.

--

Bogdan

Aug 2, 2011 at 12:20 PM

Ok, thanks.

As I see your /in:inputs/in:result[@name='GetKIVideoDBXml'] result contains KIVideoDB nodes (my example has Product nodes), So try next fixes:

 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
 
  <xsl:variable name="products" select="/in:inputs/in:result[@name='GetKIVideoDBXml']" />
 
  <xsl:key name="by-category" match="KIVideoDB" use="@categoryDetailed.name" />
 
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
       
        <div>
          <xsl:for-each select="$products/KIVideoDB[generate-id(.)=generate-id(key('by-category',@categoryDetailed.name))]/@categoryDetailed.name">
           <xsl:sort />
            <h2>
              <xsl:value-of select="." />
            </h2>
            <ul>
              <xsl:for-each select="key('by-category', .)[position()&lt;5]">
               <li>
                  <xsl:value-of select="@name" />
                </li>
              </xsl:for-each>
            </ul>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

 

 

Aug 2, 2011 at 12:27 PM

Inna,

YOU ARE BRILLIANT!!!

Thank you so much for your help

Aug 2, 2011 at 12:38 PM
Edited Aug 2, 2011 at 12:38 PM

You are welcome!

Thank you also for using our CMS :)

Aug 2, 2011 at 2:00 PM

Inna,

Sorry to bother you again, i have one more question:

after my 4 items from a category i want to have a link like <a href="allitems.aspx?category_id={@categoryDetailed.Id}">See all items</a>

I've tried to put it after the second for-each (the one who renders the 4 items) but it seems that @categoryDetailed.Id is not processed.

How can i make this?  It's not even working if i replace the Id with @categoryDetailed.name ...


Thanks

Aug 2, 2011 at 2:36 PM

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in lang f">
 
  <xsl:variable name="products" select="/in:inputs/in:result[@name='GetKIVideoDBXml']" />
 
  <xsl:key name="by-category" match="KIVideoDB" use="@categoryDetailed.name" />
 
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
       
        <div>
          <xsl:for-each select="$products/KIVideoDB[generate-id(.)=generate-id(key('by-category',@categoryDetailed.name))]">
           <xsl:sort />
            <h2>
              <xsl:value-of select="@categoryDetailed.name" />
            </h2>
            <ul>
              <xsl:for-each select="key('by-category', @categoryDetailed.name)[position()&lt;5]">
               <li>
                  <xsl:value-of select="@name" />
                </li>
              </xsl:for-each>
             <a href="allitems.aspx?category_id={@categoryDetailed.Id}">See all items</a>
            </ul>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Aug 2, 2011 at 3:40 PM

Thank you very much, again :)