Tutoriels

#Prestashop : afficher la liste des produits en liste ou grille

#Prestashop : afficher la liste des produits en liste ou grille

Pour proposer ces 2 options, nous allons modifier plusieurs fichiers de notre thème Prestashop. Il existe des modules Prestashop gratuits ou payants, mais tout comme sur WordPress, je préfère modifier le thème plutôt que d’ajouter une multitude de plugins.

Nous travaillerons sur le template Prestashop 1.4.5 et utiliserons un plugin jquery pour gérer les cookies : jquery.cookie.js

Les fichiers du thème à modifier sont :

Fichiers tpl :

  • product-sort.tpl
  • product_list.tpl
  • footer.tpl

Fichier css :

  • product_list.css

DEMO LIVE

HTML et CSS

Ajout des boutons

Commençons par afficher nos boutons grille/liste.

La liste des produits s’affiche dans plussieurs page. Nous devons donc ajouter ces boutons dans un fichier tpl qui est appelé dès que la page présente une liste de produit.

Le fichier product-sort.tpl fera l’affaire.

Au début de ce fichier (avant {if isset($orderby) AND isset($orderway)}) , ajoutez le code html suivant :

<div class="view_options"><a id="list_l" class="list_view" href="#" rel="nofollow">{l s='List'}</a>
<a id="grid_l" class="grid_view" href="#" rel="nofollow">{l s='grid'}</a></div>

 

Pour la mise en forme de ces boutons, j’ai utilisé les boutons d’un kit psd gratuit (ici) :

Grille ou Liste

Cette image est à télécharger dans le dossier img du thème.

Ajoutez les lignes suivantes dans le fichier product_list.css situé dans le dossier css du thème :

/*list grid*/
.view_options{
float: right;
padding-top: 10px;
margin-top: -18px;
padding-left: 10px;

}
.list_view, .grid_view{
height:34px;
width:34px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
display:block;
float:left;
background:url(../img/grid-list.png) no-repeat;
}
.list_view{
background-position: 0px 0px;
}
.list_l_active .list_view{
background-position: 0px -37px;
}
.grid_view{
background-position: -34px -37px;
}
.grid_l_active .grid_view{
background-position: -34px 0px;
}

 

Affichage en mode grille

Par défaut, l’affichage des produits est en mode liste. Nous devons donc ajouter la css pour l’affichage en mode grille.

Toujours dans le fichier product_list.css, ajoutez ces lignes :

/*grille*/
#product_list.grid_l li{
float: left;
width: 29%;
margin-right: 1%;
}

#product_list.grid_l li .center_block{
width:128px;
border-right:0px;
margin:0 auto;
}

#product_list.grid_l li .left_block {
display:none
}
#product_list.grid_l li .right_block {
width:auto;
float: none;
}
#product_list.grid_l a.product_img_link {
overflow: hidden;
position: relative;
float: left;
display: block;
margin-right: 0px;
border: 1px solid
#CCC;
}

#product_list.grid_l li p.product_desc {
display:none
}
.loading_view{
background: url('../img/ajax-loader.gif') #fff no-repeat top center;
}

 

Dans le fichier product-list.tpl, ajoutez après la balise /ul:

</ul>
<br clear="all" />

 

Le code css pour l’affichage grille n’est pas finalisé, je vous laisse le modifier pour un meilleur résultat.

Le javascript

La partie javascript permettra d’avoir les fonctionnalités suivantes :

  • au clic sur un des boutons, la liste des produits change d’affichage
  • ajout d’un cookie pour mémoriser le choix de l’utilisateur

Changement d’affichage

Voici le script pour changer l’affichage (Placer ces lignes dans le fichier footer.tpl, avant la balise </body> et {/if}) :

<script type="text/javascript">
$(document).ready(function() {
var ul='#product_list';
var div_btn='div.view_options';
$('.view_options a').click(function(){
var height=$(ul).height();
var width=$(ul).width();
var ul_class=$(this).attr('id');
$(div_btn).removeClass('list_l_active').removeClass('grid_l_active');
$(div_btn).addClass(ul_class+'_active');
$(ul).hide().wrap('<div class="loading_view" style="height:'+height+'px;width:'+width+'px"></div>').delay(100).removeClass().addClass(ul_class+' clear clearfix').fadeIn('fast',function(){$(this).unwrap()});
return false;
});
});
</script>

 

Pour résumer, ce script permet d’ajouter une classe list_l ou grid_l à la liste selon le bouton cliqué.

Jquery : ajout d’un cookie

Pour que l’option grille ou liste soit enregistrée à chaque visite de l’utilisateur, nous devons enregistrer un cookie. Ce cookie sera ensuite lu dans le template product-list.tpl.
Pour travailler avec les cookies et jquery, le plugin jquery.cookie est parfait (téléchargez ici ce plugin).
Enregistrez ce plugin dans le dossier js de votre thème et ajoutez ce plugin au dessus du script précédent :

<script type="text/javascript" src="{$js_dir}jquery.cookie.js"></script>

 

La création d’un cookie est très simple, il suffit de donner un nom au cookie, une valeur et une date d’expiration. par défaut nous attribuons la valeur <em>list_l </em>ce qui correspond à un affichage liste

$.cookie('nom', 'valeur', { expires: 365, path: '/' });

 

Modifions maintenant notre script d’affichage pour modifier la valeur du cookie au clic sur une des deux options :

<script type="text/javascript">
$(document).ready(function() {
if($.cookie('gridorlist_prestarocket')==null){
$.cookie('gridorlist_prestarocket', 'list_l', { expires: 365, path: '/' });
}
var ul='#product_list';
var div_btn='div.view_options';
$('.view_options a').click(function(){
var height=$(ul).height();
var width=$(ul).width();
var ul_class=$(this).attr('id');
$(div_btn).removeClass('list_l_active').removeClass('grid_l_active');
$(div_btn).addClass(ul_class+'_active');
$(ul).hide().wrap('<div class="loading_view" style="height:'+height+'px;width:'+width+'px"></div>').delay(100).removeClass().addClass(ul_class+' clear clearfix').fadeIn('fast',function(){$(this).unwrap()});
//mise à jour du cookie
$.cookie('gridorlist_prestarocket', ul_class, { expires: 365, path: '/' });
return false;
});
});
</script>

 

Passons maintenant à l’étape suivante : lecture du cookie dans le fichier product-list.tpl

Cookie et Smarty

Les modifications effectuées plus haut permettent de proposer 2 modes d’affichage mais lorsque l’utilisateur change de page, l’option n’est pas mémorisée et l’idée ici est de garder « en mémoire » le choix de l’utilisateur d’une page à l’autre et d’une visite à l’autre.

Pour lire la valeur de notre cookie dans un fichier Smarty (tpl), il suffit d’utiliser la variable réservée :

{$smarty.cookies.nom_du_cookie}
Dans le fichier product-list.tpl, ajoutons les ligne suivantes après {if isset($products)} :

{if isset($smarty.cookies.gridorlist_prestarocket) && $smarty.cookies.gridorlist_prestarocket=="grid_l"}
{assign var="ul_class" value="grid_l"}
{else}
{assign var="ul_class" value="list_l"}
{/if}

 

Quelques explications :

  • si le cookie existe et que sa valeur est grid_l, alors la variable $ul_class=grid_l
  • si la condition précédente n’est pas vérifiée, alors $ul_class=list_l
  • la variable $ul_class est une classe ajoutée à la balise : ul class= »{$ul_class} »

Pour terminer, utilisons la même logique dans le fichier product-sort.tpl pour l’état actif des boutons :

{if isset($smarty.cookies.gridorlist_prestarocket) && $smarty.cookies.gridorlist_prestarocket=="grid_l"}
{assign var="active_l" value="grid_active"}
{else}
{assign var="active_l" value="list_active"}
{/if}
<div class="view_options {$active_l}"><a id="list_l" class="list_view" href="#" rel="nofollow">{l s='List'}</a>
<a id="grid_l" class="grid_view" href="#" rel="nofollow">{l s='grid'}</a></div>

 

La liste complète des modifications

product-list.css

/*liste ou grille*/

/*boutons*/
.view_options{
float: right;
padding-top: 10px;
margin-top: -18px;
padding-left: 10px;

}
.list_view, .grid_view{
height:34px;
width:34px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
display:block;
float:left;
background:url(../img/grid-list.png) no-repeat;
}
.list_view{
background-position: 0px 0px;
}
.list_l_active .list_view{
background-position: 0px -37px;
}
.grid_view{
background-position: -34px -37px;
}
.grid_l_active .grid_view{
background-position: -34px 0px;
}

/*grille*/
#product_list.grid_l {
zoom: 1;
}

#product_list.grid_l li{
float: left;
width: 29%;
margin-right: 1%;
}

#product_list.grid_l li .center_block{
width:128px;
border-right:0px;
margin:0 auto;
}

#product_list.grid_l li .left_block {
display:none
}
#product_list.grid_l li .right_block {
width:auto;
float: none;
}
#product_list.grid_l a.product_img_link {
overflow: hidden;
position: relative;
float: left;
display: block;
margin-right: 0px;
border: 1px solid
#CCC;
}

#product_list.grid_l li p.product_desc {
display:none
}
.loading_view{
background: url('../img/ajax-loader.gif') #fff no-repeat top center;
}

 

footer.tpl

<script type="text/javascript" src="{$js_dir}jquery.cookie.js"></script>
{literal}
<script type="text/javascript">
$(document).ready(function() {
if($.cookie('gridorlist_prestarocket')==null){
$.cookie('gridorlist_prestarocket', 'list_l', { expires: 365, path: '/' });
}
var ul='#product_list';
var div_btn='div.view_options';
$('.view_options a').click(function(){
var height=$(ul).height();
var width=$(ul).width();
var ul_class=$(this).attr('id');
$(div_btn).removeClass('list_l_active').removeClass('grid_l_active');
$(div_btn).addClass(ul_class+'_active');
$(ul).hide().wrap('<div class="loading_view" style="height:'+height+'px;width:'+width+'px"></div>').delay(100).removeClass().addClass(ul_class+' clear clearfix').fadeIn('fast',function(){$(this).unwrap()});
//mise à jour du cookie
$.cookie('gridorlist_prestarocket', ul_class, { expires: 365, path: '/' });
return false;
});
});
</script>
{/literal}

 

product-list.tpl

{if isset($products)}
{if isset($smarty.cookies.gridorlist_prestarocket) && $smarty.cookies.gridorlist_prestarocket=="grid_l"}
{assign var="ul_class" value="grid_l"}
{else}
{assign var="ul_class" value="list_l"}
{/if}

<!-- Products list -->
<ul id="product_list" class="clear {$ul_class}">

product-sort.tpl

{if isset($smarty.cookies.gridorlist_prestarocket) && $smarty.cookies.gridorlist_prestarocket=="grid_l"}
{assign var="active_l" value="grid_l_active"}
{else}
{assign var="active_l" value="list_l_active"}
{/if}
<div class="view_options {$active_l}">
<a id="list_l" href="#" class="list_view" rel="nofollow">{l s='List'}</a>
<a id="grid_l" href="#" class="grid_view" rel="nofollow">{l s='grid'}</a>
</div>