Pour un de mes employeurs, j'ai du tester tester Craft CMS sur un vrai projet — pas une démo, un site complet avec formulaire, contenu dynamique et back-office — je m'attendais à retrouver les mêmes réflexes que des CMS traditionnelles (Wordpress/Drupal/Joomla). Ce n'a pas du tout été le cas, et c'est justement ce qui rend l'outil intéressant. Voici ce que j'ai retenu, avec de vrais bouts de code à l'appui.
1. Tout part d'un principe : séparer la structure du contenu
Dans WordPress, un article et une page sont des "types de contenu" déjà prédéfinis, qu'on étend ensuite avec des plugins (ACF, custom post types...). Dans Craft, c'est l'inverse : rien n'existe par défaut. On définit soi-même chaque type de contenu — une "Section" — et la liste exacte de champs qui le compose, avant même d'écrire une ligne de template.
Concrètement, ça veut dire qu'un champ ne peut pas traîner "juste au cas où" : chaque type de contenu n'a que les champs dont il a réellement besoin. Le formulaire d'édition dans le CP (l'admin) reste toujours propre et lisible, même après des mois d'évolutions.
2. Les champs Matrix : des blocs de contenu réutilisables
Le champ le plus puissant que j'ai utilisé s'appelle un champ Matrix. Il permet de transformer une zone de la page en une liste de blocs réordonnables, chacun avec sa propre structure. Par exemple, une section "services" avec une icône, un titre, un texte et un lien — sans jamais toucher au code une fois que c'est en place :
{% for bloc in entry.services.all() %}
<div class="service">
<img src="/icons/{{ bloc.icone }}" alt="">
<h3>{{ bloc.titre }}</h3>
<p>{{ bloc.texte }}</p>
{% if bloc.lien %}
<a href="{{ bloc.lien.url }}">{{ bloc.lien.label }}</a>
{% endif %}
</div>
{% endfor %}
Le client (ou la personne qui gère le contenu) peut ajouter, retirer ou réordonner ces blocs depuis le CP, sans jamais pouvoir casser la mise en page — puisque la structure elle-même est verrouillée par le développeur en amont.
3. Twig, un langage de template qui force à séparer logique et affichage
Craft utilise Twig plutôt que du PHP mélangé au HTML. Au début ça déroute un peu, mais on s'y fait vite : c'est lisible, sécurisé par défaut (tout est échappé automatiquement) et ça oblige à garder la logique métier hors des templates. Un exemple simple, n'afficher que les entrées actives et publiées :
{% set articles = craft.entries()
.section('actualites')
.actif(true)
.orderBy('date DESC')
.all()
%}
{% for article in articles %}
<h4>{{ article.title }}</h4>
{% endfor %}
4. Les migrations : chaque changement de structure est versionné
C'est le point qui m'a le plus surpris. Ajouter un champ, créer une section, modifier un type de contenu — tout ça peut (et devrait) passer par une migration : un fichier PHP versionné dans Git, exécuté une seule fois, qui documente précisément ce qui a changé et pourquoi.
class m250101_120000_add_subtitle_field extends Migration
{
public function safeUp(): bool
{
$field = new \craft\fields\PlainText([
'name' => 'Sous-titre',
'handle' => 'subtitle',
]);
return Craft::$app->getFields()->saveField($field);
}
}
Résultat : on peut reconstruire exactement le même site sur une autre machine, revenir en arrière si besoin, et savoir précisément quand et pourquoi un champ a été ajouté. Sur WordPress, ce genre de changement se fait le plus souvent directement dans l'admin, sans aucune trace.
5. Modules et plugins : deux façons d'étendre le CMS
Craft distingue clairement deux types d'extensions. Un module est du code propre à un projet, sans interface d'administration prête à l'emploi — parfait pour une fonctionnalité sur mesure (un formulaire de contact avec sa propre liste de messages dans le CP, par exemple). Un plugin, même très simple, hérite automatiquement d'une page de réglages dans l'admin :
class Plugin extends \craft\base\Plugin
{
public bool $hasCpSettings = true;
protected function createSettingsModel(): ?Model
{
return new Settings();
}
protected function settingsHtml(): ?string
{
return Craft::$app->view->renderTemplate(
'mon-plugin/settings',
['settings' => $this->getSettings()]
);
}
}
Ces quelques lignes suffisent à obtenir un vrai écran de réglages, sauvegardé et versionné comme le reste de la configuration du site — sans dépendre d'un plugin tiers pour ça.
6. Ce que ça change concrètement pour un développeur
La contrepartie est réelle : il faut connaître PHP, apprendre Twig, et surtout comprendre la logique de modélisation propre à Craft avant de devenir productif. L'écosystème d'extensions est aussi beaucoup plus restreint que celui de WordPress — pour un besoin courant, il faut souvent coder soi-même plutôt que trouver un plugin tout fait.
En échange, on obtient un contenu structuré, un historique de chaque changement, et un back-office qui reste propre quel que soit le nombre de fonctionnalités ajoutées au fil du temps. Pour un site qui va vivre plusieurs années et évoluer souvent, c'est un compromis qui vaut clairement la peine d'être évalué.
En résumé
- Les Sections et types d'entrées remplacent les custom post types — sans plugin, nativement.
- Les champs Matrix permettent de créer du contenu structuré et réordonnable par blocs.
- Twig impose une séparation propre entre logique et affichage.
- Les migrations versionnent chaque évolution de structure, comme du code.
- Modules et plugins couvrent respectivement le sur-mesure et les fonctionnalités avec interface d'admin.
Ce n'était que mon premier vrai projet avec l'outil — mais assez pour comprendre que c'est vraiment un outil taillé pour principalement les devs et bien structuré un site internet .