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

Passer une variable Smarty dans jQuery sur PrestaShop

Comment récupérer une variable Smarty dans un script jQuery sur PrestaShop : attributs data, balise literal, boucles foreach et appels AJAX.

En bref : Pour récupérer une variable Smarty dans jQuery au sein d'une boucle foreach, utilisez les attributs HTML5 data-* pour injecter les valeurs dans le DOM, la balise {literal} pour protéger le JavaScript inline, et $(this).data('key') pour cibler l'élément précis cliqué par l'utilisateur.

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

Le problème : Smarty et JavaScript ne parlent pas le même langage

Quand on développe un module ou un thème PrestaShop, on se retrouve tôt ou tard face à ce mur : comment récupérer une variable Smarty (côté serveur) dans un script jQuery (côté client) ?

La tentation naturelle est d'écrire quelque chose comme :


var idmsg = $(".test").val();

Mais .val() ne fonctionne que sur les éléments de formulaire (input, select, textarea). Sur un

ou un

, il renvoie undefined. Et même en utilisant .text() ou .html(), le vrai piège arrive quand on travaille dans une boucle {foreach} : le sélecteur de classe cible tous les éléments portant cette classe, et jQuery ne récupère que la valeur du premier (ou du dernier, selon la méthode).

Voici la bonne approche, propre et maintenable.

Solution : les attributs HTML5 `data-*` combinés à `{literal}`

La technique repose sur deux mécanismes complémentaires :

  1. **Les attributs `data-*`** du HTML5 pour injecter la valeur Smarty dans le DOM
  2. **La balise `{literal}`** de Smarty pour empêcher l'interprétation des accolades jQuery comme du Smarty
  3. Pourquoi `{literal}` est indispensable

    Smarty utilise les accolades {} comme délimiteurs. Or jQuery et JavaScript en font un usage intensif (objets, fonctions, callbacks). Sans {literal}, Smarty tente d'interpréter chaque { de votre code JavaScript et provoque des erreurs de compilation du template.

    
    {literal}
    <script type="text/javascript">
    // Ici, les accolades sont protégées de Smarty
    jQuery(document).ready(function() {
        // Votre code JS en toute sécurité
    });
    </script>
    {/literal}
    

    PrestaShop 1.7+ et 8.x : Si vous utilisez les fichiers .js séparés (bonne pratique), le problème {literal} ne se pose plus puisque Smarty ne traite pas les fichiers JavaScript externes. Privilégiez cette approche dans vos modules modernes.

    Le template : injecter les données dans le DOM

    Dans votre fichier .tpl, utilisez les attributs data-* pour attacher chaque valeur Smarty à son élément HTML :

    
    {foreach from=$messages item=message name=messageLoop}
    <div class="message-item" data-id="{$message.id_msg|intval}">
        <div class="message-content">
            {$message.content|escape:'html':'UTF-8'}
        </div>
        <button class="btn-mark-read" data-id="{$message.id_msg|intval}">
            Marquer comme lu
        </button>
    </div>
    {/foreach}
    

    Points importants :

    • **`|intval`** sur les identifiants numériques pour se prémunir contre les injections XSS
    • **`|escape:'html':'UTF-8'`** sur tout contenu textuel affiché
    • L'attribut `data-id` est **unique à chaque itération** du `foreach`, contrairement à une classe CSS qui serait partagée par tous les éléments

    Le JavaScript : récupérer la bonne valeur au clic

    
    {literal}
    <script type="text/javascript">
    jQuery(document).ready(function($) {
        $('.btn-mark-read').on('click', function(e) {
            e.preventDefault();
    
            // $(this) cible le bouton cliqué, pas tous les boutons
            var idMsg = $(this).attr('data-id');
            // Ou en syntaxe moderne : $(this).data('id');
    
            $.ajax({
                url: '{/literal}{$module_dir}{literal}ajax/mark-read.php',
                type: 'POST',
                data: {
                    id_msg: idMsg,
                    token: '{/literal}{$token}{literal}'
                },
                dataType: 'json',
                success: function(response) {
                    if (response.success) {
                        // Retirer visuellement le message ou changer son style
                        $(e.target).closest('.message-item').addClass('read');
                    }
                },
                error: function(xhr, status, error) {
                    console.error('Erreur AJAX:', error);
                }
            });
        });
    });
    </script>
    {/literal}
    

    Le secret est dans $(this) : à l'intérieur du gestionnaire d'événement click, this référence l'élément précis qui a été cliqué, pas l'ensemble des éléments correspondant au sélecteur. C'est ce qui résout le problème du foreach.

    Pourquoi `.val()` et `.text()` échouent dans une boucle

    Pour bien comprendre le piège, détaillons ce qui se passe avec les approches naïves :

    MéthodeComportement dans un foreachRésultat `$('.test').val()`Cible le premier élément `.test`, renvoie `undefined` sur un `

    `Échec total `$('.test').text()`Cible le premier élément `.test` uniquementToujours la même valeur `$('.test').each()`Parcourt tous les éléments mais sans contexte de clicPas de lien avec l'interaction utilisateur `$(this).data('id')`Cible l'élément cliqué précisémentValeur correcte à chaque clic

    Approche moderne : PrestaShop 1.7+ et 8.x

    Sur les versions modernes de PrestaShop, la bonne pratique est de séparer complètement le JavaScript du template Smarty.

    1. Enregistrer le script dans votre module

    
    public function hookDisplayHeader()
    {
        // Passer les données PHP → JS via Media::addJsDef
        Media::addJsDef([
            'myModuleAjaxUrl' => $this->context->link->getModuleLink(
                $this->name,
                'ajax',
                [],
                true
            ),
            'myModuleToken' => Tools::getToken(false)
        ]);
    
        $this->context->controller->addJS(
            $this->_path . 'views/js/front.js'
        );
    }
    

    2. Le fichier JavaScript externe

    
    // views/js/front.js
    // Pas besoin de {literal} puisque Smarty ne traite pas ce fichier
    
    jQuery(document).ready(function($) {
        $(document).on('click', '.btn-mark-read', function(e) {
            e.preventDefault();
            var idMsg = $(this).data('id');
    
            $.ajax({
                url: myModuleAjaxUrl,
                type: 'POST',
                data: {
                    action: 'markAsRead',
                    id_msg: idMsg,
                    token: myModuleToken
                },
                dataType: 'json',
                success: function(response) {
                    if (response.success) {
                        $(e.target).closest('.message-item')
                            .fadeOut(300, function() {
                                $(this).addClass('read').fadeIn(300);
                            });
                    }
                }
            });
        });
    });
    

    3. Le contrôleur AJAX côté module

    
    // controllers/front/ajax.php
    class MyModuleAjaxModuleFrontController extends ModuleFrontController
    {
        public function initContent()
        {
            if (!Tools::getIsset('token')
                || Tools::getValue('token') !== Tools::getToken(false)) {
                die(json_encode(['success' => false, 'error' => 'Invalid token']));
            }
    
            $action = Tools::getValue('action');
    
            if ($action === 'markAsRead') {
                $idMsg = (int) Tools::getValue('id_msg');
                // Votre logique métier ici
                $result = Db::getInstance()->update(
                    'my_messages',
                    ['is_read' => 1],
                    'id_msg = ' . $idMsg
                );
                die(json_encode(['success' => (bool) $result]));
            }
        }
    }
    

    Cette architecture est plus propre, plus sécurisée (token CSRF, contrôleur dédié) et plus facile à déboguer.

    Les erreurs classiques à éviter

    1. Oublier d'échapper les variables Smarty

    
    {* DANGEREUX — injection XSS possible *}
    <div data-name="{$message.name}">
    
    {* CORRECT *}
    <div data-name="{$message.name|escape:'html':'UTF-8'}">
    

    2. Construire la query string manuellement

    
    // FRAGILE — pas d'encodage, pas de structure
    var dataString = '&idmsg=' + idmsg;
    
    // CORRECT — jQuery encode automatiquement
    $.ajax({
        data: { id_msg: idmsg }
    });
    

    3. Ne pas valider côté serveur

    Même si la valeur vient d'un attribut data-* que vous avez généré, validez toujours côté PHP :

    
    $idMsg = (int) Tools::getValue('id_msg');
    if ($idMsg <= 0) {
        die(json_encode(['success' => false, 'error' => 'ID invalide']));
    }
    

    4. Utiliser `.click()` au lieu de `.on('click')`

    Si vos éléments sont générés dynamiquement (AJAX, pagination), .click() ne fonctionnera pas sur les nouveaux éléments. Utilisez la délégation d'événements :

    
    // Ne fonctionne PAS sur les éléments ajoutés après le chargement
    $('.btn-mark-read').click(function() { ... });
    
    // Fonctionne TOUJOURS grâce à la délégation
    $(document).on('click', '.btn-mark-read', function() { ... });
    

    Récapitulatif

    ContexteTechnique recommandée PrestaShop 1.6 avec JS inline`{literal}` + attributs `data-*` + `$(this)` PrestaShop 1.7 / 8.x`Media::addJsDef()` + fichier JS externe + contrôleur AJAX Boucle foreachToujours `$(this).data('key')`, jamais sélecteur de classe global SécuritéToken CSRF + `intval` + `escape` + validation serveur
#smarty #jquery #javascript #ajax #templates #data-attributes

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.