Customiser le template de commentaires de WordPress

WordPress est souvent utilisé comme base pour des solutions sur mesure. La création de thème est dans l’ensemble bien documentée. Cependant, lorsque l’on développe un thème de A à Z, il n’est pas toujours évident de personnaliser les commentaires. Voyons comment arriver à nos fins.

Évidemment, tout ce que nous allons voir est 100% standard pour WordPress. Cependant, les exemples de code proviennent du site e-commerce d’Alphapole réalisé avec le blank theme 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>"
        ]);
        ?>

        
        <ul>
            <?php wp_list_comments('callback=steroids_comment'); ?>
        </ul>

    
    <?php else : ?>
    	<p><?php _e('Comments are closed here.', 'steroids'); ?></p>
    <?php endif; ?>
</section>

La plupart des options sont précisées dans la documentation. En revanche, la documentation ne mentionne pas comment spécifier le HTML du bouton.

Pourtant, ces fonctions ont été ajoutées il y a maintenant plusieurs années.

  • submit_button permet de préciser le code du bouton,
  • submit_field permet de définir à la fois le code de la balise qui entoure le bouton et le bouton lui-même.

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 donc 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/template-functions.php 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 enfant lorsque vous activez cette fonctionalité pour les commentaires répondant à d’autres commentaires.

Liste sur mesure via get_comments

Alternativement, la fonction get_comments retourne un tableau aves 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 :

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

Vous noterez que j’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 fonctionalité, WordPress utilise le JavaScript et place le forumalaire 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 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. Donc vous pouvez l’inclure même si vous vous êtes débarrasé de jQuery. Pour se faire, plusieurs solutions, 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 ?

C’est aussi simple que ça… Si vous utilisez la version WordPress originale. Cependant, sans entrer dans les détails, 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é. 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.

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() [en]. S’il y a une erreur, la balise body a est taggée comme ceci id="error-page". Cela permet un contrôle assez facile.

Voici les données à envoyer :

comment	mon petit commentaire de test
author	buzut
email	super@mail.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 dans le cas d’Alphapole, 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 !

Il n'y a pas encore de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *