Aller au contenu principal

Développeur WordPress : sortir du thème acheté

Un thème premium à soixante euros, deux extensions de mise en page, quarante réglages cochés et un site livré en trois jours. Puis vient la demande que le thème ne sait pas faire. Cet article décrit ce qui bloque à ce moment précis, les quatre points d'extension de WordPress à connaître, du code pour chacun, et les pièges qui transforment un site en dette technique.

Outils & environnement ·
Adel LATIBI
Adel LATIBI

Le Briefing Dev - les ressources et actus de la semaine, droit dans ta boîte chaque vendredi gratuitement.

En vous inscrivant, vous acceptez de recevoir notre newsletter. Désinscription possible à tout moment.

Il existe une frontière très nette entre deux métiers qui portent le même nom sur les fiches de poste. D'un côté, l'intégrateur WordPress : il choisit un thème, installe des extensions, configure, et livre vite. De l'autre, le développeur WordPress : il écrit du PHP, crée des types de contenu, branche du code sur les événements du cœur et livre un site dont il contrôle chaque ligne.

Le passage d'un rôle à l'autre ne se fait pas en apprenant un nouvel outil. Il se fait en comprenant comment WordPress est construit à l'intérieur, ce qui reste largement invisible tant qu'on travaille depuis l'interface d'administration. Voici cette structure, avec le code qui va avec.

Le problème : la demande que le thème ne sait pas faire

Un client vend des formations. Il veut une page par session, avec une date, un lieu, un nombre de places, un tarif, et une page listant les sessions à venir triées par date, filtrables par ville. Rien d'extraordinaire.

Avec un thème acheté, la réponse habituelle consiste à créer des articles, à bricoler des catégories qui servent de villes, à écrire les dates dans le corps du texte, et à trier par date de publication en croisant les doigts. Le site fonctionne pendant trois mois. Puis le client demande de masquer automatiquement les sessions passées, et là, il n'existe aucune case à cocher.

Les autres symptômes du plafond arrivent souvent ensemble : une page d'accueil qui charge en cinq secondes parce que l'extension de mise en page ajoute deux cents kilo-octets de CSS et de JavaScript, un site impossible à migrer sur un autre thème sans tout réécrire, une mise à jour du thème qui efface les modifications faites directement dans ses fichiers, et une facture qu'on n'ose pas augmenter parce que le travail réel se voit mal.

Le principe : quatre points d'extension, trois couches

WordPress n'est pas un logiciel fermé qu'on configure, c'est un socle qui expose des points d'accroche. Quatre suffisent à couvrir la quasi-totalité des besoins d'un site sur mesure.

Les hooks d'abord. Le cœur de WordPress annonce en permanence ce qu'il est en train de faire, et n'importe quel code peut s'y brancher : les actions permettent d'exécuter quelque chose à un moment donné, les filtres permettent de modifier une valeur avant qu'elle ne soit utilisée. C'est le mécanisme qui rend une modification durable, parce qu'elle vit dans ton code et pas dans les fichiers d'un thème que sa mise à jour va écraser.

La hiérarchie de templates ensuite. Pour chaque URL demandée, WordPress cherche un fichier de gabarit en suivant un ordre précis, du plus spécifique au plus général. Une page de catégorie cherche d'abord un gabarit dédié à cette catégorie, puis un gabarit de catégorie générique, puis un gabarit d'archive, puis le gabarit par défaut. Connaître cet ordre transforme la question "où est-ce que je modifie ça" en réponse immédiate.

Les types de contenu et champs personnalisés ensuite. Un article et une page sont deux types parmi d'autres. Une session de formation, un bien immobilier ou une recette méritent leur propre type, avec leurs propres champs, plutôt que d'être tordus dans le moule de l'article.

Le fichier theme.json enfin, arrivé avec les thèmes de blocs. Il déclare la palette, les tailles de texte, les espacements et les réglages disponibles dans l'éditeur, en un seul endroit. Le thème par défaut livré avec WordPress est aujourd'hui un thème de blocs, et l'éditeur de site a remplacé l'ancien personnalisateur.

Données types de contenu champs, taxonomies extension métier Présentation gabarits, blocs theme.json thème Comportement actions et filtres requêtes, sécurité extension métier Ce qui doit survivre à un changement de thème vit dans une extension, pas dans functions.php.
La répartition qui détermine si un site pourra changer d'habillage sans être reconstruit.

Le code, étape par étape

Déclarer un type de contenu

Le code ci-dessous crée le type "session" avec son propre menu dans l'administration. Il va dans une extension maison, pas dans le thème, parce que les sessions du client doivent survivre à un changement de design.

<?php
add_action( 'init', 'lp_enregistrer_type_session' );
 
function lp_enregistrer_type_session() {
    register_post_type( 'session', array(
        'labels' => array(
            'name'          => 'Sessions',
            'singular_name' => 'Session',
        ),
        'public'       => true,
        'has_archive'  => true,
        'menu_icon'    => 'dashicons-calendar-alt',
        'supports'     => array( 'title', 'editor', 'thumbnail', 'custom-fields' ),
        'show_in_rest' => true,
        'rewrite'      => array( 'slug' => 'sessions' ),
    ) );
}

L'option show_in_rest mérite qu'on s'y arrête : elle expose le type dans l'API REST et le rend utilisable dans l'éditeur de blocs. L'oublier donne un type de contenu qui s'ouvre encore avec l'ancien éditeur, ce qui déroute immédiatement le client.

Filtrer une requête sans toucher au gabarit

La demande de départ, masquer les sessions passées, se règle en une dizaine de lignes grâce à un hook sur la requête principale.

<?php
add_action( 'pre_get_posts', 'lp_masquer_sessions_passees' );
 
function lp_masquer_sessions_passees( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }
 
    if ( $query->is_post_type_archive( 'session' ) ) {
        $query->set( 'meta_key', 'date_debut' );
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'order', 'ASC' );
        $query->set( 'meta_query', array( array(
            'key'     => 'date_debut',
            'value'   => date( 'Y-m-d' ),
            'compare' => '>=',
            'type'    => 'DATE',
        ) ) );
    }
}

Les deux premières conditions ne sont pas décoratives. Sans elles, le filtre s'applique aussi dans l'administration et dans les requêtes secondaires, et le client se retrouve incapable de retrouver ses anciennes sessions pour les dupliquer.

Créer un thème enfant propre

Tant qu'un thème du commerce reste en place, toute modification passe par un thème enfant. Deux fichiers suffisent : un style.css avec l'en-tête qui déclare le parent, et un functions.php qui charge les feuilles de style dans le bon ordre.

<?php
add_action( 'wp_enqueue_scripts', 'lp_styles_enfant' );
 
function lp_styles_enfant() {
    wp_enqueue_style(
        'lp-enfant',
        get_stylesheet_uri(),
        array( 'parent-style' ),
        wp_get_theme()->get( 'Version' )
    );
}

Le numéro de version passé en quatrième argument sert de cache buster : à chaque publication, le navigateur des visiteurs récupère la nouvelle feuille au lieu de servir l'ancienne pendant deux jours.

Poser ses jetons de design dans theme.json

Avec un thème de blocs, la palette et la typographie se déclarent une fois. L'éditeur ne propose alors que les couleurs de la charte, ce qui évite les pages où le client a choisi un vert fluo dans le sélecteur libre.

{
  "version": 3,
  "settings": {
    "color": {
      "custom": false,
      "palette": [
        { "slug": "fond",    "color": "#e5e4e0", "name": "Fond" },
        { "slug": "texte",   "color": "#1a1919", "name": "Texte" },
        { "slug": "accent",  "color": "#10a37f", "name": "Accent" }
      ]
    },
    "typography": {
      "fluid": true,
      "fontSizes": [
        { "slug": "petit",  "size": "0.9rem", "name": "Petit" },
        { "slug": "normal", "size": "1.05rem", "name": "Normal" }
      ]
    }
  }
}

WordPress génère à partir de ce fichier des variables CSS réutilisables dans les gabarits et dans les styles du thème. Le réglage "custom": false ferme le sélecteur de couleur libre, et c'est probablement la ligne qui rend le plus service sur un site géré par plusieurs personnes.

Un bloc dynamique plutôt qu'un raccourci

Les shortcodes fonctionnent encore, mais ils affichent un texte entre crochets dans l'éditeur. Un bloc rendu côté serveur donne un aperçu réel et se déclare avec un fichier de configuration et une fonction de rendu.

<?php
add_action( 'init', 'lp_enregistrer_bloc_sessions' );
 
function lp_enregistrer_bloc_sessions() {
    register_block_type( __DIR__ . '/blocs/prochaines-sessions', array(
        'render_callback' => 'lp_rendu_prochaines_sessions',
    ) );
}
 
function lp_rendu_prochaines_sessions( $attributs ) {
    $sessions = new WP_Query( array(
        'post_type'      => 'session',
        'posts_per_page' => 3,
        'meta_key'       => 'date_debut',
        'orderby'        => 'meta_value',
        'order'          => 'ASC',
    ) );
 
    if ( ! $sessions->have_posts() ) {
        return '<p>Aucune session programmee pour le moment.</p>';
    }
 
    $sortie = '<ul class="lp-sessions">';
    while ( $sessions->have_posts() ) {
        $sessions->the_post();
        $sortie .= sprintf(
            '<li><a href="%s">%s</a></li>',
            esc_url( get_permalink() ),
            esc_html( get_the_title() )
        );
    }
    $sortie .= '</ul>';
    wp_reset_postdata();
 
    return $sortie;
}

Deux fonctions passent souvent inaperçues dans cet exemple et méritent d'être retenues : esc_url et esc_html échappent les valeurs avant affichage. C'est la ligne de défense de base contre l'injection de code dans une page, sujet développé dans l'article sur les risques réels d'une application non sécurisée. Et wp_reset_postdata remet la requête principale en place, sans quoi le reste de la page affiche parfois le mauvais titre.

Les pièges

Modifier les fichiers du thème parent

La modification survit jusqu'à la prochaine mise à jour du thème, puis disparaît sans avertissement. La conséquence indirecte est pire : par peur de perdre le travail, beaucoup de sites finissent avec les mises à jour désactivées, y compris les correctifs de sécurité.

Tout entasser dans functions.php

Un fichier de mille deux cents lignes contenant le type de contenu, les envois de mail, les réglages d'administration et trois correctifs oubliés. Le jour du changement de thème, tout part avec. La règle est simple à énoncer : ce qui concerne l'apparence va dans le thème, ce qui concerne le métier va dans une extension.

Requêtes non préparées

Une requête personnalisée écrite en concaténant une variable venue de l'URL ouvre une injection SQL. WordPress fournit $wpdb->prepare() pour ça, et son usage n'est pas négociable dès qu'une donnée extérieure entre dans une requête.

Le formulaire sans nonce ni vérification de droits

Une action déclenchée depuis l'administration doit vérifier deux choses avant d'agir : que la requête vient bien du bon formulaire, avec wp_verify_nonce, et que la personne a le droit de la faire, avec current_user_can. Les extensions maison oublient très souvent la seconde.

Développer en direct sur le site en ligne

Éditer un fichier via le gestionnaire de fichiers de l'hébergeur, sans historique et sans possibilité de revenir en arrière, reste répandu chez les freelances WordPress. Un dépôt Git sur le dossier des extensions et du thème coûte une demi-journée à mettre en place et évite la nuit blanche du vendredi. Le sujet est traité dans la formation Git et GitHub pour débutants, et l'écart entre l'environnement local et le serveur est décortiqué dans "Ça marche sur ma machine".

Empiler les extensions

Chaque extension installée est du code tiers exécuté sur le site, avec ses requêtes, ses scripts et sa surface d'attaque. Trente-cinq extensions actives sur un site vitrine indiquent presque toujours qu'une dizaine remplacent chacune vingt lignes de PHP.

Ce que ça change côté tarif

Le marché de l'installation de thème est saturé et tiré vers le bas, parce que n'importe qui peut apprendre à cocher des réglages en un week-end. Le marché du développement sur mesure l'est beaucoup moins : un type de contenu bien pensé, une extension métier documentée et un site qui passe une mise à jour majeure sans casser se facturent sur un autre barème, et surtout se renouvellent en maintenance.

La transition demande du PHP réel. Pas seulement la syntaxe, mais les tableaux associatifs, les fonctions de rappel, l'échappement, et à terme les classes et l'autoloading. Les formations PHP moderne puis PHP orienté objet couvrent ce chemin, et la formation WordPress Développeur : thèmes sur mesure, PHP et architecture applique le tout à l'écosystème WordPress, des hooks jusqu'à l'architecture d'un projet livrable. Le reste du parcours backend prend la suite pour ceux qui veulent élargir au-delà du CMS.

Pour une personne en reconversion qui hésite encore sur sa direction, WordPress a un avantage rare : il donne des clients tôt, avec des projets réels, pendant qu'on apprend le PHP en dessous. L'article sur le choix entre front, back et fullstack aide à situer cette voie par rapport aux autres, et une extension maison publiée sur un dépôt public fait un projet de CV nettement plus convaincant qu'un énième site vitrine.

Un dernier repère pour se tester : prends le dernier site que tu as livré et compte combien de ses fonctionnalités tu saurais reconstruire sans le thème acheté. Le chiffre obtenu dit assez précisément où tu en es.

Questions fréquentes

Faut-il savoir coder en PHP pour devenir développeur WordPress ?

Oui, et il n'y a pas de contournement durable. Les blocs et l'éditeur de site couvrent l'apparence, mais dès qu'il faut un type de contenu, une requête personnalisée, un formulaire sécurisé ou une intégration avec un service externe, le code s'écrit en PHP. Une base de JavaScript devient utile ensuite pour les blocs personnalisés.

Thème de blocs ou thème classique en 2026 ?

Pour un nouveau projet, le thème de blocs avec theme.json est la direction prise par le cœur de WordPress, et l'éditeur de site s'est stabilisé au fil des versions. Les thèmes classiques restent parfaitement fonctionnels et représentent une part énorme du parc existant, donc savoir lire et maintenir un thème en PHP reste une compétence rémunératrice pour plusieurs années.

Faut-il utiliser ACF ou coder ses champs personnalisés ?

Advanced Custom Fields fait gagner un temps réel sur les interfaces d'administration, à condition de savoir ce qu'il fait en dessous : il écrit dans les métadonnées de publication, exactement comme le ferait du code écrit à la main. Apprendre d'abord la version manuelle rend l'outil beaucoup plus lisible, et permet de s'en passer quand un client refuse une dépendance supplémentaire.

Comment monter un environnement de développement local ?

Les outils clés en main comme Local ou LocalWP suffisent pour démarrer en quelques minutes. Docker offre ensuite un environnement plus proche du serveur de production et se transporte d'une machine à l'autre. Dans les deux cas, le point important est de ne plus toucher directement au site en ligne.

Elementor et les constructeurs de pages sont-ils à éviter ?

Ils rendent service quand le client édite lui-même ses pages et que le budget ne couvre pas du sur-mesure. Le coût apparaît sur le poids des pages et sur l'enfermement : un site construit entièrement avec un constructeur se migre difficilement, puisque la mise en page vit dans le format propriétaire de l'extension. Le choix se pose projet par projet, pas une fois pour toutes.

Combien de temps pour passer d'intégrateur à développeur WordPress ?

Avec une pratique régulière et des projets réels sur lesquels appliquer les notions, quelques mois suffisent pour livrer un thème enfant sérieux, un type de contenu et une extension maison. Le repère utile n'est pas le nombre d'heures de cours suivies mais le premier site livré sans thème du commerce.

Vous êtes expert ?

Partagez votre expertise sur notre blog

Tutoriel, retour d'expérience, analyse - publiez un article invité et gagnez en visibilité.

Écrire pour nous