Semantic Comments for WordPress


As regular readers will know, I love adding Semantic things to my blog.

The standard WordPress comments HTML isn't very semantic - so I thought I'd change that. Here's some code which you can add to your blog's theme - an an explanation of how it works.

The aim is to end up with some HTML which looks like this (edited for brevity):

HTML HTML<li itemscope itemtype="https://schema.org/Comment" itemid="#246827">
    <article>
        <time datetime="2022-04-12T10:22:32+01:00" itemprop="dateCreated">
            <a href='#comment-246827' itemprop='url'>22-04-12 10:22</a>
        </time>
        <div itemprop="https://schema.org/author" itemscope itemtype="https://schema.org/Person">
            <img itemprop="image" alt='' src='logo.jpg' height='64' width='64'/>
            <span itemprop="name">
                <a itemprop="url" href="https://twitter.com/example">Commenter's Name</a></span> says:
        </div>
        <div itemprop="text">This is the text of my comment</code></div>
    </article>
</li>

Which will be interpreted as: A schema tree showing all the properties.

This adds <time> elements as well as Schema.org microdata.

Howto

In comments.php you'll see something like this:

PHP PHP<ol class="comment-list">
    <?php
        wp_list_comments( array(
            'style'       => 'ol',
            'short_ping'  => true,
            'avatar_size' => 64,
        ) );
    ?>
</ol>

You need to add a new callback. In this case, I've called it my_comments_walker:

PHP PHP<ol class="comment-list">
    <?php
        wp_list_comments( array(
            'style'       => 'ol',
            'short_ping'  => true,
            'avatar_size' => 64,
            'callback' => 'my_comments_walker',
        ) );
    ?>
</ol>

You can read more about WordPress Walkers on their documentation page.

Now that's done, you need to create a function in your functions.php file. I added this to the end of my file:

PHP PHPfunction my_comments_walker() {

    //  Basic comment data
    $comment_id          = get_comment_id();
    $comment             = get_comment( $comment_id );

    //  Date the comment was submitted
    $comment_date        = get_comment_date( "c" );
    //  In slightly more human-readable format
    $comment_date_human  = get_comment_date( "y-m-d H:i" );

    //  Author Details
    $comment_author      = get_comment_author();

    //  Author's URl if they've added one
    $comment_author_url  = get_comment_author_url();

    //  If there's an Author URl, link it
    if ($comment_author_url != null) {
        $comment_author_name = "<a itemprop='url' href='{$comment_author_url}' rel='external nofollow ugc' class='url'>{$comment_author}</a>";
    } else {
        $comment_author_name = "{$comment_author}";
    }

    //  Provide a link to the comment anchor
    $comment_url_link = "<a href='#comment-{$comment_id}' itemprop='url'>{$comment_date_human}</a>";

    //  Author's Avatar based on ID
    //  As per https://developer.wordpress.org/reference/functions/get_avatar/ both alt & default must be set
    $gravatar            = get_avatar( $comment, 64, "", "", array('extra_attr' => 'itemprop="image"') );

    //  Comment needs newlines and links added
    $comment_text        = apply_filters( 'comment_text', get_comment_text(), $comment);


    //  The comment may have various classes. They are stored as an array
    $comment_classes     = get_comment_class();
    $comment_classes_text = "";
    foreach( $comment_classes as $class ) {
        $comment_classes_text .= $class . " ";
    }
    $comment_classes_text = trim($comment_classes_text);

    //  Link to open the reply box
    $comment_reply_link = get_comment_reply_link( [
                    'depth'     => 20,
                    'max_depth' => 100,
                    'before'    => '<div class="reply">',
                    'after'     => '</div>'
            ] );

    //  Write the comment HTML. No need for a closing </li> as WP handles that.
    echo <<<EOT
    <li id="comment-$comment_id" itemscope itemtype="https://schema.org/Comment" itemid="#comment-$comment_id" class="$comment_classes_text">
        <article class="comment-body" id="div-comment-$comment_id">
            <time datetime="$comment_date" class="comment-meta commentmetadata" itemprop="dateCreated">
                $comment_url_link
            </time>
            <div class="comment-author vcard" itemprop="https://schema.org/author" itemscope itemtype="https://schema.org/Person">
                $gravatar
                <span class="fn" itemprop="name">$comment_author_name</span> <span class="says">says:</span>
            </div>
            <div itemprop="text" class="comment-text">$comment_text</div>
            $comment_reply_link
        </article>
    EOT;
}

There are a few extra classes and spans which I use. You can remove them if you like.

And that's it. All your comments will have individual semantic metadata. If you think anything else should be included, please let me know.


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

2 thoughts on “Semantic Comments for WordPress”

  1. says:

    Neat. So this is my first ever semantically marked-up blog post comment?

    Could these changes be packaged as a WordPress plugin? Or even submitted as a change to the WordPress core (or whatever it's called)?

    Also, you could include an option for the commenter to enter their ORCID iD.

    Reply
    1. @edent says:

      It is! I can't be bothered doing WordPress plugins any more - too much hassle. Similarly, getting changes in can be tricky. Your ORCiD will show up if you add it as your website in the comment.

      Reply

What links here from around this blog?

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">