Child Themes PrestaShop : Guide de personnalisation Classic & Hummingbird
Créez des thèmes enfants PrestaShop pour Classic et Hummingbird — overrides de templates, personnalisation SCSS, hooks JavaScript et nouveautés PS 9.
Qu’est-ce qu’un thème enfant et pourquoi c’est important
Un thème enfant hérite des templates et des ressources d’un thème parent tout en vous permettant de ne surcharger que ce que vous modifiez. Sans thème enfant, chaque modification CSS ou édition de template se trouve dans les fichiers du parent — et sera écrasée lors de la prochaine mise à jour.
Un thème enfant est une couche transparente. PrestaShop cherche d’abord dans le thème enfant. S’il trouve un fichier, il l’utilise. Sinon, il se rabat sur le parent. Vous n’incluez que ce que vous modifiez.
Utilisez un thème enfant pour des modifications ciblées — couleurs, ajustements de mise en page, surcharges de templates, CSS/JS personnalisés. Créez un thème entièrement personnalisé uniquement lorsque vous avez besoin d’une architecture fondamentalement différente.
| Thème parent | Version PS | Framework | Idéal pour |
|---|---|---|---|
| Classic | 1.7.x / 8.x | Bootstrap 4, jQuery | Compatibilité maximale, base stable |
| Hummingbird | 8.1+ / 9.x | Bootstrap 5.3, TypeScript | Boutiques modernes, préparation à PS 9 |
Pour les nouveaux projets sur PrestaShop 8.1+, choisissez Hummingbird — c’est le thème par défaut orienté vers l’avenir et le seul thème activement maintenu par le projet PrestaShop.
Structure d’un thème enfant
Un thème enfant se trouve à côté de son parent dans le répertoire /themes/. Le thème enfant minimal ne nécessite que deux fichiers :
themes/my-child-theme/
config/
theme.yml <-- requis : configuration du thème
preview.png <-- requis : aperçu du thème 200x200
À mesure que les personnalisations s’accumulent, le répertoire reproduit la structure du parent mais ne contient que les fichiers modifiés :
themes/my-child-theme/
config/theme.yml
assets/
css/custom.css
js/custom.js
templates/
catalog/product.tpl
_partials/header.tpl
modules/
ps_featuredproducts/views/templates/hook/
ps_featuredproducts.tpl
translations/en-US/Shop/Theme.xlf
preview.png
N’ajoutez que les fichiers que vous modifiez. Chaque fichier ajouté est un fichier que vous devrez maintenir. Un thème enfant vide qui hérite de tout est préférable à un thème encombré de copies inchangées.
La configuration theme.yml
Le fichier config/theme.yml est le cœur de votre thème enfant. La ligne essentielle est parent: classic (ou parent: hummingbird) — elle établit la chaîne d’héritage :
parent: classic
name: my-child-theme
display_name: My Child Theme
version: 1.0.0
author:
name: "Your Name"
email: "you@example.com"
url: "https://yoursite.com"
meta:
compatibility:
from: 1.7.0.0
to: ~
assets:
use_parent_assets: true
theme_settings:
default_layout: layout-full-width
layouts:
category: layout-left-column
Créer un thème enfant pour Classic
Classic est le thème par défaut original de PrestaShop depuis la version 1.7. Le processus se fait en quatre étapes :
# 1. Créer le répertoire
mkdir -p themes/my-classic-child/config
# 2. Créer config/theme.yml avec parent: classic (voir ci-dessus)
# 3. Ajouter preview.png (200x200)
# 4. Activer via le Back Office > Apparence > Thème & Logo
# Ou en CLI : php bin/console prestashop:theme:enable my-classic-child
Avec use_parent_assets: true et aucune surcharge, vous obtenez une copie identique au pixel près de Classic. Les templates, CSS, JS, types d’images, mises en page et surcharges de templates de modules sont tous hérités.
Créer un thème enfant pour Hummingbird
Hummingbird utilise Bootstrap 5.3 (propriétés personnalisées CSS), les CSS Layers (@layer), TypeScript compilé avec Webpack 5 et une convention de nommage de type BEM (.product__name, .product__description-short). La mise en place est identique à Classic — créez le fichier theme.yml avec parent: hummingbird et la compatibilité from: 9.0.0. La différence réside dans la personnalisation des ressources.
Le système de CSS Layers de Hummingbird
Hummingbird définit cet ordre de couches dans son SCSS :
@layer vendors, bs-base, bs-components, bs-custom-components,
ps-base, ps-components, ps-pages, ps-modules, utilities;
Les styles des couches ultérieures surchargent les précédents, indépendamment de la spécificité des sélecteurs. Placez vos règles personnalisées dans la couche appropriée :
@layer ps-components {
.product__name {
font-family: 'Your Custom Font', sans-serif;
}
}
@layer ps-pages {
.page--category .product-miniature {
border: 1px solid #eee;
border-radius: 8px;
}
}
Compilation SCSS
Pour du SCSS personnalisé, ajoutez une étape de compilation. Créez un package.json avec sass comme dépendance de développement et des scripts pour build:css (sass src/scss/custom.scss assets/css/custom.css --style=compressed) et watch:css. Puis npm install && npm run build:css pour compiler.
Dart Sass peut ajouter un BOM UTF-8 au CSS compilé, ce qui amène les navigateurs à ignorer silencieusement des règles. Supprimez-le : sed -i '1s/^\xEF\xBB\xBF//' assets/css/custom.css
Surcharges de templates
Les surcharges de templates sont le point fort des thèmes enfants. PrestaShop utilise Smarty, qui prend en charge un modèle d’héritage propre.
Ordre de résolution des templates
- Thème enfant —
themes/my-child/templates/ - Thème parent —
themes/hummingbird/templates/
Méthode 1 : Copie complète (simple, moins maintenable)
Copiez le template parent et modifiez-le. Votre version remplace entièrement celle du parent :
cp themes/hummingbird/templates/catalog/product.tpl \
themes/my-child/templates/catalog/product.tpl
Inconvénient : Vous êtes responsable de l’intégralité du fichier. Les mises à jour du parent pour ce template ne vous parviendront pas.
Méthode 2 : Smarty {extends} (recommandée)
Étendez le template parent et ne surchargez que des blocs spécifiques :
{extends file='parent:catalog/listing/category.tpl'}
{block name='product_list_header'}
<div class="custom-category-header">
<h1>{$category.name}</h1>
<p>{$listing.pagination.total_items} products</p>
</div>
{/block}
Le préfixe parent: est essentiel — sans lui, Smarty trouve le propre fichier du thème enfant et crée une boucle infinie.
Modificateurs de blocs
Au lieu de remplacer un bloc entièrement, ajoutez du contenu avant ou après :
{extends file='parent:catalog/product.tpl'}
{block name='product_description' append}
<div class="shipping-notice">Free shipping on orders over $50</div>
{/block}
{block name='product_prices' prepend}
<span class="price-badge">Best Price</span>
{/block}
Structure des blocs de Hummingbird
Points de surcharge clés dans la page produit de Hummingbird (catalog/product.tpl) :
{block name='product_cover_thumbnails'} — images du produit
{block name='product_header'} — nom du produit (h1)
{block name='product_manufacturer'} — lien de la marque
{block name='product_prices'} — affichage du prix
{block name='product_description_short'} — description courte
{block name='product_variants'} — sélecteurs de déclinaisons
{block name='product_add_to_cart'} — bouton d’ajout au panier
{block name='product_tabs'} — accordéon description/détails
{block name='product_accessories'} — produits associés
Pour trouver les blocs disponibles sur n’importe quelle page, lisez le fichier de template du thème parent — chaque {block name='...'} est un point de surcharge.
Personnalisation CSS
Enregistrer le CSS dans theme.yml
assets:
use_parent_assets: true
css:
all:
- id: my-child-custom-style
path: assets/css/custom.css
media: all
priority: 200
Les valeurs de priority plus élevées sont chargées en dernier, vous permettant de surcharger les styles du parent. Pour Hummingbird, préférez les déclarations @layer plutôt que de lutter contre la spécificité. Pour Classic, reproduisez la profondeur des sélecteurs du parent. Évitez !important.
Changer la palette de couleurs
Pour Hummingbird (Bootstrap 5), surchargez les propriétés personnalisées CSS :
:root {
--bs-primary: #2563eb;
--bs-primary-rgb: 37, 99, 235;
--bs-body-font-family: 'Inter', system-ui, sans-serif;
}
Personnalisation JavaScript
Enregistrer le JS dans theme.yml
assets:
use_parent_assets: true
js:
all:
- id: my-child-custom-js
path: assets/js/custom.js
priority: 200
Remplacez all par un nom de page pour limiter la portée des scripts : product, category, cart, checkout, cms, index (page d’accueil), ou tout nom de contrôleur.
Événements JavaScript de PrestaShop
Vos scripts peuvent écouter les événements PrestaShop via l’objet global prestashop :
prestashop.on('updatedProduct', function(event) { /* combination changed */ });
prestashop.on('updateCart', function(event) { /* cart updated */ });
Disponibilité de jQuery
Avec Classic, jQuery est chargé globalement. Avec Hummingbird, jQuery 3.x est toujours chargé pour la compatibilité des modules, mais le thème lui-même utilise TypeScript. Pour le nouveau code de votre thème enfant, préférez le JavaScript natif.
Ne supprimez pas jQuery de votre thème enfant — vous casseriez les modules tiers qui en dépendent. Mais pour votre propre code, le JavaScript natif offre de meilleures performances et une meilleure compatibilité future.
Surcharges de templates de modules
Vous pouvez surcharger le rendu de n’importe quel module en plaçant des templates dans le répertoire modules/ de votre thème.
Ordre de résolution
- Thème enfant :
themes/my-child/modules/module_name/views/templates/... - Thème parent :
themes/parent/modules/module_name/views/templates/... - Le module lui-même :
modules/module_name/views/templates/...
Comment surcharger
Trouvez le template du module (par ex., modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl), copiez-le dans le chemin correspondant sous themes/my-child/modules/, et modifiez la copie. Le module peut se mettre à jour librement sans affecter votre version.
Les surcharges de thème ont la priorité absolue. Si un module met à jour son template pour corriger une faille de sécurité et que votre thème contient une ancienne copie, c’est l’ancienne version qui continuera d’être utilisée. Comparez périodiquement vos surcharges avec les versions actuelles des modules.
Traductions dans les thèmes enfants
Ordre de résolution des traductions :
- Traductions en base de données (Back Office > International > Traductions)
- Répertoire
translations/du thème enfant - Répertoire
translations/du thème parent - Traductions des modules
- Traductions du noyau
L’approche la plus simple est le Back Office (International > Traductions). Pour des traductions sous contrôle de version, créez des fichiers XLIFF à l’emplacement themes/my-child/translations/en-US/Shop/Theme/Global.xlf :
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file original="shop-theme-global" source-language="en-US"
target-language="en-US" datatype="plaintext">
<body>
<trans-unit id="add_to_cart" approved="yes">
<source>Add to cart</source>
<target>Add to bag</target>
</trans-unit>
</body>
</file>
</xliff>
Pour les boutiques multilingues, créez des fichiers par locale (translations/fr-FR/, translations/de-DE/). Videz le cache après les modifications : php bin/console cache:clear
Personnalisations courantes
Mise en page personnalisée du header
{extends file='parent:_partials/header.tpl'}
{block name='header_nav'}
<nav class="custom-header-nav container">
<div class="row align-items-center">
<div class="col-md-3">{hook h='displayNav1'}</div>
<div class="col-md-6 text-center">
<a href="{$urls.base_url}"><img src="{$shop.logo}" alt="{$shop.name}"></a>
</div>
<div class="col-md-3 text-end">{hook h='displayNav2'}</div>
</div>
</nav>
{/block}
Polices personnalisées
Placez les fichiers WOFF2 dans assets/fonts/ et référencez-les dans le CSS :
@font-face {
font-family: 'CustomFont';
src: url('../fonts/CustomFont-Regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
body { font-family: 'CustomFont', system-ui, sans-serif; }
Utilisez toujoursfont-display: swappour éviter le texte invisible pendant le chargement. Préchargez les polices critiques :<link rel="preload" as="font" type="font/woff2" crossorigin>.
Réorganiser la page produit
{extends file='parent:catalog/product.tpl'}
{block name='product_description_short'}
<div class="product__description-short">{$product.description_short nofilter}</div>
{if $product.description}
<div class="product__description-full mt-3">{$product.description nofilter}</div>
{/if}
{/block}
{block name='product_description'}{/block} {* removed from tabs *}
Changements de thème dans PS 9
- Hummingbird est le thème par défaut. Classic reste disponible, mais le développement actif cible Hummingbird.
- Smarty reste pour le front office. Twig est réservé au panneau d’administration. Vos surcharges
{extends}et{block}fonctionnent comme avant. - Bootstrap 5.3 remplace Bootstrap 4. Consultez le guide de migration si vous migrez depuis Classic.
- Les CSS Layers (
@layer) modifient le fonctionnement de la spécificité dans Hummingbird. - WebP par défaut pour les images. Nouvelle clé
frameworkdans theme.yml :bootstrap-v5.3.3. - Certaines variables globales JS historiques ont été supprimées. Testez minutieusement lors d’une migration depuis PS 8.
Twig pourrait à terme atteindre le front office dans une future version majeure. Écrire des templates propres avec un minimum de surcharges facilitera toute transition future.
Déboguer les problèmes de thème
Commencez par vider tous les caches : php bin/console cache:clear. En développement, réglez le cache des templates sur « Forcer la compilation » et désactivez CCC dans Paramètres avancés > Performances.
En développement, forcez toujours la compilation des templates et désactivez CCC. Sans cela, vous déboguez des fichiers en cache.
Activez le débogage Smarty en ajoutant ?SMARTY_DEBUG à n’importe quelle URL front. Cela affiche les templates chargés, les chemins de fichiers et les variables. Activez-le dans config/defines.inc.php en définissant _PS_SMARTY_FORCE_COMPILE_ et _PS_SMARTY_CONSOLE_ à 1.
Erreurs courantes
| Symptôme | Cause probable | Solution |
|---|---|---|
| Page blanche | Erreur de syntaxe Smarty | Vérifiez var/logs/ |
| Template introuvable | Chemin incorrect ou préfixe parent: manquant | Vérifiez que le chemin reproduit exactement celui du parent |
| Boucle infinie / timeout | {extends} sans préfixe parent: | Utilisez {extends file='parent:...'} |
| Contenu de bloc manquant | Nom de bloc incorrect | Vérifiez les noms exacts dans le template parent |
| CSS non appliqué | Problème de cache ou de spécificité | Videz le cache, vérifiez la priorité dans les DevTools |
| HTML doublement encodé | Auto-échappement d’un contenu déjà échappé | Utilisez {$var nofilter} |
Si le cache persiste, supprimez également var/cache/prod/smarty/compile/ et var/cache/prod/smarty/cache/.
Mises à jour avec les thèmes enfants
C’est là que les thèmes enfants prennent tout leur sens. Lorsque le parent est mis à jour :
- Fichiers uniquement dans le parent — mis à jour normalement, le thème enfant en hérite automatiquement.
- Fichiers surchargés dans le thème enfant — la version du thème enfant continue d’être utilisée, la mise à jour du parent est invisible.
- Fichiers propres au thème enfant — entièrement non affectés.
Avant la mise à jour : sauvegardez, listez vos surcharges (find themes/my-child/templates -name "*.tpl"), testez la mise à jour dans un environnement de préproduction (guide de développement local), comparez avec diff les templates parents modifiés par rapport à vos surcharges, et testez chaque page personnalisée.
Les surcharges ciblées avec {extends} sont supérieures aux copies de fichiers complets. Avec les surcharges de blocs, les nouveaux blocs du parent sont automatiquement inclus. Les copies de fichiers complets les ignorent entièrement.
Checklist de pré-lancement du thème enfant
Configuration : theme.yml contient les bonnes valeurs pour parent: et name: (minuscules, sans espaces). use_parent_assets: true est défini. preview.png existe. La plage de compatibilité correspond à votre version de PS.
Templates : Toutes les surcharges utilisent {extends file='parent:...'} dans la mesure du possible. Les noms de blocs correspondent exactement au parent. Aucune erreur Smarty dans var/logs/. Les surcharges de modules sont testées avec les versions actuelles des modules. nofilter est utilisé pour les variables HTML.
Ressources : Le CSS personnalisé se charge après le parent (valeur priority élevée). Pas d’abus de !important. Les polices utilisent font-display: swap et le format WOFF2. Aucune erreur JS dans la console. CCC activé sans provoquer de dysfonctionnement.
Tests : Bureau (Chrome, Firefox, Safari, Edge), mobile (iOS Safari, Android Chrome), points de rupture responsive. Vérifiez : page d’accueil, catégories, produit, panier, tunnel de commande, compte client, CMS, recherche, 404.
Maintenance : Thème enfant sous Git. Templates surchargés documentés. Processus de build documenté (consultez notre guide des outils de développement). L’équipe sait qu’il ne faut pas modifier les fichiers du parent.
More guides available
Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.