💻 DéveloppementIntermédiaire PS 1.7 PS 8.x

Affichage aléatoire dans PrestaShop : randomiser vos blocs Smarty

Découvrez comment afficher aléatoirement des blocs de contenu dans PrestaShop avec Smarty {math} et les alternatives PHP modernes sous PS 8.x.

En bref : Pour afficher des blocs aléatoirement dans PrestaShop, utilisez {math equation="rand(min, max)"} en Smarty pour un résultat rapide, ou préférez ORDER BY RAND() / shuffle() côté PHP pour une solution robuste compatible avec le cache.

Publié le 21 mars 2026 5 min de lecture Alexandre Carette

Pourquoi randomiser l'affichage de certains blocs

Sur une boutique PrestaShop, afficher systématiquement les mêmes contenus sur la page d'accueil finit par lasser les visiteurs réguliers. Alterner aléatoirement entre plusieurs blocs — avis clients, promotions, mises en avant produit — donne une impression de fraîcheur sans aucune intervention manuelle.

Deux approches existent : la manipulation directe en Smarty (rapide à mettre en place) et la modification côté PHP (plus robuste et performante). Voyons les deux.

Méthode 1 : randomisation via Smarty `{math}`

Le principe

Smarty dispose d'une fonction {math} qui accepte l'expression rand(). On génère un nombre aléatoire, on le stocke dans une variable, puis on conditionne l'affichage de chaque bloc en fonction de sa valeur.

Exemple simple : une chance sur trois


{math equation="rand(min, max)" min="1" max="3" assign="randomBlock"}

{if $randomBlock == 1}
  <div class="promo-block promo-block--soldes">
    <h2>Soldes d'hiver</h2>
    <p>Jusqu'à -40 % sur toute la collection.</p>
  </div>
{elseif $randomBlock == 2}
  <div class="promo-block promo-block--nouveautes">
    <h2>Nouveautés</h2>
    <p>Découvrez les derniers arrivages de la saison.</p>
  </div>
{else}
  <div class="promo-block promo-block--avis">
    <h2>Ils nous font confiance</h2>
    <p>Plus de 2 000 avis clients vérifiés.</p>
  </div>
{/if}

rand(1, 3) retourne un entier entre 1 et 3 inclus. Chaque bloc a donc statistiquement une chance sur trois d'apparaître à chaque chargement de page.

Limiter à la page d'accueil

Il est souvent souhaitable de ne randomiser l'affichage que sur la homepage. PrestaShop expose la variable $page.page_name dans tous les templates :


{if $page.page_name == 'index'}
  {math equation="rand(min, max)" min="1" max="3" assign="randomBlock"}
  {if $randomBlock == 1}
    {* Bloc A *}
  {elseif $randomBlock == 2}
    {* Bloc B *}
  {else}
    {* Bloc C *}
  {/if}
{/if}

Sur toutes les autres pages, aucun de ces blocs ne s'affichera.

Appliquer la technique à un module tiers (carrousels, blocs statiques)

Beaucoup de thèmes et modules (type AnThemeBlocks, Creative Elements, etc.) génèrent leurs blocs via des templates .tpl. Le principe reste identique : enveloppez le markup du bloc avec la condition {math} + {if}.


{math equation="rand(min, max)" min="1" max="2" assign="showReviews"}
{if $showReviews == 1}
  <div class="reviews-carousel owl-carousel owl-theme"
       id="reviews-block_{$block->id}"
       data-autoplay="{$block->formdata->autoplay}"
       data-loop="{$block->formdata->loop}">
    {foreach from=$block->getChildrenBlocks() item=child}
      {include file=$child->getTemplatePath()}
    {/foreach}
  </div>
{/if}

Ici, le carrousel d'avis a une chance sur deux d'apparaître.

Méthode 2 : randomisation côté PHP (recommandée pour PS 8.x)

La manipulation Smarty fonctionne, mais elle a ses limites :

  • **Cache Smarty** : si le cache de template est actif, le résultat aléatoire peut être mis en cache et donc toujours identique.
  • **Performances** : multiplier les conditions Smarty sur des dizaines de blocs alourdit le rendu.
  • **Maintenabilité** : le code Smarty devient vite illisible quand la logique métier s'accumule.

Modifier la requête SQL dans le module

Pour les modules qui récupèrent des blocs ou des produits depuis la base de données, la solution la plus propre consiste à randomiser directement au niveau SQL :


// Dans la méthode getChildrenBlocks() ou équivalent
$sql = new DbQuery();
$sql->select('*');
$sql->from('module_block', 'b');
$sql->where('b.id_parent = ' . (int)$this->id);
$sql->where('b.active = 1');
$sql->orderBy('RAND()');
$sql->limit(3); // N'afficher que 3 blocs parmi tous les actifs

$blocks = Db::getInstance()->executeS($sql);

L'ajout de ORDER BY RAND() mélange les résultats à chaque requête. Combiné avec un LIMIT, vous sélectionnez un sous-ensemble aléatoire sans toucher aux templates.

Attention aux performances de ORDER BY RAND()

Sur de petites tables (quelques dizaines de lignes), ORDER BY RAND() est parfaitement acceptable. Sur des tables volumineuses (milliers de produits), cette clause force MySQL à générer un nombre aléatoire pour chaque ligne avant de trier : c'est coûteux.

Alternative performante pour les grandes tables :


// Récupérer les IDs disponibles
$ids = Db::getInstance()->executeS(
    'SELECT id_block FROM ' . _DB_PREFIX_ . 'module_block
     WHERE id_parent = ' . (int)$this->id . ' AND active = 1'
);

// Mélanger côté PHP (quasi-instantané)
shuffle($ids);
$selectedIds = array_slice(array_column($ids, 'id_block'), 0, 3);

// Requête ciblée
$blocks = Db::getInstance()->executeS(
    'SELECT * FROM ' . _DB_PREFIX_ . 'module_block
     WHERE id_block IN (' . implode(',', array_map('intval', $selectedIds)) . ')'
);

Cette approche en deux temps évite le tri aléatoire SQL sur toute la table.

Méthode 3 : randomisation JavaScript côté client

Si vous ne pouvez pas modifier le PHP ou le Smarty (thème acheté, module verrouillé), une solution front-end reste possible :


document.addEventListener('DOMContentLoaded', function () {
  const blocks = document.querySelectorAll('.randomizable-block');
  if (blocks.length === 0) return;

  // Masquer tous les blocs
  blocks.forEach(block => block.style.display = 'none');

  // En afficher un au hasard
  const randomIndex = Math.floor(Math.random() * blocks.length);
  blocks[randomIndex].style.display = '';
});

Cette méthode a l'avantage de fonctionner même avec un cache de page activé (Varnish, CDN), puisque la logique s'exécute dans le navigateur. L'inconvénient : un léger flash de contenu (FOUC) si les blocs ne sont pas masqués par défaut en CSS.

Pour éviter le FOUC :


.randomizable-block {
  display: none;
}

Le JavaScript se chargera de révéler le bloc sélectionné.

Bonnes pratiques

CritèreSmarty `{math}`PHP `ORDER BY RAND()`JavaScript Compatibilité cacheNon (résultat mis en cache)Dépend du cache applicatifOui (côté client) PerformanceCorrecteAttention aux grosses tablesExcellente MaintenabilitéFaible si complexeBonneBonne Nécessite accès code PHPNonOuiNon

Recommandations :

  1. **Préférez la méthode PHP** quand vous développez ou maintenez un module. C'est la plus propre et la plus fiable.
  2. **Utilisez Smarty `{math}`** pour des personnalisations rapides sur un thème, en gardant à l'esprit l'impact du cache.
  3. **Recourez au JavaScript** comme solution de dernier recours ou quand un cache serveur agressif rend les autres méthodes inefficaces.
  4. **Testez toujours** en vidant le cache PrestaShop (`Paramètres avancés > Performances > Vider le cache`) pour vérifier que la randomisation fonctionne réellement.
  5. **Documentez** la logique aléatoire dans votre code : un bloc qui "disparaît" aléatoirement peut vite devenir un bug mystérieux pour un collègue qui ne connaît pas le mécanisme.
#smarty #template #random #affichage-conditionnel #personnalisation #homepage

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

Alexandre Carette

Expert PrestaShop & Architecture E-commerce

Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.