Le blog.

8 snippets pour modifier le comportement d’ACF.

Je ne sais pas si vous êtes un habitué de cette extension WordPress, mais j’adore Advanced Custom Fields. Dans mon quotidien de développeur WordPress freelance, il me fait gagner un temps fou ! Créer des metaboxes, insérer des champs simples ou complexes dedans, gérer leur affichage conditionnel… J’évite grâce à ACF beaucoup de lignes de code pour arriver à un résultat de qualité.

Mais parfois, l’interface d’ACF ne permet pas de dynamisme poussé. Heureusement, Elliot Condon — le développeur d’ACF — a bien pensé à truffer le code de son extension de hooks utiles et bien pensés. Découvrons ici-même quelques uns des filtres et actions d’ACF pour personnaliser son comportement.

Développer pour WordPress avec ACF : trucs et astuces pour personnaliser la logique du plugin Advanced Custom Fields
Développer pour WordPress avec ACF : trucs et astuces pour personnaliser la logique du plugin Advanced Custom Fields
Le plugin regroupant toutes ces astuces, ainsi que la configuration de la metabox et des champs utilisés, est téléchargeable gratuitement ici.

5 ans déjà que j’ai publié des articles et vidéos sur l’utilisation d’une librairie pour définir des groupes de champs et des champs dans WordPress via du code… beaucoup de code ! Aujourd’hui, mon développement WordPress est grandement facilité grâce à l’utilisation de l’excellente extension Advanced Custom Fields. Je l’utilise 2 fois sur 3 dans mes projets nécessitant la création de groupes de champs, champs et pages d’options.

ACF : Ah C’est Quoi ?

Rapide résumé d’ACF pour ceux qui ne le connaissent pas : ACF est un plugin permettant de créer des metaboxes et des champs dans WordPress, et ce via une interface visuelle efficace intégrée dans le back-office WordPress.

L'interface visuelle d'ACF permet de créer facilement un ensemble complexe de champs dans WordPress
L’interface visuelle d’ACF permet de créer facilement un ensemble complexe de champs dans WordPress

C’est simple, on peut faire énormément de choses grâce à lui, nous évitant plusieurs centaines de lignes de code pour arriver aux mêmes fins :

  1. on créée facilement ses groupes de champs et on définit où les afficher
  2. on ajoute des champs dans nos groupes en quelques clics et décide de les afficher selon certaines conditions
  3. on peut choisir parmi de nombreux types de champs (texte, nombre, images, relation avec des posts/taxonomies)
  4. on peut créer des structures de champs complexes comme des groupes de champs, des onglets, des accordéons
  5. on peut faire des compositions de champs grâce aux Contenus Flexibles, et des champs duplicables grâces aux Champs Repeater
  6. on peut facilement créer des pages d’options pour configurer efficacement nos sites WordPress
  7. … et bien plus encore

La liste est longue mais vous l’avez compris : ACF est une pépite d’or pour tout bon développeur WordPress ne souhaitant pas réinventer la roue.

Une extension « hookable » par filtres et actions

J’entends déjà les puristes ronchonner : « ouiiii d’accord c’est bien beau, mais utiliser une interface visuelle pour créer des champs, on va vite être limité et on ne pourra jamais aller aussi loin qu’avec des champs définis dans du code, et puis mince je suis développeur moi jamais j’utiliserai un plugin pour enregistrer mes champs metas ». Et bien détrompez-vous !

Le cœur du plugin se base sur une intelligente utilisation d’actions et de filtres, rendant ACF un champion de la personnalisation de ses propres logiques. Il n’est en aucun cas limité par les définitions que l’on peut mettre en place dans son interface visuelle.

Pour preuve, j’ai travaillé sur la refonte du site D-Clics.com sous WordPress et me suis basé exclusivement sur ACF pour les dizaines de metaboxes et formulaires front-end disponibles sur le site. Chacun de ces formulaires est largement personnalisé via le code pour, entre autre :

  1. modifier les conditions d’affichages de certains champs ACF et leurs paramètres,
  2. modifier certaines valeurs de champs avant enregistrement,
  3. créer des validations de champs/formulaires sur-mesure,
  4. exécuter d’autres actions après la soumission d’un formulaire ACF

Alors, l’ayant utilisé de fond en comble ces derniers mois, voici quelques trucs et astuces pour vous permettre de propulser votre utilisation d’ACF et le personnaliser grâce à ces filtres et actions. Faites votre choix : vidéo ou texte ?


Les 8 trucs et astuces de dév ACF en vidéo

Trucs et astuces de développement avec ACF

Enregistrer les fichiers JSON ACF dans votre plugin

ACF propose par défaut une fonctionnalité dite Local JSON fort pratique : en créant un dossier nommé acf-json à la racine de votre thème, ACF enregistrera un fichier JSON à chaque fois que vous enregistrez un de vos groupes de champs. La configuration de ce groupe et des champs qu’il contient est donc d’une part enregistrée dans ce JSON, mais également chargée à partir de celui-ci ; on évite ainsi des appels à la base de données pour qu’ACF charge ces champs et on gagne ainsi en performance.

« Oui mais heu je dév un plugin WordPress avec ACF moi »

Pas de souci ! Pour les développeurs WordPress n’ayant pas besoin d’enregistrer ces fichiers JSON de configuration ACF dans le thème, on peut heureusement indiquer à ACF l’endroit où sauvegarder nos metaboxes et champs. Si ces derniers sont si vitaux à votre plugin :

  1. créer un dossier vide à la racine du plugin WordPress que vous développez
  2. utilisez le filtre acf/settings/save_json pour indiquer à ACF où écrire les fichiers JSON à chaque enregistrement de groupe de champs
  3. utilisez le filtre acf/settings/load_json pour indiquer à ACF où lire des fichiers JSON et charger les metaboxes qui y sont enregistrées

Une fois ces fichiers de configuration synchronisés avec un nouveau dossier de votre plugin, il se remplira automatiquement de fichiers .json à chaque création ou mise à jour de vos groupes de champs.

Fort pratique si, par exemple, vous déposez la source de votre extension WordPress dans Git : un autre développeur qui récupèrera votre repo verra alors dans son interface ACF la possibilité de synchroniser de nouveaux groupes de champs issus de ces fichiers .json.

Dév WordPress et ACF : synchroniser des groupes de champs grâce aux fichiers JSON
Synchronisation disponible d’un groupe de champs grâce à un fichier JSON

Définir un champ ACF en lecture seule

On abuse ici du filtre acf/load_field qui nous offre la possibilité de modifier le paramètre d’un champ avant qu’il soit chargé par ACF. On peut ainsi modifier ses propriétés comme son label, le fait qu’il soit requis ou non, sa valeur par défaut, son ID ou classe CSS, la largeur du champ, etc.

En définissant la propriété $field[‘disabled’] sur true, on indique à ACF que l’on ne souhaite pas rendre le champ éditable. Il sera visible, mais disabled et donc impossible à éditer.

Cela peut être utile pour proposer une donnée à l’utilisateur mais ne pas lui donner la possibilité de modifier cette donnée. Ici, on désactive notre champ « Prix avec commission » qui sera plus tard calculé dynamiquement lors de la sauvegarde d’une annonce : l’utilisateur verra alors le prix réel de son produit sur notre site dans le champ concerné, mais ne pourra pas l’éditer.

Notez que le paramètre $field[‘readonly’] fait exactement la même chose !

Remarquez la syntaxe dynamique de nombreux filtres et actions ACF :
  1. le filtre acf/load_field cible tous les champs,
  2. le filtre acf/load_field/name=abc cible tous les champs dont le nom est abc
  3. le filtre acf/load_field/key=xyz cible tous les champs dont le nom est xyz
  4. le filtre acf/load_field/type=text cible tous les champs de type texte

Peupler dynamiquement un menu déroulant ACF

Encore une fois, on utilise le filtre acf/load_field mais dans l’optique de modifier un autre paramètre d’un champ. Comment faire pour remplir dynamiquement les options d’un champ <select> créé par ACF ?

En modifiant la clé $field[‘choices’], on va pouvoir fournir à ACF un tableau associatif permettant de remplir le menu déroulant des valeurs que nous souhaitons. Dans ce tableau, les clés seront les values des <options> et ce sont elles qui seront associées au post meta et enregistrées dans la base SQL. Les valeurs du tableau sont quant à elles présentées dans le menu déroulant pour être sélectionnées par l’utilisateur.

Grâce à une telle logique, on va pouvoir proposer des données variables dans le menu déroulant, comme par exemple pour :

  1. choisir une valeur selon l’utilisateur connecté,
  2. choisir une valeur selon un réglage global au site,
  3. approvisionner le menu déroulant de données issues d’un site tiers fournies via une API

Pratique, n’est-ce pas ?

Modifier des variables dans un champ ACF de type Message

Décidément, on ne lâche plus le filtre acf/load_field ! Ici, on a inséré des « mots marqueurs » (variables) dans un champ de type Message, comme ci-dessus :

WordPress & ACF : mots-marqueurs variables dans un champ message

Grâce à une astucieuse utilisation de str_replace(), on va pouvoir modifier le paramètre $field[‘message’] pour que ces mots-marqueurs soient remplacés par des variables dynamiques.

Nous avons précédemment rempli dynamiquement un menu déroulant avec les 5 dernières années (2018 à 2013). Autant que le message expliquant cela, avant le menu déroulant, reflète la même logique : encore mieux, cela se fera dynamiquement et nous n’aurons pas à éditer notre champ chaque année !

Valider des champs ACF en comparant leurs valeurs entre elles

Chose que j’adore pouvoir faire avec ACF : la validation d’un champ passe par un filtre, on peut donc librement dire à ACF de considérer la valeur d’un champ comme valide, ou lui dire qu’il n’est pas valide tout en lui indiquant le message d’erreur qui s’affichera en rouge au-dessus du champ concerné.

function msk_acf_validate_value($valid, $value, $field) {
	// Déjà invalidé par une autre logique en amont ? On renvoie le message d'erreur déjà présent dans $valid
	if (!$valid) return $valid;

	// Si la valeur de notre champ est inférieur à 10, OK : on renvoie true
	if ($value < 10) {
		return true;

	// Si la valeur de notre champ est supérieur à 10, pas bon : on renvoie un message d'erreur
	} else {
		return 'Nous voulons une valeur inférieure à 10 !';
	}
}
add_filter('acf/validate_value', 'msk_acf_validate_value', 10, 3);

Tout cela se passe dans le filtre acf/validate_value. La fonction que l’on passera à ce hook pourra recevoir 3 paramètres très utiles :

  1. $valid contient l’état actuel de la validation en cours. Si le champ n’est déjà pas validé avant que notre fonction intervienne, autant (peut-être) ignorer notre propre validation.
  2. $value est la valeur indiquée dans le champ en question. C’est elle qu’on analysera pour faire nos vérifications et tester des choses plus précises dans notre code, comme par exemple :
    1. si une adresse e-mail n’existe pas déjà dans notre base d’utilisateurs
    2. si un mot de passe fait au moins 8 caractères
    3. si un numéro de téléphone est au bon format
  3. et $field, moins utilisé, contient les paramètres du champ en question, comme dans le filtre acf/load_field

Ce filtre attend la valeur true pour considérer le champ comme valide, et une chaîne de caractères s’il n’est pas valide : cette chaîne de caractères sera utilisée par ACF comme message d’erreur et affichée dans une tooltip rouge au-dessus du champ.

Accéder aux valeurs d’autres champs lors de la validation d’un champ spécifique

Dans notre cas, on cherche à s’assurer qu’au moins un de nos deux champs Marque ou Modèle n’est pas vide (donc qu’au moins un des deux est rempli). On va donc utiliser une même fonction hookée sur la validation de ces deux champs, grâce aux 2 filtres dynamiques acf/validate_value/name=annonce_marque et acf/validate_value/name=annonce_modèle.

La fonction dispose bien de la valeur du champ en cours d’analyse à travers la variable $value. Mais il est aussi possible d’accéder à toutes les valeurs des autres champs du formulaire envoyé, stockées dans la variable globale $_POST.

Les valeurs des champs du formulaire sont disponibles dans $_POST[‘acf’]
Vous trouverez donc dans la variable $_POST[‘acf’] un tableau associatif avec les valeurs des autres champs du formulaire, chaque clé du tableau correspondant à la clé du champ qu’ACF a assigné au champ.

Récupérer la valeur d’un autre champ ACF en spécifiant son nom (name)

Si vous êtes comme moi et que vous n’aimez pas vraiment travailler avec les clés illisibles qu’ACF assigne à chacun de ces champs, utilisez la fonction get_acf_post_value($name) que vous trouverez dans le snippet ci-dessus. Cette fonction permet d’aller trouver dans les données $_POST[‘acf’] la valeur d’un champ dont on aura fourni son nom, et non sa clé.

Dans notre cas, on peut ainsi facilement récupérer par exemple la marque du produit entrée par l’utilisateur grâce à get_acf_post_value(‘annonce_marque’). Je trouve ça beaucoup plus naturel et logique ; on évite de devoir trouver l’identifiant ACF du champ et on garde une certaine lisibilité dans notre code.

Nettoyer les valeurs champs WYSIWYG d’ACF avant leur enregistrement SQL

Une fois tous les champs considérés valides par ACF vient l’enregistrement des valeurs de ces champs dans la base de données. Et encore une fois, ACF nous donne la possibilité d’intercepter ses valeurs juste avant leur enregistrement pour éventuellement les modifier grâce au filtre acf/update_value.

Comme mentionné dans la documentation, ce filtre dispose de 3 paramètres que nous pouvons utiliser dans notre fonction :

  1. $value contient la valeur d’origine du champ, que l’on souhaitera peut-être modifier
  2. $post_id donne accès à l’ID du post en cours d’édition
  3. et $field nous donne les détails du champ en cours d’enregistrement

Ces informations vont nous aider à décider de la modification, ou non, de la valeur entrée par l’utilisateur afin par exemple de la nettoyer et la rendre saine et sécurisée avant son enregistrement dans la base de données.

Enregistrer d’autres données lorsque ACF enregistre le post

Besoin d’exécuter des actions lorsque ACF enregistre les données du post ? Le hook acf/save_post est fait pour ça ! Elle nous met à disposition l’ID du post ($post_id) qui vient d’être enregistré.

Attention à la priorité de l’action que vous définirez : en dessous de 10, ACF n’aura pas encore fait son travail d’enregistrement des valeurs. Vous avez donc encore les anciennes valeurs meta associées au post dans la base de données, les nouvelles étant accessibles dans la variable globale $_POST.

Avec une priorité supérieure à 10, le post est fraîchement enregistré et ses metas sont à jour. Utilisez donc la bonne priorité selon votre usage : en dessous de 10 si vous avez besoin d’accéder aux anciennes valeurs des champs metas du post avant qu’elles soient écrasées par les nouvelles, et au dessus de 10 pour bénéficier des données les plus à jour.

C’est l’un des hooks le plus tardif dans ACF : l’utilisateur a envoyé le formulaire d’édition du post, les champs sont validés et les données sont enregistrées. C’est donc une action très utile pour exécuter d’autres logiques une fois un post enregistré, comme par exemple :

  1. envoyer un e-mail à l’administrateur pour l’informer de la publication d’une nouvelle annonce
  2. supprimer et recréer des données transients, comme par exemple des statistiques globales sur les petites annonces publiées
  3. ajouter l’e-mail du vendeur dans une mailing list
  4. ou comme dans notre cas, enregistrer de nouvelles données dans le post édité pour mettre à jour le titre du produit ou le prix commission comprise

Notez que l’action acf/save_post s’exécute à chaque fois qu’un post bénéficiant de champs ACF est enregistré. Il est donc important de vérifier le type de contenu du post en cours d’édition (avec get_post_type($post_id)), pour vous assurer d’exécuter votre logique seulement quand c’est nécessaire. Gare aux mauvaises surprises !

Ne pas enregistrer la valeur d’un champ ACF

Pour terminer cet article, petite astuce pratique pour forcer ACF à n’enregistrer aucune meta pour un champ spécifique. On utilise encore une fois le filtre acf/update_value mais en ne « retournant rien » (avec return null), on indique à ACF de ne rien enregistrer dans la base de données. Bien pratique si vous avez un champ mot de passe à n’utiliser que pour la création d’un compte utilisateur dans WordPress : une fois l’utilisateur créé, ne stockez surtout pas le mot de passe en clair dans une post meta !


Et vous, avez-vous des astuces de développeur WordPress / ACF à nous partager en commentaires :) ?

Soyez le premier à publier un commentaire.

Laisser un commentaire