Cheatsheet

Customiser le template de commentaires de WordPress

Laisser un commentaire

Dès lors que l’on veut personnaliser l’affichage et la soumission des commentaires, on doit manuellement en recréer la logique. Voyons comment mettre en place cela.

Tout ce que nous allons voir est 100% standard. Les exemples de code proviennent du site e-commerce de MTO réalisé avec le Steroids.

Le template des commentaires

Plutôt que d’appeler les différentes fonctions des commentaires directement dans le fichier des articles – single.php en général – ou des pages, c’est une bonne pratique d’avoir un template dédié.

Ainsi, si vous avez des commentaires à plusieurs endroits, par exemple pour les articles et sur certaines pages, vous vous évitez évidemment de vous répéter (DRY !). comments_template récupère par défaut comments.php mais il est tout à fait possible de préciser un autre nom de fichier.

Le formulaire de commentaires

Point de commentaires sans formulaire ! C’est en effet le seul moyen de soumettre ces derniers. C’est donc par là que l’on commence.

On va utiliser comments_open afin de savoir si les commentaires sont activés pour ce post et comment_form afin de générer le formulaire.

comment_form accepte des arguments qui permettent de préciser le HTML généré. Il trouve sa place dans comments.php.

<section id="comments" class="comments">
    <!-- si les commentaires sont acceptés !-->
    <?php if (comments_open()) : ?>
        <?php
        // on génère le formulaire avec du html personnalisé
        comment_form([
            'title_reply' => 'Une remarque, une question ? Laissez un commentaire.',
            'fields' => apply_filters('comment_form_default_fields', [
                'author' => '<label for="author">Votre nom <abbr class="required" title="obligatoire">*</abbr></label><br>
                            <input id="author" name="author" type="text" value="" placeholder="Nom" required>',

                'email'  => '<label for="email">Votre adresse email <abbr class="required" title="obligatoire">*</abbr></label><br>
                            <input id="email" name="email" type="email" value="" placeholder="Email" required>'
            ]),

            'comment_field' => '<label for="comment">Que souhaitez-vous dire ? <abbr class="required" title="obligatoire">*</abbr></label><br>
                                    <textarea id="comment" name="comment" placeholder="Commentaire" required></textarea>',
            'comment_notes_before' => '',
            'submit_button' => "<button>Envoyer le commentaire</button>"
        ]);
        ?>

        <!-- fonction de récupération des commentaires, nous y reviendrons !-->
        <ul>
            <?php wp_list_comments('callback=steroids_comment'); ?>
        </ul>

    <!-- On peut afficher un message si les commentaires sont fermés !-->
    <?php else : ?>
        <p><?= __('Comments are closed here.', 'steroids') ?></p>
    <?php endif; ?>
</section>

La liste des commentaires

Dans l’exemple précédent, nous avons aperçu la fonction de génération de commentaires : wp_list_comments. De nouveau, la documentation précise les différentes options acceptées par la fonction. Le plus souple est d’utiliser la fonction de callback.

Cette dernière récupère chacun des commentaires un à un et permet donc d’avoir la main sur 100% du code.

Vous avez peut-être vu que l’on passe callback=steroids_comment à la fonction wp_list_comments. C’est ici la fonction steroids_comment qui a la charge de générer le code des commentaires.

Cette fonction est déclarée dans le fichier functions.php – ou autre fichier de fonction selon le thème utilisé (/inc/templates.php est le plus indiqué dans Steroids).

function steroids_comment($comment, $args, $depth) {
    ?>
    <li>
        <article id="comment-<?php comment_ID(); ?>" class="comment">
            <header>
                <span><?= $comment->comment_author ?></span>
                <time datetime="<?php comment_time('c'); ?>">
                    le <?= get_comment_date() ?>
                </time>
            </header>
            <div class="comment-content"><?php comment_text(); ?></div>

            <a class="reply" href="#comments" data-id="<?= $comment->comment_ID ?>">Répondre</a>
        </article>
    <?php
}

Chaque commentaire est contenu dans une balise li et une balise article. Le W3C considère en effet un commentaire comme un article d’un point de vue sémantique. Et il s’agit là d’une liste de commentaires.

Vous remarquez peut-être que nous ouvrons la balise li mais que nous ne la refermons pas. Il est précisé dans la documentation que WordPress se charge de fermer la balise. Cela permet d’automatiquement imbriquer les commentaires enfants lorsque vous activez cette fonctionnalité pour les commentaires répondant à d’autres commentaires.

Liste sur mesure via get_comments

Alternativement, la fonction get_comments retourne un tableau avec tous les commentaires (du site ou de l’article selon les paramètres passés) et les informations associées. Voici un exemple d’utilisation de la fonction.

$comments_arr = get_comments('post_id=' . get_the_ID());
$comments = null;

foreach ($comments_arr as $comment) {
    $comments .= '<article>';
    $comments .= '<header>';
    $comments .= '<h1><cite class="fn">' . $comment->comment_author . '</cite> dit :</h1>';
    $comments .= '<date datetime="' . $comment->comment_date . '">' . date_i18n(get_option('date_format'), strtotime($comment->comment_date)) . '</date>';
    $comments .= '</header>';
    $comments .= '<p>' . $comment->comment_content . '</p>';
    $comments .= '</article>';
}

echo $comments;

Vous noterez qu’on utilise ici la fonction get_the_ID – laquelle permet de récupérer l’id du post courant – pour ne récupérer que les commentaires de l’article concerné.

En outre, sans en expliquer le fonctionnement date_i18n(get_option('date_format'), strtotime($e->comment_date)) permet d’obtenir une date formatée en français. date_i18n et get_option sont des fonctions propres à Wordpress tandis que strtotime est une fonction PHP native.

Répondre à un commentaire

Nous en avons parlé, il est possible de répondre directement à un commentaire. C’est pour cela que sous chaque commentaire figure un lien “Répondre”. Pour cette fonctionnalité, WordPress utilise le JavaScript et place le formulaire juste sous le commentaire auquel vous voulez répondre. Pour le marquage HTML de WordPress, le plus indiqué est d’utiliser la fonction comment_reply_link. Cette dernière génère le lien et appelle une fonction JavaScript au clic.

Si, comme moi, votre thème se la joue light et n’inclut rien par défaut, ce JavaScript n’est pas importé. Le JavaScript en question est en pur ES5. Vous pouvez donc l’inclure même si vous vous êtes débarrassé de jQuery.

Pour ce faire, plusieurs solutions sont possibles. Soit vous l’incluez directement depuis WordPress, soit vous le copiez dans votre thème et vous l’importez uniquement sur les pages qui le requièrent, soit vous l’importez dans votre bundle JavaScript.

<?php
// Version WordPress native
if (is_singular() && comments_open() && get_option('thread_comments')) {
    wp_enqueue_script('comment-reply');
}

Vous avez dit Ajax ?

Je préfère soumettre les commentaires sans recharger la page, d’autant plus que la plupart du temps, les commentaires ne sont pas affichés avant modération. C’est pour cette raison que dans l’exemple de code fourni plus haut, je génère manuellement le lien de réponse.

<a class="reply" href="#comments" data-id="<?= $comment->comment_ID ?>">Répondre</a>

Ainsi, mon code JavaScript peut facilement récupérer l’id du parent. Quant au endpoint ajax, ce n’est peut être pas très catholique, mais je me contente d’envoyer à l’url à laquelle la formulaire serait normalement envoyée. La réponse est 409 si le commentaire a déjà été envoyé, 200 sinon. 200 ne signifiant pas que tout s’est bien déroulé. Le plus simple à mon avis est de bien valider en JS les données envoyées et de partir du principe que tout va bien se passer.

Un vrai endpoint

Si vous voulez prendre le temps de faire les choses dans les règles de l’art et profiter d’encore plus de contrôle, vous pouvez créer un vrai endpoint Ajax. Vous utiliserez ensuite la fonction wp_insert_comment afin d’insérer votre commentaire.

Après tout, si l’email est valide, tout doit bien se passer. Sauf erreur réseau, auquel cas, vous n’aurez pas un code 200 en retour. Pour la validation, si vous ciblez les navigateurs décemment récents, vous pouvez facilement valider le contenu des formulaires avec form.reportValidity(). S’il y a une erreur, la balise body contient id="error-page". Cela permet un contrôle assez facile.

Voici les données à envoyer :

comment    mon petit commentaire de test
author    buzut
email    mon@email.com
comment_post_ID    164
comment_parent    45

author et email ne sont pas à renseigner si l’utilisateur est connecté puisque dans ce cas, WordPress a déjà ces infos. De plus, comment_parent n’est à renseigner que s’il s’agit d’une réponse à un commentaire.

Pour le retour visuel, je me contente d’afficher une notification puisque, de toute façon, la plupart du temps les messages ne sont affichés qu’après approbation. Dans le cas contraire, vous pourriez récupérer le dernier commentaire et l’insérer à la bonne place. En cas de succès, même pas besoin d’ajax, vous avez déjà toutes les infos, il suffit de mettre les éléments en forme !

Et voilà, vous avez un système de commentaire qui se plie maintenant totalement à vos besoins.

N’hésitez pas à oartager vos questions, remarques ou astuces en commentaires !

Commentaires

Rejoignez la discussion !

Vous pouvez utiliser Markdown pour les liens [ancre de lien](url), la mise en *italique* et en **gras**. Enfin pour le code, vous pouvez utiliser la syntaxe `inline` et la syntaxe bloc

```
ceci est un bloc
de code
```