Listing products within a category

This is a Category's most important role and a Category may have zero or more products. Accessing product data is the same whether the product data is filtered or not.

The products variable supplied contains a ProductCollection object - a collection of Product objects.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
            <!-- Title and Description -->
            <div class="product-blurb">
                <strong>{{ product.title }}</strong><br>
                {{ product.description.nl2br() }}
            </div>
        </a>
    </li>
<?ev } ?>
</ul>


Showing a product's primary image

A Product may have any number of photos, but may only have one primary image - product.thumbnail. Using the <ev:img> tag dramatically simplifies a variety of operations:

  • Image resizing within a bounding area
  • Image cropping
  • Automatic utilisation of a CDN

Whilst your theme design may have an aspect ratio preference, many merchants obtain photos from a number of sources with varying image dimensions. Consequently, image cropping is generally undesirable and we recommend resizing images sympathetically within a bounding area. Fortunately <ev:img> makes this ridiculously easy.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
        
            <!-- Primary Image -->
            <div class="product-image">
                <ev:img src="{{ product.thumbnail }}" width="400" maxheight="300" />
            </div>
            
            <!-- Title and Description -->
            <div class="product-blurb">
                <strong>{{ product.title }}</strong><br>
                {{ product.description.nl2br() }}
            </div>
        </a>
    </li>
<?ev } ?>
</ul>


In the example above we're stipulating our image must fit within a maximum bounding area of 400×300 pixels (a standard aspect ratio of 4:3). If the image is larger than this it will be resized accordingly without being cropped. Neither the width nor height attribute will be rendered within your html, allowing you to gracefully handle images responsively within your CSS.

How do I get a CDN URI?

This is automated by Evance. For more information on how this is rendered take a look at the <ev:img> documentation.

Learn more about <ev:img>


Available on Github

The code example above may be incomplete for easy reading.
A more complete code sample category/product.partial.evml is available on Github.

Go to Github


Adding product prices

Evance supports a range of price settings for Products, so it is worth exploring the Product and Price object documentation. In the example below we're just going to implement the basics to highlight how to get started.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
        
            <!-- Primary Image -->
            <div class="product-image">
                <ev:img src="{{ product.thumbnail }}" width="400" maxheight="300" />
            </div>
            
            <!-- Title and Description -->
            <div class="product-blurb">
                <strong>{{ product.title }}</strong><br>
                {{ product.description.nl2br() }}
            </div>
            
            <!-- Pricing -->
            <div class="product-pricing">
                <?ev if (product.price) { ?>
                    <ul>
                        <!-- Recommended Retail Price -->
                        <?ev if (product.rrp) { ?>
                        <li>RRP {{ product.rrp }}</li>
                        <?ev } ?>
                        
                        <!-- Standard List Price -->
                        <?ev if (product.isOffer) { ?>
                        <li>WAS {{ product.listPrice }}</li>
                        <?ev } ?>
                        
                        <!-- Current Price -->
                        <li>{{ product.price }}</li>
                    </ul>
                <?ev } ?>
            </div>
        </a>
    </li>
<?ev } ?>
</ul>

Product price partial available on Github

The example above illustrates the basics of showing product price information, but is not complete. A more complete example of an EVML product price partial is now available on Github.

View on Github


Paginating products in categories

A category is not limited to the number of products it may host. Some of our merchants sell thousands of products on a single store, so pagination plays an important role in categories. The number of products you show per page may depend on the design of your template. 

First, set the default number of products to show per page in your ~/theme/config/templates.json file by adding a "perpage" property to your category template config.

{
    "category": {
        "index": {
            "title": "Default",
            "path": "~/theme/category/index.evml",
            "perpage": 24
        }
    }
}

Then, we can add pagination to our template. The easiest way to implement pagination is with the <ev:pagination> tag.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
            ...
        </a>
    </li>
<?ev } ?>
</ul>

<!-- Pagination -->
<ev:pagination />

The <ev:pagination> tag automates a number of calculations on your behalf and is the fastest way to get started.

Learn more about <ev:pagination>

Changing the number of products per page

Users may want to have the option to view more, less or all products on a single page. The simplest way to implement a select box to facilitate a user's preference is with the <ev:perpage> tag. This tag automates a number of calculations on your behalf allowing it integrate with category pagination, sorting and filtering.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
            ...
        </a>
    </li>
<?ev } ?>
</ul>

<!-- Pagination -->
<ev:pagination />

<!-- PerPage Selection -->
<ev:perpage options="24,48,96,0" />

In the example above we're allowing users to view 24, 48, 96 or all products on a single page. You should always include the perpage setting value added in your ~/theme/config/templates.json config within the comma separated list of options.

Sorting products

Product categories accept sort strings to apply a sort and order (ascending or descending). Users may prefer to browser products by price, for example. The easiest way to implement a sort preference box is with the <ev:sortpage> tag. This tag automates a number of calculations to integrate neatly with pagination and product filtering.

<ul>
<?ev for (var product of products) { ?>
    <li>
        <a href="{{ product.url }}">
            ...
        </a>
    </li>
<?ev } ?>
</ul>

<!-- Pagination -->
<ev:pagination />

<!-- PerPage Selection -->
<ev:perpage options="24,48,96,0" />

<!-- Sort Selection -->
<ev:sortpage>
    <option value="price:asc">Price low to high</option>
    <option value="price:desc">Price high to low</option>
    <option value="sequence:asc">By Recommendation</option>
    <option value="age:desc">Newest to oldest</option>
    <option value="age:asc">Oldest to newset</option>
    <option value="title:asc">Title A-Z</option>
    <option value="title:desc">Title Z-A</option>
    <option value="rating:asc">Rating low to high</option>
    <option value="rating:desc">Rating high to low</option>
</ev:sortpage>

The example above illustrates how to add all available sort strings for product sorting. You may change the order and labels of the <option> elements, but their values must remain the same.

Why aren't rating options showing?

Product reviews are optional and can be turned on or off by a website administrator. <ev:sortpage> will ignore rating options automatically if the administrator has disabled product reviews. Try turning product reviews on - your rating sort options should appear.