Étude de cas · Projet client

IQTAG

Un site WordPress qu’une startup blockchain administre entièrement seule — thème sur mesure, sans page-builder, sans dette de plugins.

Rôle : architecture du thème, développement, déploiement, documentation2025 — 2026Durée : 1 à 2 semainesWordPress · PHP 8.3 · ACF · Vanilla JSiqcom.xyz
La page d’accueil d’IQTAG : navigation du thème, promesse « Protect Your Brand », bouton « Get QR code » et un téléphone affichant un QR code vérifié.
01/ Le contexte

Un design figé, une équipe non technique, aucune place pour la dette de plugins

IQTAG protège les marques contre la contrefaçon avec des QR codes vérifiés par blockchain, et récompense par un programme de fidélité les acheteurs qui les scannent. Il fallait un site corporate qui reproduise exactement leur design Figma, que leur propre équipe puisse modifier tous les jours sans développeur, et qui puisse accueillir de nouvelles sections plus tard sans accumuler la dette de plugins qui rend un WordPress immaintenable. Le thème est écrit depuis une page blanche : pas de thème parent, pas de page-builder.

02/ Le problème

Ce qu’un thème du commerce ne sait pas faire

  1. 01

    Le design était un fichier Figma terminé, pas une planche d’inspiration. Un thème du commerce en reproduit l’essentiel et bute sur le reste : les écarts se rattrapent en surcharges CSS, et les surcharges cassent à la mise à jour suivante du thème.

  2. 02

    Chaque élément de chaque page (les étapes du process, les avantages, l’équipe, les pages légales) devait être modifiable dans l’administration par quelqu’un qui n’écrit pas de code et n’ouvrira jamais un client FTP.

  3. 03

    Le budget outillage s’arrêtait à ACF Free, qui n’a pas de champ répétable. Or les listes éditables du site sont de longueur variable par nature : le nombre d’étapes et d’avantages relève du contenu et change avec lui, alors qu’une maquette le fige.

03/ La solution

Un thème sur mesure construit comme un monolithe modulaire

Chaque capacité est un fichier unique dans `inc/`, branché par un seul `require_once` dans `functions.php` : déclaration des champs, types de contenu, traitement AJAX, chargement des assets. Les listes de longueur variable passent par un motif de champs numérotés (des champs ACF déclarés en code, relus par des fonctions d’aide qui écartent les valeurs vides et rendent un tableau propre), si bien que les gabarits ignorent comment le contenu est stocké et que l’éditeur ne rencontre jamais de mur payant. Les formulaires de contact et d’abonnement partent en AJAX, protégés par un nonce et intégralement nettoyés, et sont écrits à deux endroits à la fois : un type de contenu visible dans l’administration, et un e-mail à l’administrateur.

Pas d’étape de build, pas de jQuery, pas de thème parent. Les assets sont de simples fichiers `.css` et `.js`, versionnés par `filemtime()`. N’importe quel développeur WordPress ouvre le projet et devient productif en une heure.

04/ Décisions clés

Quatre fois contre l’évidence

Pourquoi un thème sur mesure plutôt qu’Elementor ou Divi ?

Un page-builder stocke la mise en page sous forme de balisage sérialisé dans la base. Il rend la première version plus rapide à atteindre et toutes les suivantes plus lentes : le design est approximatif, la sortie est lourde, et le site devient impossible à migrer sans l’extension qui l’a produit. Un thème à champs structurés garde le contenu dans la base et le design dans le dépôt : chacun à sa place.

Pourquoi des champs numérotés plutôt que le champ répétable d’ACF Pro ?

Le répétable est un confort de stockage : il ne rend rien possible qui ne le soit déjà. Des champs numérotés avec leurs fonctions d’aide donnent à l’éditeur exactement la même expérience (j’ajoute un élément, je laisse le reste vide) tout en gardant la structure des champs sous contrôle de version, en code, et sans coût par site. Les gabarits consomment un tableau dans les deux cas : le jour où le répétable devient disponible, la migration se fait dans `acf-helpers.php` et nulle part ailleurs.

Pourquoi enregistrer les formulaires en base et pas seulement les envoyer par e-mail ?

L’e-mail est un canal de notification, pas un registre. La délivrabilité échoue, les boîtes se classent toutes seules, et une startup qui perd un lead perd un client. Écrire chaque message et chaque abonné dans `castom_message` et `castom_subscriber` donne un registre consultable dans l’administration déjà utilisée au quotidien, l’e-mail devenant le double et non l’unique exemplaire.

Pourquoi aucune étape de build et pas de jQuery ?

La surface interactive tient en un tiroir mobile, un filtre d’équipe, deux formulaires AJAX et des apparitions au défilement. Tout cela est de l’API navigateur native : Fetch, IntersectionObserver, scroll-snap CSS. Un bundler ajouterait une chaîne d’outils que le client devrait maintenir en vie pour changer une ligne de CSS, et jQuery ajouterait une dépendance pour faire ce que la plateforme fait déjà.

05/ Visuels

Le site et son administration

La section « How It Works » : trois étapes numérotées — générer, vérifier, récompenser — puis le visuel des deux QR codes sur l’emballage.
1440 px · chaque étape est un champ éditable
Le tiroir de navigation ouvert sur mobile : les cinq entrées du menu, le bouton de connexion et le sélecteur de langue.
390 px
L’archive du blog : article en une avec image, date et catégories, et une colonne latérale listant les catégories et les derniers billets.
1440 px · publié après la livraison
06/ Sous le capot

Modules, contenu, sécurité

functions.php ne contient que des points d’entrée. Tout le reste vit dans inc/ : setup.php (supports du thème, menus), enqueue.php (assets et wp_localize_script), acf.php (tous les appels acf_add_local_field_group() et la page d’options), acf-helpers.php (la lecture des champs numérotés), ajax-contact.php, submissions.php, team.php. Les gabarits de page utilisent l’en-tête standard Template Name, si bien que le client les assigne depuis l’administration sans développeur. Les définitions de champs sont répliquées en JSON dans acf-json/, ce qui met la structure du contenu sous contrôle de version et supprime la configuration manuelle par environnement.

Trois types de contenu sur mesure : team_member (photo, rôle, LinkedIn, e-mail, département), castom_subscriber et castom_message — les deux derniers gardent l’orthographe du projet d’origine. Une taxonomie team_department pilote le filtrage côté client sur la page équipe, sans rechargement. Les CSS et JS spécifiques à une page (team-page.css, team-filter.js) sont chargés depuis le module concerné et conditionnés par is_page_template(), donc la page d’accueil ne les télécharge jamais. La couche d’animation est une paire motion.css / motion.js pilotée par IntersectionObserver, à la place de ce qui aurait été une dépendance GSAP ou AOS.

Toute valeur entrante passe par les fonctions de nettoyage de WordPress (sanitize_text_field, sanitize_email, sanitize_textarea_field, wp_unslash) ; toute valeur sortante est échappée (esc_html, esc_url, esc_attr). Chaque requête AJAX porte un nonce vérifié côté serveur. Chaque fichier PHP s’ouvre sur defined('ABSPATH') || exit. L’adresse de l’administrateur est lue depuis get_option('admin_email') plutôt que codée en dur, donc elle survit à un changement de propriétaire. La migration du local vers la production est documentée comme une procédure, avec réécriture des URL par wp search-replace en WP-CLI.

07/ Résultats et livrables

Ce qui a été livré

0page-builder, étape de build ou jQuery dans le thème livré
5gabarits de page que le client assigne seul, depuis l’administration
3types de contenu sur mesure : équipe, abonnés, messages entrants
1–2semaines du répertoire vide à la mise en production

Depuis la mise en ligne, l’équipe d’IQTAG publie et modifie le contenu du site sans moi : les sections, l’équipe, les pages légales. Je ne suis pas repassé sur le thème pour une demande de contenu.

  • Thème sur mesure en production
  • Structure des champs ACF sous contrôle de version (acf-json)
  • Procédure de migration local → production documentée
  • Passation : chaque section modifiable sans code

Un projet du même ordre ? Décrivez-le en cinq lignes.

Réponse sous 1 heure, chiffrage sous 24 h, en journée ouvrée. Un message n’engage à rien.

ou hello@site.fr