Formation « Développer un thème WordPress sur mesure »

Utiliser le hook « save post » pour ajouter un temps de lecture à un article

Lecture : 5 minutes • 5

Les hooks sont les alliés des développeurs lorsqu’il s’agit de créer des thèmes et extensions. Grâce au hook save_post, il est possible de lancer une action juste après l’enregistrement d’un article, ce qui va nous permettre de calculer le temps de lecture d’un article.

Nous avons abordé les hooks un peu plus tôt dans cette formation. Ils nous ont été utiles dans le functions.php pour configurer notre thème. Pour rappel voici leur définition :

Hooks

Définition

Les Hooks sont des fonctions déclarées par le développeur de thème ou d’extension qui permettent d’interagir avec le coeur de WordPress, d’autres thèmes ou extensions et lancés à des moments clés de leur exécution. Par exemple, on peut intercepter le moment où WordPress enregistre un article dans la base, afin d’y apporter des modifications. Il existe 2 types de Hooks : les actions, un moment clé pour lancer ses propres fonctions, et les filtres, pour intercepter une valeur à un moment donné et la modifier.

Traduction : Crochets

Et il y en a un qui s’avère particulièrement utile et qui va nous permettre de calculer le temps de lecture d’un article, ainsi que générer un sommaire. C’est le hook save_post.

La capture montre le site Capitaine WP affichant un temps de lecture et un sommaire.
Le sommaire et le temps de lecture ont été générés par le hook save_post

Celui-ci va se lancer juste après l’enregistrement d’une publication (article, page, CPT…) et renvoyer les données enregistrées.

Utiliser le hook Save Post

Voici la base du hook save_post, à placer dans le functions.php de votre thème :

PHP
functions.php

Ce hook vous renvoie 3 paramètres : l’identifiant de l’article, ses données (titre, contenu…), et un booléen nous indiquant si on est dans le cas d’une création d’article, ou d’une mise à jour.

Comme notre fonction va être lancée à chaque fois qu’une publication est enregistrée, on va avoir besoin de mener quelques tests préalables afin d’être sûr qu’elle soit exécutée dans les bonnes conditions.

1 • Test création vs mise à jour

Justement, le hook est appelé dès lors que l’on créé un nouvel article (en cliquant sur Articles > Ajouter dans l’interface d’administration). Donc notre fonction va être exécutée une première fois à ce moment là. Mais cela ne nous intéresse pas car il n’y a pas encore de contenu à analyser.

C’est pourquoi on va tester le paramètre $update qui va nous indiquer dans quel cas on se trouve :

  • $update est égal à false si on est dans le cas d’une première création ;
  • $update est égal à true lorsqu’on enregistre un article.

Ainsi, lorsqu’on est dans le cas d’une première création, on appelle return pour sortir de la fonction et éviter ainsi son exécution.

PHP
functions.php

Par contre, dans le cas où vous voudriez assigner automatiquement une catégorie à la création d’un article, on testerait cette fois qu’update est bien à false. Voici un exemple :

PHP
functions.php

2 • Éviter les révisions

WordPress risque également d’entrer dans notre fonction lorsqu’il gère les révisions. Si c’est le cas, on arrête là aussi l’exécution de la fonction. Le test se fait grâce à wp_is_post_revision().

PHP
functions.php

3 • Éviter l’autosave

WordPress enregistre automatiquement votre contenu à intervalles réguliers, ce qui va là aussi déclencher notre fonction. Mais là encore, on n’a pas besoin de l’exécuter.

En fait on a besoin d’enregistrer le temps de lecture seulement lorsque le rédacteur clique de lui même sur Publier / Mettre à jour.

Donc afin de ne pas trop alourdir l’enregistrement automatique, on vérifie avec la constante DOING_AUTOSAVE si on est dans ce cas, auquel cas on sort de la fonction.

PHP
functions.php

Afin de ne pas générer d’erreur, on teste préalablement si cette constante est définie.

4 • Tester le type de publication

Et enfin, il faut vérifier que l’on est bien sur le type de publication souhaité, sinon notre calcul se lancerait sur les articles, pages, et tout autre Custom Post Type créé dans votre thème.

Si ce n’est pas ce que vous souhaitez, on va ajouter un dernier test afin de contrôler qu’on est bien dans le cas d’un article.

PHP
functions.php

Bien, une fois qu’on a testé tout ça, on s’est assuré qu’on est bien dans le bon cas de figure. Si je résume : le rédacteur est en train de rédiger un article et a bien cliqué lui-même sur le bouton Publier / Mettre à jour.

Calculer le temps de lecture d’un article

Maintenant, le but va être de récupérer le contenu de l’article, retirer les balises HTML, compter le nombre de mots et enfin calculer le temps de lecture.

Voici le code correspondant. Notez que j’ai écrit les tests et les return sur une seule ligne afin de gagner un peu de place, sans perdre en lisibilité pour autant.

PHP
functions.php

En premier lieu, je vais récupérer le contenu de l’article, accessible via $post->post_contentpuis j’utilise en amont la fonction strip_tags() qui permet de supprimer les balises HTML. Enfin, la fonction str_word_count() permet de compter le nombre de mots.

À partir de là on peut calculer le temps de lecture. D’après Wikipedia, une personne lit en moyenne 250 mots par minute.

On divise donc le nombre de mots obtenus par 250 et on obtient notre temps de lecture exprimé en minutes. J’utilise ceil() pour arrondir à la minute supérieure et ainsi éviter les nombres à virgule.

Il ne nous reste plus qu’à stocker cette valeur quelque part, et le plus judicieux est de l’enregistrer dans les méta-données de l’article, les fameuses post metas. Et pour cela on utilise la fonction update_post_meta(). C’est d’ailleurs sur ce même principe que sont enregistrés les champs additionnels, qu’ils soient natifs ou issus d’ACF.

Le saviez-vous ?

Il existe la fonction add_post_meta qui permet de créer une nouvelle méta-donnée, mais on utilise tout le temps update_post_meta, car cette dernière est capable de créer la donnée si elle n’existe pas encore.

Aparté: Métas et base de données

Les méta-données d’un article sont enregistrées dans la table wp_postmeta alors que les articles sont enregistrés dans wp_post. Pour plus de détails sur la structure des données de WordPress, référez-vous au cours sur le coeur de WordPress et la base de données.

Afficher le temps de lecture dans le template

Maintenant, pour afficher le temps de lecture, il suffit d’utiliser la fonction get_post_meta dans le template de notre publication, soit single.php pour un article.

PHP
single.php

Le troisième paramètre, passé à true, permet d’indiquer que la valeur est unique : il n’y a qu’un seul temps de lecture par article. C’est dû au fait que WordPress permet d’enregistrer plusieurs metas avec le même nom, et dans ce cas il retournerait un tableau.

Comme ce n’est pas utile dans notre cas, on lui indique qu’on a qu’une seule valeur, qui est retournée comme une string et non pas comme un array.


Vous savez désormais tirer parti du hook save_post, et l’utiliser dans les bonnes conditions. Dans le prochain cours on va à nouveau utiliser ce hook, mais cette fois pour générer un sommaire. Et on aura de nouveaux défis puisqu’il faudra par exemple modifier le contenu tout juste enregistré.

5

Questions, réponses et commentaires

  1. Cisco

    Le 4 février 2023

    Bonjour, c’est top ! Que faut il rajouter à cela pour prendre les contenus ACF avec des flexible layouts ?

    1. Maxime BJ

      Le 6 février 2023

      Il faudrait faire une boucle pour lire le contenu de tes champs flexibles. En définitive le code sera quasi identique à celui du cours sur le champ flexible ACF et tu utiliseras str_word_count( strip_tags( get_sub_field( ‘content’ ) pour récupérer les contenus et compter les mots.

  2. Fred - FLQ

    Le 24 janvier 2024

    Toujours aussi passionnant ! Les explications détaillées sur les différents tests sont vraiment hyper utiles et on voit tout de suite leur intérêt de manière plus globale.

    Petite question : as-tu eu à travailler sur des projets pour lesquels tu as choisi d’enregistrer des infos dans une/des tables supplémentaires que celles par défaut ? Si oui, quels critères sont selon toi déterminants pour faire ce choix ?

    Encore un grand merci pour tout ton travail ! 🙂

    1. Maxime BJ

      Le 24 janvier 2024

      En général quand tu bosses sur un projet assez gros, ça devient plus intéressant de faire des tables customs pour gérer les relations. Thomas Deneulin explique assez bien les limitations SQL de WordPress au WordCamp Biarritz si tu veux en savoir plus : https://wordpress.tv/2023/11/23/comprendre-et-optimiser-notre-base-de-donnees-wordpress/.

      J’ai notamment pu utiliser des tables customs chez WPChef lors du développement de notre LMS, car on avait des stagiaires, des formations, des sessions, des évaluations, des compétences… Autant d’entités qu’il n’aurait pas été très agréable de manipuler en tant que Custom Post Type (notamment pour toutes les données enregistrées en postmeta).

      1. Fred - FLQ

        Le 24 janvier 2024

        Merci pour ta réponse : je vais aller regarder ça avec intérêt !

Laisser un commentaire