Objet
Le template comments est chargé:
- d’afficher le nombre de commentaires par type,
- d’afficher les méta-données du commentaire (origine, date)
- d’afficher le commentaire selon son niveau de profondeur,
- de créer le lien vers la réponse à un commentaire,
- de ne pas afficher les commentaires en attente de modération,
- d’afficher le bloc de saisie d’un commentaire.

Les commentaires sont affichés dans l’ordre hiérarchique des réponses. Le niveau de profondeur maximum est modifiable dans le réglage des options de discussion du tableau de bord, paramètres:  Enable threaded (nested)  et comments levels deep.

Structure du template
S’il y a des commentaires
- compter les commentaires par type: commentaire ou pings
- afficher le nombre de commentaires
- s’il y a des pings, afficher le nombre de pings
- boucle d’affichage des commentaires: fonctions wp_list_comments et mytheme_comment
- s’il y a trop de commentaires par page, afficher la navigation par page
Sinon
- si les commentaires ne sont pas ouverts, afficher un message
Fin Si
Si les commentaires sont ouverts
- afficher le bloc de saisie d’un commentaire
- contrôler la présence des informations obligatoires, nom et email (1)
Fin Si

Remarque (1). Le traitement en cas d’erreur est assez brut. Un simple message sur une page blanche. Je m’en contente pour l’instant.

Avec l’éditeur de texte ouvrir un nouveau fichier comments.php. Insérer dans ce fichier les lignes suivantes:

<?php
// Do not delete these lines
if (!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
    die ( __('Veuillez ne pas passer directement par cette page. Merci!', 'montheme') );

/* Récupère le réglage de l'option de discussion du tableau de bord:
L’auteur d’un commentaire doit renseigner son nom et son e-mail
1 : Yes (default)
0 : No
Data type: Integer */
$requireoption = get_option('require_name_email');
?>

<div id="comments">
    <?php
    /* S'il y a des commentaires les afficher! */
    if ( have_comments() ) :
        // Compter le nombre de commentaires et pings
        $ping_count = $comment_count = 0;  // init compteur de pings et de commentaires
        foreach ( $comments as $comment ) get_comment_type() == "comment" ? ++$comment_count : ++$ping_count;
        ?>

        <!-- affiche le nombre de commentaires -->
        <h3>
            <?php if ( $comment_count != 0 || $ping_count != 0) : ?>
                <?php printf($comment_count == 0 ? __('Aucun Commentaire', 'montheme') :
                    ($comment_count == 1 ? __('1 Commentaire', 'montheme') :
                    __('%d Commentaires', 'montheme')), $comment_count) ?>
            <?php endif; ?>
            <?php if ( $ping_count != 0 ) : ?>
                &middot;
                <?php printf($ping_count == 1 ? __('1 R&eacute;trolien', 'montheme') :
                    __('%d R&eacute;troliens', 'montheme'), $ping_count) ?>
            <?php endif; ?>
        </h3>
        <div style="clear:both"></div>

        <!-- Une liste classée des commentaires, voir custom_comments() dans functions.php -->
        <ol class="commentlist"> <!-- type=comment filtre les commentaires -->
            <?php wp_list_comments('type=all&callback=custom_comments'); ?>
        </ol>

        <?php
        /* S'il y a trop de commentaires placer les liens de navigation  */
        $total_pages = get_comment_pages_count();
        if ( $total_pages > 1 ) : ?>
            <div class="navigation" style="clear:both">
                <div class="alignleft"><?php previous_comments_link(__('&laquo; Commentaires plus anciens', 'montheme')) ?></div>
                <div class="alignright"><?php next_comments_link(__('commentaires plus r&eacute;cents &raquo;', 'montheme')) ?></div>
            </div>
        <?php endif; ?>
        <div style="clear:both"></div>

    <?php else : // pas de commentaires ?>
        <?php if ( $post->comment_status == 'open') : ?>
            <!-- commentaires ouverts -->
        <?php else : // comments are closed ?>
            <!-- commentaires fermés-->
            <p class="nocomments"><?php _e('Commentaires ferm&eacute;s.', 'montheme'); ?></p>
        <?php endif; /* if ( open ) */ ?>

    <?php endif; // have_comments() ?>

    <?php
    /* Si les commentaires sont ouvert, afficher le bloc de saisie d'un commentaire */
    if ( $post->comment_status == 'open' ) : ?>
        <div id="respond">
            <b><?php comment_form_title( __('Publier un commentaire', 'montheme'), __('Publier un commentaire &agrave; %s', 'montheme') ); ?>
            </b>&nbsp&nbsp&nbsp<?php cancel_comment_reply_link( __('(Annuler)', 'montheme')); ?>

            <?php if ( get_option('comment_registration') && !$user_ID ) : ?>
                <p><?php _e('Vous devez &ecirc;tre', 'montheme'); ?> <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>"><?php _e('connect&eacute;', 'montheme'); ?></a> <?php _e('pour publier un commentaire.', 'montheme'); ?></p>
            <?php else : ?>
                <form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
                    <?php if ( $user_ID ) : ?>
                        <p><?php _e('Connect&eacute; comme', 'montheme'); ?>
                          <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>
                        | <a href="<?php echo wp_logout_url(get_permalink()); ?>" title="<?php _e('Logout', 'montheme'); ?>"><?php _e('D&eacute;connexion &raquo;', 'montheme'); ?></a>
                        </p>
                    <?php else : ?>
                        <p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
                           <label for="author"><small><?php _e('Nom', 'montheme'); ?> <?php if ($requireoption) _e('(requis)', 'montheme'); ?></small></label>
                        </p>
                        <p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
                           <label for="email"><small><?php _e('Mail (non publi&eacute;)', 'montheme'); ?> <?php if ($requireoption) _e('(requis)', 'montheme'); ?></small></label>
                        </p>
                        <p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
                           <label for="url"><small><?php _e('Site web', 'montheme'); ?></small></label>
                        </p>
                    <?php endif /* if ( $user_ID ) */ ?>
                    <!--<p><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></small></p>-->

                    <p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
                    <p><input name="submit" type="submit" id="submit" tabindex="5" value="<?php _e('Valider', 'montheme'); ?>" />
                    <?php comment_id_fields(); ?> <!--Génère 2 champs cachés: comment_post_ID et comment_parent -->
                    </p>
                    <?php do_action('comment_form', $post->ID); ?>
                </form><!-- #commentform -->
            <?php endif; // If registration required and not logged in ?>
        </div><!-- #respond -->
    <?php endif; // if ( 'open' == $post->comment_status ) ?>
</div><!-- #comments -->

Structure de la fonction mytheme_comment
La fonction mytheme_comment est une itération de la fonction d’affichage des commentaires wp_list_comments . Elle affiche les éléments suivants:
- les méta-données: auteur, date, type
- le lien modifier,
- le message non approuvé pour le commentaire en attente de modération,
- le lien répondre s’il s’agit bien d’un commentaire.

Avec l’éditeur de texte ouvrir le fichier functions.php. Insérer dans ce fichier les lignes suivantes:

<?php
// Une itération de la boucle de traitement des commentaires wp_list_comments
// Affiche le commentaire, ping, trackback, ses méta-données, la possibilté de modifier et d'y répondre
// $comment = commentaire affiché
// $args contient les arguments par défaut de la fonction wp_list_comments
// $depth = niveau de profondeur du commentaire affiché = 1 à n
// Voir tableau de bord, options de discussion Enable threaded (nested) comments
function mytheme_comment($comment, $args, $depth) {
$GLOBALS['comment'] = $comment;
$GLOBALS['comment_depth'] = $depth;
?>
<li id="comment-<?php comment_ID() ?>" <?php comment_class() ?>>
    <div>
        <span class="comment-author">
            <cite class="fn"><?php comment_author_link() ?></cite> &middot;
        </span>
        <span class="comment-meta">
            <!--La fonction __() (2 underscore) traduit une chaîne de caractères en utilisant le gettext PHP.
            Le 1er paramètre est le string à traduire,
            le second, appelé le domain, dit à WordPress où se trouve la traduction.
            Il est ainsi possible de fournir un fichier.po qui contient la traduction du thème-->
            <?php printf(__('<a href="%3$s" title="Lien vers ce commentaire">%1$s &agrave; %2$s </a>', 'montheme'),
                           get_comment_date('l j F Y'),
                           get_comment_time('H:m:s'),
                           '#comment-' . get_comment_ID() ); ?> &nbsp;&nbsp;
            <?php edit_comment_link(__('(Modifier)', 'montheme'), ''); ?>
        </span>
    </div>
    <div>
        <?php if ($comment->comment_approved == '0') : ?>
            <span class='comment-unapproved'>
                <?php _e("En attente de mod&eacute;ration.", 'montheme'); ?>
            </span>
        <?php else : comment_text(); // le commentaire est affiché s'il est approuvé?>
        <?php endif ?>    <!-- fin comment_approved -->
    </div>
    <div class="reply">
        <?php if(get_comment_type() == 'comment') : //réponse possible au commentaire?>
            <?php // lien pour la réponse
            comment_reply_link(array_merge($args, array(
                'reply_text' => __('R&eacute;pondre','montheme'),
                'login_text' => __('Connexion pour r&eacute;pondre.','montheme'),
                'depth' => $depth,
                'before' => '<div>',
                'after' => '</div>'
            )));?>
        <?php else : ?>
            <?php comment_type(); ?>
        <?php endif ?><!-- comment_type() == 'comment' -->
    </div><!--end class="reply-->
</li><!--end li id="comment-"-->
<?php } // end mytheme_comment
?>

Style
Insérer dans le fichier style.css les lignes suivantes:

/* COMMENTAIRES */

#comments {
margin: 3em 0 0 0; /* séparation du post et des commentaires */
padding: 0 0 0 0;
font-size:1.2em;
font-family: Arial;
font-weight:normal;
}

#comments h3 {
font-size:1.0em;
font-weight:bold;
}

#comments div.navigation {
font-size:0.9em;
}

#comments p,  #comments ol{
margin:1em 0 0 0;
padding:0 0 0 0;
}

#comments ol{
margin:1em 0 0 1.5em; /* marges de chaque tête de commentaires */
padding:0 0 0 0;
}

/*Je définis une taille de caractère dans mes ul en em (0.76em par exemple).
Mais comme j'ai des "ul d'ul", je me retrouve avec une taille qui diminue
jusqu'à devenir illisible dès le second niveau (0.76x0.76=0.5776). Solution mettre 1em */
#comments li ul, #comments ul li {
margin: 0 0 0 1.0em; /* marge d'indentation */
padding:0 0 0 0;
list-style:none;
font-size:1em; /* très important pour garder la même taille: taille des caractères X 1 */
}

.comment-author {
font-size:1.2em;
font-style:normal;
}

.comment-author cite {
font-style:normal;
font-weight:bold;
}

.comment-meta, .reply {
margin:0;
padding:0;
font-size:0.9em;
}

.reply {
margin: 1em 0 1em 0; /* séparation du post et des commentaires */
}

.comment-unapproved {
color:#e55c0c; /*orange*/
font-style:normal;
}

textarea#comment {
width:95%; /* largeur de l'espace pour la saisie du commentaire */
}

/* balise HTML des acronymes, sigles et abréviations */

acronym, abbr, span.caps {
border: 0;
cursor: help; /* curseur = point d'interrogation */
text-decoration: underline;
}

Enregistrer les fichier sous /themes/montheme.
Presser CTRL+SHIFT+R (sous Firefox) pour vider le cache du navigateur et rafraichir l’écran.
Entrer quelques commentaires et réponses. Mettre quelques commentaires en attente. Vérifier l’affichage des commentaires et  du bloc commentaire soit en cliquant sur le nombre de commentaires de l’article dans la page index, soit en cliquant sur le titre de l’article dans la page index pour en afficher le contenu.

Télécharger les fichiers de cette partie et les copier sous /themes/montheme .

Liens
Partie 1 – Choix des outils
Partie 2 – Environnement de développement et de qualification
Partie 3 – Installation de WordPress sur serveur local
Partie 4 – Créer son thème WordPress
Partie 5 – Créer son thème WordPress – Template Index
Partie 6 – Créer son thème WordPress – Template Sidebar
Partie 7 – Créer son thème WordPress – Template Footer
Partie 8 – Créer son thème WordPress – Template Archive
Partie 9 – Créer son thème WordPress – Template Search
Partie 10 – Créer son thème WordPress – Template Single
Partie 11 – Créer son thème WordPress – Template Comments
Partie 12 – Créer son thème WordPress – Style Print
Partie 13 – Créer son thème WordPress – Autres Templates
Partie 14 – Créer son thème WordPress – Traduction