Displaying Similar Products

A common strategy on e-commerce sites is to include a list of similar products on the product detail page. The list can offer alternative options to customers helping them find the “right” product faster.

Displaying the list may also lead to more sales as the customers viewing the product page are likely to be interesed in similar items.

You may even include multiple lists. For example, you can have one list of products from the same brand and aother list of products from the same categories.

On this post I’ll go through how you can achieve this in Perch Shop. And with the help of the productlist field type, I’ll explain how you can manually select similar products or create a list of accessories.

Get Product’s data

On the product page, use perch_shop_product() to get the product and use the skip-template option to return the product’s data in an array.

$product_data = perch_shop_product(perch_get('s'), [
    'skip-template' => true,
]);

We’re using perch_get() to get the product slug from the URL. If you are new to Perch, I suggest you read the function’s documentation as it is one of the most used utility functions in Perch.

Now all the product data we need are in the array $product_data. If you want to examine and see what data is available, you can print_r($product_data).

Assuming none of your products share the same slug, $product_data will only contain one array at $product_data[0] containing the data.

if(is_array($product_data)) {
    $cats = $product_data[0]['category'];
    $brand = $product_data[0]['brand'];
}

$cats is an array of category paths. $brand is a brand ID.

Displaying the lists

Now we can do some filtering with perch_shop_products() to display our lists. I covered some of the basics of filtering products in a previous post: User-filtered Product Listing.

Same Categories

The following gets a list of products in the same categories as the product’s:

perch_shop_products([
    'category' => $cats,
    'category-match' => 'any',
]); 

However, the above also includes the product on the current page. We need to use the filtering options to exclude it:

perch_shop_products([
    'category' => $cats,
    'category-match' => 'any',
    'filter' => 'slug',
    'match' => 'neq',
    'value' => perch_get('s'),
]); 

You can use the count option to limit the number of products in the list. And if you want to randomise the list, you can use 'sort-order' => 'RAND'.

Same Brand

Here we have to apply multiple filters to get products from the same brand AND exclude the product on the page:

// filter to exclude product on page
$filters[] = [
    'filter' => 'slug',
    'match' => 'neq',
    'value' => $productSlug,
];

// filter to get products from the same brand
$filters[] = [
    'filter' => 'brand',
    'match' => 'eq',
    'value' => $brand,
];

perch_shop_products([
    'filter' => $filters,
    'filter-mode' => 'ungrouped',
    'count' => 5,
]); 

Manually selected

Now we’ll use the productlist field type to select related products from the product edit form.

Let’s create a list of products as accessories. In your product template product.html:

<perch:shop id="accessories" type="productlist" label="Accessories" suppress="true" />

We can get the accessories the same way as Categories and Brands.

$accessories = $product_data[0]['accessories'];

// glue together the slugs as 'product1,product-number-two,product3'
$accessory_slugs = implode(',', $accessories);

perch_shop_products([
    'filter' => 'productSlug',
    'match' => 'in',
    'value' => $accessory_slugs,
]);

It is probably wise to check whether the field exists (especially if you add a custom field to the template):

if(isset($product_data[0]['brand'])) {
    $brand = $product_data[0]['brand'];
    .
    .
    .
}

if(isset($product_data[0]['accessories'])) {
    $accessories = $product_data[0]['accessories'];
    .
    .
    .
}
link