Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Développez avec PHP pour PrestaShop
  3. Thèmes
Extrait - Développez avec PHP pour PrestaShop Architecture, personnalisation, thèmes et conception de modules
Extraits du livre
Développez avec PHP pour PrestaShop Architecture, personnalisation, thèmes et conception de modules
4 avis
Revenir à la page d'achat du livre

Thèmes

Introduction

À l’instar d’un module qui est conçu pour apporter une nouvelle fonctionnalité à la boutique PrestaShop, le thème est un élément important dans la présentation de celle-ci.

PrestaShop embarque par défaut un thème nommé Classic : https://github.com/PrestaShop/classic-theme

Hérité de PrestaShop 1.7, il embarque notamment une version alpha de la librairie CSS Bootstrap, en sa version 4.

Une alternative plus moderne développée par PrestaShop est le thème Hummingbird (https://github.com/PrestaShop/hummingbird), qui utilise la version 5 de Bootstrap.

Au-delà de ces deux thèmes existants, vous trouvez bon nombre de thèmes en vente, apportant chacun leur spécificité : travail du SEO, rendu graphique ou encore fonctionnalités de personnalisation avancées.

Et, bien entendu, vous pouvez également concevoir votre propre thème afin de restituer une maquette graphique aux visiteurs d’une boutique PrestaShop.

Au sein de ce chapitre, vous allez avoir un aperçu de l’utilisation des thèmes sous PrestaShop et de comment modifier un thème existant, en se basant sur le thème inclus par défaut.

Structure d’un thème

L’ensemble des fichiers constituant un thème est présent dans un dossier qui lui est propre et dont le nom est unique.

Chaque dossier de thème est contenu dans le dossier /themes.

Le moteur de rendu utilisé pour les thèmes étant le même que celui des modules, il s’agit de Smarty.

La structure d’un thème peut se rapprocher de ceci :

  . 
  ├── _dev 
  │   ├── css 
  │   │   └── ... 
  │   ├── js 
  │   │   └── ... 
  │   ├── package.json 
  │   └── webpack.config.js 
  ├── assets 
  │   ├── css 
  │   │   ├── ... 
  │   ├── img 
  │   │   └── ... 
  │   └── js 
  │       └── ... 
  ├── composer.json 
  ├── config 
  │   └── theme.yml 
  ├── dependencies 
  │   └──...

Fichier de configuration

1. Paramètres généraux

Lors de la création d’un thème, un fichier de configuration basique est requis.

Il reprend notamment le nom du thème, sa version ainsi que sa plage de compatibilité. 

Ce fichier, au format YAML, est situé dans le dossier /themes/eni/config/ - eni étant le nom du répertoire associé au thème que l’on crée - et se nomme theme.yml. 

La propriété name doit impérativement correspondre au nom du répertoire.

name: eni 
display_name: Theme ENI 
version: 1.0.0 
author: 
  name: "Jonathan Danse" 
  email: "j.danse@prestaedit.com" 
  url: "https://prestaedit.github.io/" 
 
meta: 
  compatibility: 
    from: 8.0.0 
    to: ~ 

Il n’est pas obligatoire d’indiquer la plage de compatibilité maximale par le biais du paramètre to.

À l’heure actuelle, les paramètres de compatibilité ne sont pas pris en considération.

2. Paramètres spécifiques

a. Configuration

Lors de l’activation d’un thème, il est possible de modifier les valeurs de configurations stockées dans la table configurations.

Ceci permet notamment de désactiver un comportement tel que l’aperçu rapide, le panier en mode AJAX ou encore de modifier le nombre de produits par page visible dans un listing produits.

Vous avez également la possibilité d’ajouter de nouvelles configurations propres à votre thème et qui seraient utilisée par un module embarqué dans ce dernier.

global_settings: 
  configuration: 
    PS_QUICK_VIEW: false 
    PS_PRODUCTS_PER_PAGE: 8 
    ENI_CUSTOM: true 

b. Modules

L’activation d’un thème permet l’activation, la désactivation et l’action de réinitialisation sur un à plusieurs modules.

Les modules ciblés par l’activation ne doivent pas impérativement être embarqués dans le thème mais doivent toutefois être présents dans votre installation, le cas échéant. Cela n’est pas requis dans le cas d’une réinitialisation.

global_settings: 
  modules: 
    to_enable: 
      # Les modules doivent être présents 
      - enithemeeditor 
      - ps_mainmenu 
    to_disable: 
      - eninotexists 
      - blockwishlist 
    to_reset: 
      - ps_mainmenu 
      - eninotexists 

Les modules repris sous la propriété to_enable sont désactivés lorsque le thème n’est plus utilisé.

De même, ceux repris sous la propriété to_disable sont à nouveau activés lorsque le thème n’est plus utilisé.

c. Hooks

Tout...

Fichiers requis

Pour qu’un thème soit considéré comme valide et soit donc installable sur une boutique, cela requiert l’existence d’un ensemble de fichiers dans son répertoire associé :

  • preview.png

  • config/theme.yml

  • assets/js/theme.js

  • assets/css/theme.css

De plus, un ensemble de templates est requis :

  • templates/_partials/form-fields.tpl

  • templates/catalog/product.tpl

  • templates/catalog/listing/product-list.tpl

  • templates/checkout/cart.tpl

  • templates/checkout/checkout.tpl

  • templates/cms/category.tpl

  • templates/cms/page.tpl

  • templates/customer/address.tpl

  • templates/customer/addresses.tpl

  • templates/customer/guest-tracking.tpl

  • templates/customer/guest-login.tpl

  • templates/customer/history.tpl

  • templates/customer/identity.tpl

  • templates/index.tpl

  • templates/customer/my-account.tpl

  • templates/checkout/order-confirmation.tpl

  • templates/customer/order-detail.tpl

  • templates/customer/order-follow.tpl

  • templates/customer/order-return.tpl

  • templates/customer/order-slip.tpl

  • templates/errors/404.tpl

  • templates/errors/forbidden.tpl

  • templates/checkout/cart-empty.tpl

  • templates/cms/sitemap.tpl

  • templates/cms/stores.tpl

  • templates/customer/authentication.tpl

  • templates/customer/registration.tpl

  • templates/contact.tpl

Il existe également un ensemble de templates qui, contrairement aux précédents, sont implicitement requis de par leur utilisation au sein du code et non par la contrainte de validation du thème :

  • templates/catalog/_partials/miniatures/product.tpl...

Gestions des assets

Au sein de la configuration du thème, vous avez pu voir que PrestaShop charge un ensemble de fichiers par défaut et qu’il vous est possible de définir l’ajout d’assets selon vos besoins.

D’autres manipulations sont possibles.

1. Décharger un asset

Oubli ou volonté de la part du logiciel, si la configuration d’un thème permet d’enregistrer simplement un asset, il n’est toutefois pas possible de supprimer l’un de ceux ajoutés par défaut via cette même configuration.

Une solution rapide - et simpliste - consisterait à inclure un fichier vide de contenu au sein du thème et ayant les mêmes nom et chemin que le fichier ciblé.

La mécanique de surcharge - qui est vue plus en détail au sein du chapitre Pour aller plus loin - prend alors le dessus.

Cette méthode a l’avantage de nécessiter de connaître uniquement le chemin de base du fichier.

Une autre solution - via un module - serait d’utiliser le point d’accroche relatif à la gestion des médias.

public function hookActionFrontControllerSetMedia($params) 
{ 
    $this->context->controller->unregisterJavascript('used-id'); 
 
    $this->context->controller->unregisterStylesheet('used-id'); 
} 

Cette méthode a pour avantage de pouvoir désactiver temporairement le retrait des médias ou encore d’affiner selon des conditions déterminées les moments de désenregistrements.

Toutefois, vous devez obligatoirement connaître l’identifiant utilisé - par le thème ou le module - pour l’enregistrement du média, ce qui n’est pas toujours chose aisée.

2. Webpack

Outil open-source de type module bundler, il permet notamment de compiler les assets de conception.

Son utilisation n’est pas requise et vous pouvez librement utiliser l’outil qui vous convient le mieux.

Le thème par défaut inclus par PrestaShop utilisant ce dernier, une rapide introduction est réalisée à son sujet.

a. Installation

Webpack est un outil qui nécessite l’installation de NodeJS.

Ce dernier embarque avec lui NPM - un package manager JavaScript - facilitant la gestion des packages au même titre que Composer pour le PHP.

La version de NodeJS utilisée doit être la 14.x ou 16.x tandis que la version de NPM doit être la version 7.x ou 8.x.

Pour procéder à l’installation de NodeJS, rendez-vous sur son site officiel (https://nodejs.org/) pour y télécharger la version correspondant à votre système d’exploitation.

Une fois l’installation faite, et pour la vérifier...

Core.js

Ce fichier, chargé par défaut et fournit par PrestaShop, embarque un ensemble de fonctions définissant une logique commune à l’ensemble des thèmes.

On y retrouve notamment des fonctions utiles concernant le panier, les facettes ou encore le listing de produits.

Compilé, il n’a pas vocation à être modifié. Les sources servant à la compilation de ce fichier se situent dans le dossier /themes/_core/js accessible sur le repository GitHub de PrestaShop. Elles ne sont pas incluses dans une version packagée. 

Par ailleurs, le fichier core.js embarque également la librairie jQuery par défaut. 

La version 3.5 de cette dernière est utilisée.

Le core.js étant chargé indépendamment du thème utilisé, vos modules peuvent s’appuyer dessus sans crainte.

1. Fonctions utiles

Des fonctions utiles sont ajoutées au sein du JavaScript utilisé pour former le core.js.

Ces méthodes n’étant pas exposées, elles ne sont toutefois pas utilisables directement. 

Vous pouvez faire soit une utilisation indirecte soit une copie de celles-ci dans votre propre logique JavaScript.

psShowHide()

Cette fonction est appelée lors de chaque ouverture de page.

Elle permet d’afficher ou de masquer du contenu au sein du DOM lorsqu’il est entièrement chargé, via l’utilisation des fonctions show() et hide() de jQuery.

Pour afficher un élément, la classe ps-show-by-js doit lui être attribuée.

Dans le cas contraire, pour masquer un élément...

Les thèmes enfants

Un thème est dit enfant lorsqu’il repose sur un thème existant, son parent.

Il hérite de l’ensemble des paramètres, des assets ainsi que des templates du thème de référence.

Cela permet de modifier le comportement d’un thème en ciblant les modifications effectuées.

1. Créer un thème enfant

Un thème enfant se définit de la même manière que n’importe quel autre thème : il comporte une prévisualisation, une configuration ainsi que des templates. 

Pour qu’il soit valide, la seule contrainte réside dans sa structure :

  . 
  ├── config 
  │   └── theme.yml 
  └── preview.png 

La configuration du thème est également minimaliste :

parent: eni 
name: enichild 
display_name: Theme enfant pour le theme ENI 
version: 1.0.0 

2. Charger les assets du thème parent

Au sein d’un thème, les assets sont placés dans un dossier nommé assets.

Ce dernier contient à son tour les dossiers img, css et js.

PrestaShop vous fournit un ensemble de variables Smarty utilisables directement dans vos templates pour cibler les dossiers selon vos besoins.

{$theme_assets} {* /themes/<nom du thème>/assets/ *} ...

Smarty

1. Hooks

Au sein d’un template, vous pouvez effectuer un appel de module en précisant un point d’accroche particulier.

{* Peu importe le module *} 
{hook h='displayContent'} 
 
{* Uniquement le module enimodule *} 
{hook h='displayContent' mod='enimodule'} 

2. Widgets

De la même manière, un widget peut être inclus.

{widget name='enimodule'} 
{widget name='enimodule' hook='displayContent'} 

3. Plugins

En tant que moteur de rendu, Smarty embarque un ensemble de microcomposants pouvant définir des fonctions ou encore des modificateurs de variables : les plugins.

Vous avez la possibilité d’ajouter vos propres plug-ins.

Une documentation détaillée sur la conception de plug-in pour Smarty est disponible sur le site de ce dernier : https://www.smarty.net/docs/en/plugins

a. Ajouter une fonction

Une fonction, à l’instar de {hook} ou de {widget} ajoutées par PrestaShop, permet de réaliser un traitement spécifique et d’effectuer ensuite un rendu.

Pour ajouter une fonction au sein d’un thème, vous devez ajouter le fichier dans le dossier plug-ins de celui-ci.

Le nom de fichier répond à la norme suivante : function.<nom de la fonction>.php. 

Ajoutons...

Événements JavaScript

Certaines actions, telles que le changement de déclinaisons, peuvent entraîner des événements JavaScript.

Ils sont émis par le core.js et sont principalement gérés par le theme.js. Certains événements sont traités également par le core, au sein de composants.

Pour que votre thème soit en mesure d’intercepter ces événements, vous devez ajouter les imports suivants dans votre fichier d’entrée :

import prestashop from 'prestashop'; 
import EventEmitter from 'events'; 
 
// "inherit" EventEmitter 
for (const i in EventEmitter.prototype) { 
    prestashop[i] = EventEmitter.prototype[i]; 
}  

Ceci a pour effet de rajouter à l’objet prestashop les prototypes définis par EventEmitter : emit et on.

D’autres prototypes comme off ou once sont également inclus.

La documentation sur leur utilisation est disponible ici : https://nodejs.org/docs/latest-v16.x/api/events.html

1. Transmettre un événement

Pour envoyer un événement, la fonction emit() est utilisée.

prestashop.emit('editAddress'); 
 
// Avec des arguments 
prestashop.emit('updatedDeliveryForm', { 
    dataForm: $deliveryMethodForm.serializeArray(), ...

Sélecteurs JavaScript

Au sein du DOM généré, un ensemble de classes et d’identifiants sont attribués aux différents éléments qui composent une page.

Afin de limiter les modifications du JavaScript lorsqu’une classe associée à un élément HTML est vouée à être modifiée au sein du thème, les sélecteurs sont globalement définis au sein d’un seul et même fichier (selectors.js) et sont rattachés à l’objet prestashop.

On retrouve la propriété selectors pour les sélecteurs issus du core et themeSelectors pour ceux déclarés par le thème.

Dans votre thème, vous pouvez donc altérer le fichier pour y faire figurer les changements. Cela nécessite une copie globale du fichier, ce que l’on pourrait vouloir éviter dans le cadre d’un thème enfant.

Dans le cas des sélecteurs issus du core, mais également de ceux du thème, vous pouvez procéder à une surcharge des déclarations effectuées initialement.

prestashop.once('selectorsInit', () => { 
    prestashop.selectors.cart.overview = 
'.cart-overwiew-overrided'; 
}); 
 
prestashop.once('themeSelectorsInit', () => { 
    prestashop.themeSelectors.cart.displayPromo...

Prise en charge du RTL

Lorsque la langue utilisée sur la boutique PrestaShop est une langue dite RTL (Right to Left), un nouvel asset est automatiquement chargé :

  • /assets/css/rtl.css

Cette feuille de style vous permet d’ajuster le style au besoin.

De plus, pour toute feuille de style enregistrée par la méthode registerJavascript(), la même feuille de style disposant du suffixe _rtl sera automatiquement ajoutée.

La feuille de style theme_rtl.css est ajoutée en même temps que theme.css.

La feuille de style custom_rtl.css est ajoutée en même temps que custom.css.

Lorsque le thème ne dispose pas de ces alternatives ou de feuille de style spécifique à la prise en charge du RTL, PrestaShop vous permet d’en générer automatiquement.

Cette transformation s’appuie sur l’utilisation de CSSJanus : https://github.com/cssjanus/cssjanus

Pour cela, rendez-vous dans Apparence - Thème et logo.

images/06EI05.png

Lorsque vous passez le paramètre Générer une feuille de style RTL à Oui et que vous validez le formulaire, l’ensemble des feuilles de style présentes dans le dossier du thème - peu importe l’endroit - disposent d’une version déclinée. 

Lorsque le fichier décliné existe déjà, il n’est pas remplacé. Il vous faut le supprimer pour le générer...

Utilisation de templates spécifiques

Les templates d’entrées sont appelés par les contrôleurs ou les modules. Chaque template appelé peut à son tour utiliser d’autres templates plus spécifiques, permettant ainsi de découper une page sur plusieurs fichiers.

Ainsi, toutes les catégories font appel au même template initial (category.tpl).

On peut donc définir qu’une entité donnée utilise un template donné.

Selon la locale utilisée ou encore l’identifiant de l’entité visionnée, vous devrez parfois proposer une présentation qui diffère de la version commune.

La récupération du template est faite en fonction d’une hiérarchie précise.

Prenant exemple sur le lien de la catégorie « Vêtements » par défaut (/3-vetements), en voici la liste :

  • fr-FR/catalog/listing/category-3.tpl

  • catalog/listing/category-3.tpl

  • fr-FR/catalog/listing/category.tpl

  • catalog/listing/category.tpl

  • fr-FR/catalog/listing/product-list.tpl

  • catalog/listing/product-list.tpl

En ajoutant un fichier portant l’un des noms ci-dessus dans le dossier templates de votre thème, celui-ci est utilisé. Si plusieurs de ces fichiers existent, le premier trouvé en parcourant la liste de haut en bas est celui utilisé.