Josselin Dionisi - Freelance developer

Sylius: Show last viewed items to users

ionicons-v5-k Josselin Dionisi Feb 24, 2025
105 reads Level: Confirmed

Hello everyone and thank you for clicking on this article 😊

I don't know about you, but there's a little shopping site called Amazon that I find really handy. Today I wanted to tell you about something you can implement on Sylius that can make all the difference to your e-commerce.

"Wait a minute, you mean that Amazon is developed with Sylius?

No, Amazon is much older and existed before the very idea of Sylius. 😛

On the other hand, these days, for an e-commerce store just starting out, Sylius appears to be one of the best choices. And guess what? Sylius is based on Symfony (I know we've already told you here, but a reminder never hurts).

Setting up a visit history

The first step in this module is to be able to retrieve each article that the customer consults. To do this, we're going to implement a history system based on Sylius events, as well as a dedicated entity.

Let me explain:

As with Symfony, Sylius uses events that are triggered by certain actions and that we can easily listen to. To do this, we use EventSubscriber or EventListener.

In our case study, we're going to use an EventListener based on the route that displays a product. Yes, because logically what we want is to perform an action when the user arrives on a particular product page.

To do this, we can use the event that triggers the Kernel (in other words, Symfony's very core) and capture the request that has been made.
Then, thanks to the Request object, we can easily access the name of the route that has just been visited and check whether we're on a product page or not.

"Super user visits product pages on an e-commerce site. But what do we do with this now?"

We now need to record this information in our database to keep a history of products consulted by the user and therefore likely to be of interest to him.

Thanks to the url slug, we can quickly find the product that has been consulted, and since the user is logged in, we can also record his identity in a CustomerHistory Entity that we have previously defined.

Retrieve the last products consulted by the user

Ok now, each time a customer visits a product page, we record the information in the database. That's great, but we still need to process this information to display our module.

To do this, we'll declare a new service whose role will be to retrieve the last products consulted for the current user via a query.

Here, we're limiting the number of results returned to 4, as this is the number we'll be displaying on the home page to remain consistent with the default Sylius template.

Speaking of templates, this is the last stage of our little adventure. 😛

Sylius uses hooks in its templates, and as we want to display our module on the home page first (after the banner, of course), we're going to modify the home page hook. To do this, go to the

1
config/packages/_sylius.yaml

At the very end of this file you'll find the sylius_twig_hooks key we're interested in.

We'll retrieve the default Sylius configuration for the homepage and add our new module as follows

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
        'sylius_shop.homepage.index':
            banner:
                template: '@SyliusShop/homepage/banner.html.twig'
                priority: 300
                
            #On ajoute notre module après la bannière
            history:
                template: '@SyliusShop/homepage/history.html.twig'
                priority: 250
                
            latest_deals:
                component: 'sylius_shop:product:list'
                props:
                    limit: 4
                    template: '@SyliusShop/product/common/list.html.twig'
                configuration:
                    title: 'sylius.homepage.latest_deals'
                    test_attribute: 'latest-deals'
                priority: 200
            new_collection:
                template: '@SyliusShop/homepage/new_collection.html.twig'
                priority: 100
            latest_products:
                component: 'sylius_shop:product:list'
                props:
                    limit: 8
                    template: '@SyliusShop/product/common/list.html.twig'
                priority: 0

Assuming we've created a history.html.twig template, we can place the elements we want in it.

"Yes, but wait a minute, we can use twig, that's fine, but how do we display our most recently consulted products? Where do they come from?"

That's a very good question. Here, we're not just going to use classic twig, but we're going to use the render(controller( function, which calls the method of a Controller we've defined, which in turn will call our Service containing the request.

Here's a diagram to help you understand

In this Controller, we'll return a twig (the real one this time) containing the display of products and images, as well as all the desired elements.

1 2 3 4 5 6 7 8 9 10 11 12 13 14
    <?php
    
    public function showRecommendations(): Response
    {
        $recommendations = [];
        if ($this->getUser()) {
            $customer = $this->getUser()->getCustomer();
            $recommendations = $this->recommendationService->getRecommendationsForCustomer($customer->getId());
        }

        return $this->render('recommendations/product_recommendations.html.twig', [
            'recommendations' => $recommendations,
        ]);
    }

And that's it! The result of our custom module to display a module and offer your customers to resume their previous journey. 🙂

Of course, we could improve this module even further by calculating how long the customer has stayed on the page and thus avoid offering them products they may have seen by mistake in their browsing.

We could also send him an email to remind him of what he was interested in, or add an AI that would identify his tastes and suggest new products that would match them.

So many possibilities! 😊

For my part, I'd like to thank you for reading this article to the end, and see you next time!