Displaying Prestashop manufacturers in alphabetical groups
Isn’t it a bit boring to have all the manufacturers and suppliers listed as they were products? Today, we will see how to change the default Prestashop manufacturers list display to something more professional, alphabetically split.
Download Project Files
Prestashop version used: 1.5.2
Finished result
A couple of weeks ago, one of my clients expressed the will to change the look of the manufacturers and suppliers list pages into something more professional. By default, as you might know, Prestashop displays those lists the following way
Although it might be okay for some websites, we can’t say this type of design is eye-catching or professional. It’s a bit boring and conventional, and also very similar to the product list look. The client wanted to have manufacturers and suppliers listed within alphabetical groups, and brought me this website as an example: http://www.menlook.com/fr/marques-mode-homme. Indeed, that looks professional. Without much effort, Prestashop can be bended to have this kind of display, so, without further do, lets get started.
Step 1 – Planning our strategy
“Be sure you do not directly edit the default template. Create a copy instead, and select it as the active theme to see changes by going to Preferences > Themes”
We are going to use the manufacturer list for this tutorial, but you can feel free to apply the process to the suppliers list too, since the template files are almost identical. Please, also note that I’ll be using the default template, and your files might be different if you use a custom one. Let’s open up manufacturer-list.tpl, that is found in the template’s main folder. Here is how it looks:
{capture name=path}{l s='Manufacturers'}{/capture}
{include file="$tpl_dir./breadcrumb.tpl"}
<h1>{l s='Manufacturers'}</h1>
{if isset($errors) AND $errors}
{include file="$tpl_dir./errors.tpl"}
{else}
<p class="nbrmanufacturer">{strip}
<span class="bold">
{if $nbManufacturers == 0}{l s='There are no manufacturers.'}
{else}
{if $nbManufacturers == 1}
{l s='There is %d manufacturer.' sprintf=$nbManufacturers}
{else}
{l s='There are %d manufacturers.' sprintf=$nbManufacturers}
{/if}
{/if}
</span>{/strip}
</p>
{if $nbManufacturers > 0}
<ul id="manufacturers_list">
{foreach from=$manufacturers item=manufacturer name=manufacturers}
<li class="clearfix {if $smarty.foreach.manufacturers.first}first_item{elseif $smarty.foreach.manufacturers.last}last_item{else}item{/if}">
<div class="left_side">
<!-- logo -->
<div class="logo">
{if $manufacturer.nb_products > 0}<a href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}" title="{$manufacturer.name|escape:'htmlall':'UTF-8'}" class="lnk_img">{/if}
<img src="{$img_manu_dir}{$manufacturer.image|escape:'htmlall':'UTF-8'}-medium_default.jpg" alt="" width="{$mediumSize.width}" height="{$mediumSize.height}" />
{if $manufacturer.nb_products > 0}</a>{/if}
</div>
<!-- name -->
<h3>
{if $manufacturer.nb_products > 0}<a href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}">{/if}
{$manufacturer.name|truncate:60:'...'|escape:'htmlall':'UTF-8'}
{if $manufacturer.nb_products > 0}</a>{/if}
</h3>
<p class="description rte">
{if $manufacturer.nb_products > 0}<a href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}">{/if}
{$manufacturer.short_description}
{if $manufacturer.nb_products > 0}</a>{/if}
<br />
{if $manufacturer.nb_products > 0}<a href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}">{/if}
<span>{if $manufacturer.nb_products == 1}{l s='%d product' sprintf=$manufacturer.nb_products|intval}{else}{l s='%d products' sprintf=$manufacturer.nb_products|intval}{/if}</span>
{if $manufacturer.nb_products > 0}</a>{/if}
</p>
</div>
<div class="right_side">
{if $manufacturer.nb_products > 0}
<a class="button" href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}">{l s='view products'}</a>
{/if}
</div>
</li>
{/foreach}
</ul>
{include file="$tpl_dir./pagination.tpl"}
{/if}
{/if}
All we are interested in is the content of the foreach loop that starts at line 24. We want to split up the task in 2 parts: first, we will lay down the basic logic to add a new list item when the starting letter changes; This item will hold the main letter, or number range for numbers from zero to nine, and will take up all the center column’s space. Secondly, we will style the list by editing the css stored in the global.css file, and float the manufacturers so that 4 can sit in a single row. We also want to remove those manufacturers images, since they would only clutter the alphabetical split list. To give it a clean look, the only thing left will be the brand name, with, eventually, a greyed out look if it holds no products.
Now, before starting, if you have an out-of-the-box Prestashop store, you might want to go ahead an add a couple of new manufacturers to test the tutorial’s results. To do this, login to the back office, head to Catalog > Manufacturers and click Add new. For testing purposes, I suggest you add at least the following (fictitional, or so I hope!) brands:
- 0 Geez
- 7 Sins
- Arcana
- Bumblebee Go
- BillHill
- Hoo Hoo
- Zero Gs
Notice: After creating a new manufacturer, be sure you enable it (last option in the page) since, by default, they are disabled!
Step 2 – The “new letter” logic
As we said, the first step would be to add the logic that allows the system to know if the next manufacturer name has a new first letter. Luckily, they’re displayed in an alphabetical order by default, and so we only need to check when there is a change in the first letter. Add the following just after the opening of the foreach loop at line 24:
{if !isset($currentLetter)}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{$manufacturer.name|substr:0:1}</h3></li>
{else if isset($currentLetter) && $currentLetter != $manufacturer.name|substr:0:1}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{$manufacturer.name|substr:0:1}</h3></li>
{/if}
Explanation: First of all, we are checking if the $currentLetter variable has been already set. If not, it means that’s the first item in the loop, and we need to define it, and create the letter separator. As previously mentioned, we are using a list item to handle this. So, we define the current letter as a substring, from 0 to 1 (alas, the first letter) of the manufacturer’s name.
Else, if the variable has already been set up (read: it’s not the first item in the loop), we want to check if the current manufacturer’s first letter is different than what we set as the current letter. If it’s different, we create a new separator, and reassign the current letter to the new first letter. Here is what you’ll end up with:
They are logically separated into groups, depending on the letter with which they begin. And it might just be okay for you; but let’s take this a step forward: it’s common use to group numbers together, shall we do it?
Step 3 – Grouping all numbers together
If you are happy with having each of the different numbers as a separate group, you can skip this step, if not, read on.
We are now going to group the numbers into a single group, since as I said it is common use. But how can we do that? If you review the code above, you’ll notice that we are using the first character of each manufacturer name as a reference on when to start a new group. The problem is that we are still referencing a string, and, if we check it with the is_int() function, it would just return false. We have to use a bit of a trick. Here is how to change the previous block of code:
{if !isset($currentLetter)}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{if in_array($currentLetter, array(0,1,2,3,4,5,6,7,8,9))}0-9{else}{$manufacturer.name|substr:0:1}{/if}</h3></li>
{else if isset($currentLetter) && $currentLetter != $manufacturer.name|substr:0:1 && (string)($manufacturer.name|substr:0:1) != (string)((int)($manufacturer.name|substr:0:1))}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{$manufacturer.name|substr:0:1}</h3></li>
{/if}
Explanation: First, we change the very first divider to hold the current first character only if it’s not in the numbers array. If it is, we add 0-9. Of course, it will be like this regardless of the numbers that are present, but at least we can give it a clean look without further stressing the system with additional foreach statements.
Then, we have the tricky part inside the else if. The following, which we just added, might be confusing:
&& (string)($manufacturer.name|substr:0:1) != (string)((int)($manufacturer.name|substr:0:1))
Basically, we are telling the system “and if the string value of the character is different than the string value of the integer of that same value”. A bit complex I assume, let’s make a practical example. Let’s just assume the character is “A”: in this case, the string value of the integer of “A” will not be “A” itself, but “0” (since we are type casting the letter to an integer, that results in zero). So this is basically the process: we type cast “A” to an integer, which is 0 (number). Then, we compare the original string (which was “A”) with the new value, telling smarty that it’s a string, so not just 0, but “0” with quotes. If we were to check it against the number itself, it would have always resulted as a true check, and thus never adding the new list elements. Remember? We want to add new separators only if the first character is a letter.
I know, it’s a bit complex, but hopefully you can find your way around by closely looking at the code (which expresses itselft better than I can do!). Here is what we should have now;
Step 4 – Removing useless stuff
We have one small thing left in the template file. As before, you can stay with this if you’re happy, since we’ll now be removing images and all un-necessary texts. Get rid of the entire div with class “right_side”. In the left_side, get rid of everything but the H3 tag that contains the manufacturer name. In the end, your code should approximately look like this:
{capture name=path}{l s='Manufacturers'}{/capture}
{include file="$tpl_dir./breadcrumb.tpl"}
<h1>{l s='Manufacturers'}</h1>
{if isset($errors) AND $errors}
{include file="$tpl_dir./errors.tpl"}
{else}
<p class="nbrmanufacturer">{strip}
<span class="bold">
{if $nbManufacturers == 0}{l s='There are no manufacturers.'}
{else}
{if $nbManufacturers == 1}
{l s='There is %d manufacturer.' sprintf=$nbManufacturers}
{else}
{l s='There are %d manufacturers.' sprintf=$nbManufacturers}
{/if}
{/if}
</span>{/strip}
</p>
{if $nbManufacturers > 0}
<ul id="manufacturers_list" class="clearfix">
{foreach from=$manufacturers item=manufacturer name=manufacturers}
{if !isset($currentLetter)}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{if in_array($currentLetter, array(0,1,2,3,4,5,6,7,8,9))}0-9{else}{$manufacturer.name|substr:0:1}{/if}</h3></li>
{else if isset($currentLetter) && $currentLetter != $manufacturer.name|substr:0:1 && (string)($manufacturer.name|substr:0:1) != (string)((int)($manufacturer.name|substr:0:1))}
{$currentLetter = $manufacturer.name|substr:0:1}
<li class="alphabetical"><h3>{$manufacturer.name|substr:0:1}</h3></li>
{/if}
<li class="clearfix {if $smarty.foreach.manufacturers.first}first_item{elseif $smarty.foreach.manufacturers.last}last_item{else}item{/if}">
<div class="left_side">
<!-- name -->
<h4>
{if $manufacturer.nb_products > 0}<a href="{$link->getmanufacturerLink($manufacturer.id_manufacturer, $manufacturer.link_rewrite)|escape:'htmlall':'UTF-8'}">{/if}
{$manufacturer.name|truncate:60:'...'|escape:'htmlall':'UTF-8'}
{if $manufacturer.nb_products > 0}</a>{/if}
</h4>
</div>
</li>
{/foreach}
</ul>
{include file="$tpl_dir./pagination.tpl"}
{/if}
{/if}
While the page should look like this:
Notice: For some reason, pagination seems to be broken on my 1.5.2. If you experience the same problem, get rid of the {include file=”$tpl_dir./pagination.tpl”} part as well.
At this point, things are a bit screwed up. Notice that I’ve also turned the manufacturer’s name H3 into a smaller h4, to give it a better hierarchy, and added class=”clearfix” at the ul container, since we are going to float those list items in a while. Those dividers are not so useful anymore, isn’t it? Let’s give our page a decent styling in the final step!
Step 5 – Final styling touches
Open up global.css, found in the /css/ subfolder of the theme.
Locate the “PAGE MANUFACTURER” comment, ad about line 1506 of the default theme. If you use a custom theme, you might want to look for #manufacturer_list. Look for ul#manufacturers_list li, it should look like this:
ul#manufacturers_list li {
margin-bottom: 14px;
padding: 12px 8px;
border: 1px solid #eee;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius:3px;
}
Change it into this:
ul#manufacturers_list li {
float: left;
width: 24%;
margin: 0.5%;
border-bottom: 1px solid #eee;
}
Then, after that style block, but before ul#manufacturers_list li a.lnk_img, add the following:
ul#manufacturers_list li h4 {padding-bottom: 10px;font-weight:normal; color: #ccc}
ul#manufacturers_list li:hover {
border-bottom: 1px solid #990000
}
ul#manufacturers_list li a {color: #383838}
ul#manufacturers_list li:hover a {color:#990000}
ul#manufacturers_list li.alphabetical {
width: 100%;
clear:both;
margin: 14px 0;
border-bottom: 2px solid #383838;
}
ul#manufacturers_list li a:hover {text-decoration: none;}
And that’s it! We have created a nifty difference between “group LIs” and “manufactures LIs”. We also greyed out manufacturers that are not holding any product at the moment. Here is the final result:
Conclusion
That’s all folks, you now have a styled list that looks a lot more professional than the default Prestashop manufacturer list. As I said at the beginning of the article, the very same process can be applied to suppliers, since these 2 things share about the same template and styling. I am not so sure about products, since they can be ordered in other ways than by name; of course, you can always give it a try and let me know the result! If you want to know more about Prestashop manufacturers and suppliers, you can have a look at my 101 series tutorial for day 3: Prestashop categories and products.








