Sylius : Template versus Theme
J'ai eu à faire à beaucoup de projets Sylius ces derniers temps : développement, audit ou encore accompagnement d'équipe et architecture. À chaque prestation ou presque, une même question revient : quelle est la meilleure façon d'organiser ses templates ?
Au commencement : le SyliusThemeBundle
Ne vous laissez pas avoir par le nom, le SyliusThemeBundle est un bundle permettant d'ajouter une fonctionnalité de thème à un projet Symfony. Pour faire simple et compréhensible, un nouveau dossier “theme” est présent à la racine du projet et ajoute un niveau supplémentaire dans la hiérarchie de vos templates.
Étant donné qu'il s'agit d'un thème, vous pouvez en avoir plusieurs en parallèle. Le thème se déclare via un fichier composer.json
très simple et vient surcharger le système de templates que vous connaissez déjà sur Symfony. Le thème se trouve au plus haut de la hiérarchie des templates de votre projet et dans la continuité du système de fallback : un fichier qui n'existe pas dans le dossier thème est un fichier qui sera recherché dans le dossier templates (puis dans un bundle etc).
Le thème à afficher peut se choisir de bien des manières et même très simplement. Tout est imaginable à ce niveau. Vous pouvez spécifier un thème par défaut pour votre projet et/ou déclencher l'activation d'un thème suivant vos critères : session, base de données, aléatoire (pour de l'A/B testing) ou encore suivant l'utilisateur connecté... Vous êtes libres d'implémenter vos propres règles et de les hiérarchiser.
Fonctionnalité intéressante, un thème peut en étendre un autre. Vous pouvez avoir un thème de base, puis d'autres qui ne feront que surcharger quelques fichiers : vive les usines à sites.
Qu'est-ce que l'on met dans un thème ?
Récapitulons : un thème n'est qu'un ensemble de fichiers Twig qui vont venir en surcouche des templates Symfony. On y met donc ce que l'on souhaite en respectant l'arborescence des templates du projet. Assets et translations peuvent également être ajoutés.
Passons maintenant au problème de fond, comment organiser tout ça.
Je vois, dans beaucoup de projets, des thèmes dans lesquels on met tous les templates sans se poser la question suivante : que se passe-t-il si le thème est désactivé ?
La réponse est assez simple, si vous désactivez un thème, vous ne voyez plus les éléments correspondants. C'est pourquoi il est très important de respecter la hiérarchie des templates et les fallbacks. Un thème surcharge la totalité de vos templates, interface d'administration comprise (dans le cas de Sylius), ce qui peut être un vrai problème si vous avez ajouté des champs de formulaires dans l'interface d'administration par exemple.
Et donc ?
L'arbre de décision est donc le suivant :
- si un template doit TOUJOURS être présent dans un projet, que le thème soit activé ou non : il ne doit pas seulement exister dans le thème du projet, mais dans les templates (avant de potentiellement être surchargé dans un ou plusieurs thèmes),
- si un template doit être visible UNIQUEMENT si le thème est activé : le template doit être dans le dossier
themes
correspondant, - si un template peut exister dans plusieurs thèmes différents, vous pouvez utiliser la hiérarchie des thèmes (parent/enfant) afin d'éviter les copier/coller.
Coté JS, il n'est pas possible détecter le thème pour ne faire un build que si le thème est actif. Ce n'est pas un problème : faites vos build en définissant la config webpack dans votre thème puis un require
dans votre fichier webpack applicatif.
Une fois compilé, le coût technique est nul.
// webpack.config.js
const Encore = require('@symfony/webpack-encore');
// Votre config existante
// stuff
const front = Encore.getWebpackConfig();
// Fin de la config existante
Encore.reset();
const bootstrapTheme = require('./themes/BootstrapTheme/webpack.config');
module.exports = [front, bootstrapTheme];
Conclusion, respectez ces règles : vous serez joie et amour.