The challenge of creating a product configurator in Magento

20th August 2013

In my Magento career I have had to build a product configurator twice, it's a very challenging concept with a lot of things to think about before jumping into it. With this post I would like to tell you how I ended up building them and what kind of issues I came across and how I solved those issues.

Case 1

My first case was for a scooter webshop, the idea was to create your own scooter with your own colors and accessories, this being our first configurator we quickly took the obvious way of using custom options. I'll try to explain the way we handled this in a nutshell. There were several parts of the scooter you could give separate colors and there were certain dependencies which would need to be handled.

The deadline unfortunately forced us to create a php array (vs creating a nice UI) which had all these dependencies defined. On the frontend we changed the way Magento outputs the custom options and used jQuery to shape and structure the HTML. We slugged the labels of all the options and used them as a reference for the php array. I ended up writing some complex javascript with probably more nested "for" loops than anyone should ever have. The slugged labels were also used to get the right image from the filesystem, when selecting a different color we would stack the image on top of the other layers creating a live preview.

The problem with this method

Aside from the slightly bad implementation we did, here's what's wrong with using this method:

  1. The custom options are rendered in a block and are quite challenging to change, this leaves us with little flexibility unless we rewrite the entire block.
  2. There was no way we could keep track of stock, luckily this wasn't necessary but would have been good for the future.
  3. If we had made the nice UI then we would have had to work it into the custom options, them being dynamically done with javascript looks like a challenge.
  4. Without creating some complicated piece of UI, I couldn't imagine getting the dependencies manageable.
  5. You can't freely pick your price for every combination.

Case 2

Here's a case I'm quite proud of how it turned out. This one is for a lights shop, the idea was to be able to assemble lights by choosing between fixtures, lampshade shapes, colors and so forth. Knowing the difficulties we had with using custom options we initially decided to go down the configurable product road. First things first I created an import script which would import an excel which had all the dependencies in it. This import gave me a lot of flexibility throughout the project.

There were several different types of lights: floor lights, ceiling lights, table lights, etc. Each type of light was a configurable product, then I would calculate every single possible combination and created a simple product of it. The combinations were defined in its attributes which were needed to create the configurable product with the right options. I ended up having configurable products which had about 4000 simple products.

You might be surprised to hear this but Magento doesn't like it when you have that many simple products connected to a configurable product. The product view page took about 12 seconds to load (no caching) and likewise for the backend product edit page. You can do all the optimization you want but you should realize that at this point it's maybe better to take a different path. In real-time we actually discovered this after I had written most of the javascript (I tested with smaller products) to handle the frontend.

We quickly switched over to creating our own product type, making it as light as possible and only get what we need. I called it the "Configurator Product" (the module is called Configurator). I chose to stay away from creating any "tight" relations between the simple products and the configurator product so I thought I'd use a code which would identify the configurator product it belongs to. The so called collection code was the key to connect the simple products to the configurator product and vice versa. I made it possible to select the attributes that were supposed to show up as steps on the frontend. Now I was in full control of the amount of information I would have to retrieve and process on my product view page.

I handled the dependencies by getting every option of every attribute and storing all the product ids that have that option in a data attribute, I was able to execute these queries quickly thanks to MySQL's wonderful GROUP_CONCAT. The only thing stopping me from using it were limits that were set by configuration. Making sure these limits were increased before I would do the query resolved this issue (and I hope to never hit the limit again...). So GROUP_CONCAT enabled me to get all the product ids for that option instead of having to go through ~2000 rows multiple times.

Now that every option had a data attribute containing the product ids, all I had to do in my javascript was to filter the product ids to find the possible combinations. It's a bit complex to explain but it would come down to a script going through all the options and filtering the product ids to check if it would be left with one product id (there's only 1 product for every combination).

Every time the user would advance a step I would create an ajax request for every option in that step to retrieve the image and price that were used by that simple product. It's better to ajax the images and price because if Magento would have to load the products and resize a couple thousand images on one page it would take ages and probably crash. This way I have the load spread across the process and I keep my page load at around a second or two without caching (decent for a configurator with 4000 combinations if you ask me).

At the end of the steps I would setup the add to cart button to add the finally simple product to the cart and the default Magento workflow applies.

Case 1 vs Case 2

Here's what case 2's method does better than case 1's:

  1. Stock management is possible.
  2. Images are uploaded on the simple product, no more "slug this, concatanate that and hope it exists".
  3. Full control over my template making it easier to set everything up for my javascript.
  4. I can define prices for every combination possible.
  5. Dependencies are not defined on javascript level anymore, they are now defined by the simple products you have.
  6. I created a platform which I can extend easily because I built it from scratch.
  7. Using events in my javascript it was easy to extend that too. I ended up having a Configurator object which could give me all the information I needed to customize things.
  8. Special prices, catalog and shopping cart price rules apply for every individual combination.

Pitfalls

The most important thing is to make sure you know the requirements, it's the small details that can force you to change your entire plan. I can't stress this enough, I've done far too much refactoring because I didn't foresee some of the details. Luckily this refactoring was easily done because I had a flexible platform to work with.

Conclusion

Product configurators in Magento are challenging and fun if you are given the time to work on it. I don't think there's one method that works for all situations but I do believe that what I have now is very reusable for future projects! I am looking forward to case 3!

I hope I explained it well enough, it's hard putting such a huge process into a couple words and I have skipped many things but I hope I covered the important parts. Feel free to ask me anything!

comments powered by Disqus