Search

Hi

I have the following setup for an online store:

3 sections:

  • Product Categories
  • Product Types
  • Products

They are related as followed:

A product category can have many product types.

A product type can have many products

My store runs off a single xsl file and I would like to keep it that way. The page is called store and has 2 url parameters:

mydomain.com/store/category/type

The problem I am trying to solve is that some product categories only have one product type. In this scenario I would like the link on the category index page to link straight to product list for the one product type for that product category.

Hopefully a real world example will help explain:

  • Product Category: Surveys

  • Product Type: Car Survey

At the moment the product category "surveys" has only one product type "car survey". In this this scenario I would like to show all the "car survey" products instead of the product type index page.

However when I add a new product type, for example "Bike Survey" it should show the index page of the product types.

The second scenario of more than one product type I can solve but the case with just the 1 product type has left me scratching my head.

Any help with this would be greatly appreciated :)

I'm not very clear of your comment, would you mind rephrase it?

It's a simple matter of using count() in your xsl using an if or choose block to see how many entries are returned in your types datasource. You can also test on the url parameters for their presence.

That way you can display a template for a product list, or a template for a types list.

Without seeing your current xsl and xml that's all I can really say on it.

Thanks for the use of the count suggestion @designermonkey - thats got it :)

Thought I might as well detail my problem and solution in more detail in case anyone else comes across it in the future.

The problem I was having was on the category index list page I wanted the links for each category to point to the product type index page of that particular category unless there was only 1 product type in which case it should link to the product index page of that 1 product type.

What I was missing was a datasource which listed all the product types grouped by product category. I created this data source and then used the following xslt templates. First the main data template works out which of the parameters are present and calls the correct templates.

<xsl:template match="data"
<xsl:choose>
    <xsl:when test="$category=''">
        <xsl:apply-templates select="product-type-names/product-category"/>
    </xsl:when>

    <xsl:when test="$type=''">
        <xsl:apply-templates select="product-types-by-category"/>
    </xsl:when>

    <xsl:otherwise>
        <xsl:apply-templates select="products-by-product-types"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

The product type by names datasource is grouped by product category. So for each of the product categories it counts the number of entries. When there is only 1 entry then it calls the product-categories/entry templates with mode="equals1" otherwise it calls the default product-categories/entry template.

<xsl:template match="product-type-names/product-category">
<xsl:variable name="cat-name">
    <xsl:value-of select="@handle"/>
</xsl:variable>
<xsl:choose>
    <xsl:when test='count(entry)=1'>
        <xsl:apply-templates select="/data/product-categories/entry[name/@handle=$cat-name]" mode="equals1"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="/data/product-categories/entry[name/@handle=$cat-name]"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

For the case when there is more than 1 product type in a product category we spit out the name and short description and link to the product type index page:

<xsl:template match="product-categories/entry">    
<h2><xsl:value-of select="name"/></h2>
        <p><xsl:value-of select="short-description"/></p>
<a href="{$root}/{$current-page}/{name/@handle}"><xsl:value-of select="name"/></a>
</xsl:template>

When there is only 1 product type we link directly to the product list index page:

<xsl:template match="product-categories/entry" mode="equals1">
<h2><xsl:value-of select="name"/></h2>
<p><xsl:value-of select="short-description"/></p>
<xsl:variable name="cat-name">
            <xsl:value-of select="name/@handle"/>
        </xsl:variable>
        <a href="{$root}/{$current-page}/{name/@handle}/{/data/product-type-names/product-category[@handle=$cat-name]/entry/name/@handle}" >                    <xsl:value-of select="name"/>
        </a>
</xsl:template>

Here is the reduced xml that is attached to the page:

<product-type-names>

Product Types

  <entry id="278">

   <name handle="product-type-1">Product Type 1</name>

   <product-category>

     <item handle="product-category-1">Product  Category 1</item>

   </product-category>

 </entry>

</product-category>

Product Categories

 <name handle="product-category-1">Product Category 1</name>

 <short-description handle="this-is-the-sort-description">This is the short description</short-description>

</product-categories>

Thanks again for the help :)

Thanks for the writeup, that will be useful for others to read.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details