Product Detail Templates

This article describes all of the data available to the templates on the Product Listing/Category and Search pages.

Product Subscriptions

The following is a table of the subscription variables available from within the '$product' variable.

Variable NameTypeDescription
$product.product_durationIntegerFor subscription products, this is the duration over which this product's subscription will be issued on purchase.

If the product is not a Subscription product, then this value will be 0 (Zero) or not set at all.

Categories

The following is a table of the category variables available from within the '$product' variable.

Variable NameTypeDescription
$product.product_category_nameStringThe name of the Main Category this product belongs to.
$product.product_category_urlStringThe URL-safe name for the Main Category this product belongs to.
$product.categoriesArrayAn array of Category IDs for the categories to which this product belongs.
$product.product_main_categoryIntegerThe Internal ID used by Aurora to identify the Main Category this product belongs to.
$product.product_sub_categoryIntegerThe Internal ID used by Aurora to identify the last Sub-category this product belongs to within the product's Main Category.
$product.product_sub_category_nameStringThe name of the last Sub-category this product belongs to within the product's Main Category.

For example: A product in the Clothing > Men's > Shirts category where "Clothing" is its 'main' category will have a subcategory of "Shirts".
$product.product_sub_category_urlStringThe URL-safe name for the Main Category this product belongs to.

Prices

The following is a table of the pricing variables available from within the '$product' variable.

Variable NameTypeCurrencyDescription
$product.product_priceFloatDefaultThe base price of a single item of the product in question.
$product.product_taxFloatDefaultThe Tax due on the value held in the "product_price" variable.
$product.product_price_rrpFloatDefaultThe RRP of a single item of the product in question.
$product.product_price_wasFloatDefaultThe price the product used to be for a single item of the product in question.
$product.my_priceFloatSelectedThe base price of a single item of the product in question including any discounts applicable to the current customer.
$product.my_price_taxFloatSelectedThe Tax due on the value held in the "my_price" variable.
$product.my_price_rrpFloatSelectedThe RRP of a single item of the product in question.
$product.my_price_wasFloatSelectedThe price the product used to be for a single item of the product in question.
$product.price_savingFloatSelectedThe saving made on the product based on the difference between the RRP and the customers current price ("my_price").
$product.my_price_poundsFloatGBPThe base price of a single item of the product in question including any discounts applicable to the current customer.
$product.my_price_defaultFloatDefaultThe base price of a single item of the product in question including any discounts applicable to the current customer.
$product.product_tax_defaultFloatDefaultThe Tax due on the value held in the "my_price_default" variable.
$product.has_variation_price_differencesBooleanAllIf the product variations have differing prices this will be true. This can be used to show a 'from price' label or similar. Only stock available variations based on the Stock Action on Zero setting will be checked.

📘

In the table above, the "Currency" column describes whether the price held in the variable described will be:

  • Always in the default currency (Default)
  • Converted into the currently selected display currency (Selected)
  • Converted (if required) into some other currency (GBP, EUR, etc)

Finance Options

Variable NameTypeDescription
$finance_optionsArray ( finance_option )An array of available finance options.
$finance_options.x.codeStringThe code assigned to the Finance Product, as configured in the Aurora Back-end.
$finance_options.x.nameStringThe name configured for the Finance Product.
$finance_options.x.durationIntegerThe number of months over which the finance is spread for the Finance Product.
$finance_options.x.aprFloatThe APR charged for the Finance Product.
$finance_options.x.calculation_factorFloatThe calculation factor used to calculate monthly payments.

To work out how much a customer might pay a month, times the amount being borrowed by the calculation factor (don't forget to deduct any deposit required first).
$finance_options.x.minimum_spendFloatThe minimum value required to qualify for the Finance Product to be used.
$finance_options.x.pidIntegerThe PID assigned to the Finance Product, as configured in the Aurora Back-end.
$finance_options.x.pguidStringThe PGUID assigned to the Finance Product, as configured in the Aurora Back-end.
$best_finance_optionfinance_optionThe finance option considered to Aurora to be the 'best' option, based on the Longest Payment Duration and Cheapest Monthly Payment.

Stock

Stock Action on Zero

{$product.stock_action_on_zero}

Using this variable you can specify whether you want elements of the page to appear, such as the "Add to Basket" button.  For example, if the product had 0 stock, you could use the following code to determine what to do:

        {if ($product.stock_action_on_zero == '3' && $product.product_stock == '0')}
			I can display my pre-order button here.  
		{elseif ($product.stock_action_on_zero == '0' && $product.stock_stock == '0')}
			Display no button as they cannot purchase it now the stock is 0.  
		{else}
			Display my add to basket button here.  
		{/if}
Aurora DisplayVariable
Leave available, but cannot be purchased0
Leave available, and able to be purchased1
Hide2
Leave available, and can be pre-ordered3

Stock

{$product.product_stock} will reveal the stock for the master product.  

Shipping

The following is a table of the shipping variables available from within the '$product' variable.

Variable NameTypeDescriptionExample
$product.restock_datestringThe admins can either assign an actual restock date, or give an estimated length of time until the item is normally restocked. For the date format, please use PHP Date InfoThis item is due to be restocked on: {$product.restock_date|strtotime|date:"l, jS F Y"}
$product.normal_restock_daysRestocking daysWe normally restock this item in {$product.normal_restock_days} working {if $product.normal_restock_days h1. '1'}day{else}days

{/if}
$product.shipping_message_overrideThis is used if the admins want to feature a specific message on the details page relating to the shipping and only want that message to appear.<br>{if $product.shipping_message_override == '1'}<br> {if $product.shipping_message}<br> <p>{$product.shipping_message}</p><br> {/if}<br>{else}<br> Display normal shipping info<br>{/if}<br>
$product.shipping_groupsarrayA list of shipping groups assigned to a product. Coming soon<br>{if $product.shipping_groups}<br> Shipping Groups:<br> {foreach from=$product.shipping_groups item=shipping_group}<br> <div>{$shipping_group.name}</div><br> {/foreach}<br>{/if}<br>
$product.shipping_restrictions_modestringShipping mode, possible values: include | exclude<br>{if $product.shipping_restrictions_mode == 'include'}<br> <p>This product can be shipped to the following locations only:</p><br> ...<br>{else}<br> <p>This product cannot be shipped to the following locations:</p><br> ...<br>{/if}<br>
$product.banned_shipping_countriesarrayBanned shipping countries<br>{foreach from=$basket_item.product.banned_shipping_countries item="country"}<br> <li>{$country}</li><br>{/foreach}<br>
$product.allowed_shipping_countriesarrayAllowed shipping countries<br>{foreach from=$basket_item.product.banned_shipping_countries item="country"}<br> <li>{$country}</li><br>{/foreach}<br>

Display Next Day Shipping

You can clearly display when a customer may expect to receive their goods if next day delivery is available using the below code.

First of all we ensure it is in stock:

  {if $product.product_stock > 0}
   <p>Want guaranteed delivery by XXpm {$shipping_estimate}?

 Order in the next
    {if $order_by.hours}{$order_by.hours} {if $order_by.hours == '1'}hour{else}hours{/if}{/if}
    {if $order_by.hours AND $order_by.minutes > 0} and {/if}
    {if $order_by.minutes > 0}{$order_by.minutes} {if $order_by.minutes == '1'}minute{else}minutes{/if}{/if}

   and choose XXX on the checkout.

Breadcrumbsh1. h2. Standard Breadcrumbs

The standard breadcrumbs will operate in a way as you would expect - they will link back to the category you just came from.
This works on finding out their last category, and therefore if someone lands directly onto the page it will show nothing.

        {foreach from = $breadcrumbs item=breadcrumb name="breadcrumbs"}
            {if $smarty.foreach.breadcrumbs.last}
                <li>{$breadcrumb.name}</li>
            {else}
                <li><a href="{$breadcrumb.url}">{$breadcrumb.name}</a></li>
            {/if}
        {/foreach}

Breadcrumbs

Associated Categories

This will show every single other category that the product is in, line by line

{foreach from = $associated_categories item=associated_category name="associated_category"}
        <a href="{$associated_category.url}">{$associated_category.name}</a>{if !$smarty.foreach.associated_category.last}|{/if}
{/foreach}

Associated Categories v2

An improved version of Associated Categories, as it groups the items together, so that instead of displaying it such as: "Clothing" and then another one being "Leggings" it would display as:

Clothing | Leggings

<li>This product can be found in:</li>
{foreach from=$product.id|productInCategories item="associated_category" name="associated_categories"}
        <li><a href="{$associated_category.url}">{$associated_category.name}</a></li>
        {/foreach}
</ul>

Additional Fields

Variables

You can access any additional field from the template using:

{$product_fields.fieldname}

The fieldname is converted into a completely lowercase, characters and digits only version.

Some examples:
"Field Type" would become $product_fields.field_type

"Brand" would become $product_fields.brand

"Diamond Shape and Size" would become $product_fields.diamond_shape_and_size

Table

You can include all of the additional fields that an admin has entered for the product on the page like so:

If you are to use this feature, you will need to ensure that the jQuery tooltip.js is included

                {if $additionalFields}
                        <table id="additionalfields" cellpadding="0" cellspacing="0">
                        {foreach from = $additionalFields item=field}
                                <tr>
                                        <td class="light">
                                        {if $field.field_description}
                                        <a href="#" title="{$field.field_description|nl2br}" class="tooltip">{$field.field_name}</a>
                                        {else}
                                        {$field.field_name}
                                        {/if}
                                        </td>
                                        <td>{$field.field_value}</td>
                                </tr>
                        {/foreach}
                        </table>
                {/if}

Promotions

You can show what promotions the product applies to on the details page:

Variables

$xxx.promotion_name
This is the name that an admin has entered as the promotion in Aurora

$xxx.promotion_product_text
This allows for the admins to enter some specific text that they want to appear

{if $product.promotions}
2  {foreach from=$product.promotions item="promo"}
3    {if $promo.promotion_type != 'buy_x_get_y_free' AND $promo.promotion_product_text}
4      <div class="details_promo">{$promo.promotion_product_text}</div>
5    {/if}
6  {/foreach}
7{/if}

Attributesh1. Imagesh1. All images use MagicZoom and therefore must include the required files referenced below:

Images

👍

Please note that product images URIs can be obtained using product_image_uri in conjunction with the variables described below.

Variable NameTypeDescription
$product.images_by_label_idsArrayContains a Key/Value pair array of Image Label IDs and their Image IDs.
$product.images_by_label_nameArrayContains a Key/Value pair array of Image Labels and their Image IDs.
$product.grouped_product_images_by_label_idsArrayContains a Key/Value pair array of Image Label IDs and their Image IDs for all products that are included in the Product Group.

This will only include images for products that are currently available on the site for display.

This variable will not be present unless the Product Grouping system is active.
$product.grouped_product_images_by_label_nameArrayContains a Key/Value pair array of Image Labels and their Image IDs for all products that are included in the Product Group.

This will only include images for products that are currently available on the site for display.

This variable will not be present unless the Product Grouping system is active.
$product.image_idVariableThis contains the details for the main image for a product based on the image order alone (i.e. the image placed in 'order' of 1 or first will be here).
$product.image_id_2VariableThis contains the details for the secondary image for a product based on the image order alone (i.e. the image placed in 'order' of 2 or second will be here).

This is often used for image rollovers.
$product.listing_image_idVariableThis contains the details for the main image for a product for use on the Product (Category) Listing pages.

This value is controlled by the presence of the "Listing Image" Image Labels as described in the Grouping Products by Retailer (Style) Code guide and defaults to "image_id_1".
$product.listing_alternate_image_idVariableThis contains the details for the secondary image for a product for use on the Product (Category) Listing pages.

This value is controlled by the presence of the "Listing Alternate Image" Image Labels as described in the Grouping Products by Retailer (Style) Code guide and defaults to "image_id_2".

This is often used for image rollovers.
$product.grouped_product_images_to_product_idsArrayContains a Key/Value pair array of Image IDs and the Product IDs to which they belong.

This is most helpful when wanting to get additional meta information about a particular image's product.

For example, when showing a particular image, you might wish to also make it link through to its actual product details page.
$product.attribute_imagesArrayContains a Key/Value pair array of Attribute Values and their Image IDs.
$product.attribute_images.greenArrayContains an indexed array of Image IDs.

This is just an example
$product.attribute_images.redArrayContains an indexed array of Image IDs.

This is just an example
$product.attribute_images.etc...ArrayContains an indexed array of Image IDs.

 This is just an example

Main Image

We use {strip} to remove any whitespace that can cause issues in some browsers

{strip}
        {foreach from=$product_images key=count item=imageArray name=images}
            <ul class="productthumbs">
                {foreach from=$imageArray item=image}
                    <li>
                        <a href="/images/ac_product_images/product_image_data/resizeandpad:900:1111/{$image}" rel="zoom1" rev="/images/ac_product_images/product_image_data/resizeandpad:280:356/{$image}" title="" onclick="return false;">
                            <img src="/images/ac_product_images/product_image_data/resizeandpad:74:112/{$image}" alt="" {if $count > 0} style="display: none;"{/if}/>
                        </a>
                    </li>
                {/foreach}
            </ul>
        {/foreach}
    {/strip}

Thumbnails

Once again we use {strip} to remove any whitespace that can cause issues in some browsers

        {strip}
            {foreach from="`$product_images`" item="image" name="images"}
            {if $smarty.foreach.images.first}
            <a href="/images/ac_product_images/product_image_data/resizeandpad:900:1111/{$image[0]}" id="zoom1" class="MagicZoom MagicThumb mzoverride" rel="zoom-width:420px; zoom-height:500px">
                <img src="/images/ac_product_images/product_image_data/resizeandpad:280:356/{$image[0]}" alt="{$product.product_name}" />
            </a>
            {/if}
            {/foreach}
            {/strip}

Cross Sell, Up Sell and Related Lists

Displaying related products such as Cross-sells, Up-sells and Related Products as defined within Cross Sell, Up Sell and Related Lists can be achieved by utilising the following template variations:

  • $cross_sells
  • $upsells
  • $related_products

These all follow the same format and can be rendered as demonstrated in the following example:

{if $cross_sells}
    <h2>{site_text page="Product Details" part="Link: Also Bought"}</h2>
    {foreach from=$cross_sells item="related"}
        <a href="{$related.product_filename}"><img src="{product_image_uri product=$related width=180 height=180}" alt="{$related.product_name}" /></a><br />
        <a href="#" class="quicklook" rel="{$related.id}">{site_text page="Global" part="Link: Quick Look"}</a><br />
        <h2><a href="{$related.product_filename}">{$related.product_name}</a></h2><br />
        {if $related.product_price_rrp > $related.my_price}
            {site_text page="Global" part="Product Box Label: Was"}: <s>{$related.product_price_rrp|displayPrice}</s>
            {site_text page="Global" part="Product Box Label: Now"}: {$related.my_price|displayPrice}
            <br />
        {else}
            {$related.my_price|displayPrice}<br />
        {/if}
        {if $related.product_stock > 0}
            <b>In Stock</b><br />
        {else}
            <b>Pre Order Now {if $related.product.restock_date|strtotime > 0} - Due In {$related.product.restock_date|strtotime|date:"jS M"}{/if}</b><br />
        {/if}
        {if $related.product_rating > 0}
            {assign var='product_rating' value=$related.product_rating|productRating}
            <img src="/templates/{$templates_dir}/_images/template/star_{$product_rating}.png" alt="" width="74" height="14" /><br />
        {/if}
    {/foreach}
{/if}

Wishlist

The purpose of the wishlist is to engage the customer with the website, and should therefore make it easier to save their details

If they have selected any attributes, it should pass those over and save the exact product selected. Furthermore, the popup should display exactly what they've added and potentially recommend other products they may like at this stagePrinth1. Every details page should have a print friendly version of the page designed and include a link to being able to print it Leave a Messageh1. This should never be directly on the details page, as it is unnecessary clutter that can hinder SEO. Instead you should link to it like so:

<a href="/products/leaveamessage?product\_id={$product.id}" class="leaveamessage" rel="nofollow"><img src="/templates/{$templates\_dir}/\_images/buttons/leaveamessage.gif" alt="" /></a>

To edit the form that appears, you must go to:

templates/DOMAINNAME/products/leaveamessage.tpl.htmlE-mail to Friendh1. <a href="/products/emailtofriend?product\_id={$product.id}" id="emailtofriend" rel="nofollow"><img src="/templates/{$templates\_dir}/\_images/buttons/emailtoafriend.gif" alt="" /></a>

Review Rating

VariableDescriptionExample
{$product.total_reviews}The total number of reviews that are live for this product15
{$product.product_rating}The total rating divided by the number of reviews, to give the overall. e.g. 6 reviews in total; 5 reviews with a rating of 5/5 and one with a rating of 4/5 = 29/6 = 4.83, rounded to 4.84.3

Displaying Product Rating

{if $product.total_reviews > 0}      
{assign var='product_rating' value=$product.product_rating|productRating}
      <img src="/templates/{$templates_dir}/_images/template/star_{$product_rating}.png" alt="" width="74" height="14" property="v:rating" content="{$product_rating}" />
{/if} 

The logic of productRating works by taking the digits after the decimal and deciding whether to round up depending on whether it is greater or equal to 0.50.  If it is, it will round up to the nearest full digit, otherwise it will round down.  If you wanted an alternative, you could easily create your own method using Smarty logic, such as the below:

{$product.product_rating|round:"0":"PHP_ROUND_HALF_UP"} 

Full Code Example

    {if $product.total_reviews > 0}
  <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating" xmlns:v="http://rdf.data-vocabulary.org/#" typeof="v:Review-aggregate">
       <span rel="v:rating" style="display: none;">
         <span typeof="v:Rating">
         <span itemprop="ratingValue" property="v:average">{$product.product_rating|number_format:"1"}</span> out of <span itemprop="reviewCount" property="v:best">5</span>
       </span>
       </span>
    <p class="details_stars">
      {assign var='product_rating' value=$product.product_rating|productRating}
      <img src="/templates/{$templates_dir}/_images/template/star_{$product_rating}.png" alt="" width="74" height="14" property="v:rating" content="{$product_rating}" />
    </p>
    <div class="details_stars_number"><a href="#reviews" rel="nofollow" class="details_view_reviews_link read_review">Read <span property="v:count">{$product.total_reviews}</span> {if $product.total_reviews == '1'}{site_text page="Product Details" part="Text: Review" }{else}{site_text page="Product Details" part="Text: Reviews" }{/if}</a><a href="{if $language_iso}/{$language_iso}{/if}/products/reviews/write/{$product.id}" rel="nofollow" class="details_view_reviews_link write_review" title="">{site_text page="Product Details" part="Link: Write a Review" }</a></div>
        <div class="clear"></div>
    </div>
  {if}

Reviews

Please see Product Reviews

Q&A

Please see Questions and Answers