How to add Discussion forum Structured Data markup
Discussion forum (DiscussionForumPosting) Structured Data markup on your community's ForumTopicPage "is designed for any forum-style site where people collectively share first-hand perspectives".
While for other Structured Data markup it was relatively easy to add a simple JSON linked data given the thread structure with multiple replies creating that would be a bit more complex (basically a query against the messages collection) but what's worse is that it would add much duplication to the page content. That's why I decided to go for the microdata inline markup to enhance the existing topic page with semantic information. Unfortunately, this means that this solution won't be a 100% drag'n'drop deployment for every community as you might need to adapt it a bit to your page structure and class names. The good news is that as long as you are using a skin and theme derived from the Hermes theme some of the elements like authors and title already come with some markup like itemprop="headline" for the title and similar. To complete this markup according to the spec I am running a script that matches certain thread message and author elements and add the necessary attributes.
It's probably best if you pick, add and validate each of them one by one using e.g. Google's Rich Results test. Here's the code of my custom component:
<#-- This component will add structured markup in form of microdata for ForumTopicPage following Googles Discussion forum (DiscussionForumPosting) structured data definition. See doc at https://developers.google.com/search/docs/appearance/structured-data/discussion-forum -->
<@liaAddScript>
;(function($) {
$(document).ready(function () {
// This should match the outermost container encompassing the whole thread
$('.lia-quilt-column-main-content>.lia-quilt-column-alley-left').attr('itemtype', 'https://schema.org/DiscussionForumPosting').attr('itemscope', '').prepend('<meta itemprop="mainEntityOfPage" content="https://community.acme.com'+LITHIUM.CommunityJsonObject.Page.object.viewHref+'" /><meta itemprop="url" content="https://community.acme.com'+LITHIUM.CommunityJsonObject.Page.object.viewHref+'" />');
// Hermes already comes with subject markup that only needs to get changed to 'headline' and publish date added
let PublishDate = $('meta[itemprop="dateModified"]').attr('content');
$('.lia-message-subject').attr('itemprop', 'headline').after('<meta itemprop="datePublished" content="'+PublishDate+'" />');
// This goes around all replies in a thread
$('.lia-thread-reply').attr('itemprop', 'comment').attr('itemtype', 'https://schema.org/Comment').attr('itemscope', '');
// Marking up all author containers...
$('.lia-component-message-view-widget-author-username').attr('itemprop', 'author').attr('itemtype', 'https://schema.org/Person').attr('itemscope', '');
// ...and the author name
$('.lia-component-message-view-widget-author-username>.lia-user-name-link>span').attr('itemprop', 'name');
// Marking up the kudo button container as interaction counter...
$('.KudosButton').attr('itemprop', 'interactionStatistic').attr('itemtype', 'https://schema.org/InteractionCounter').attr('itemscope', '');
// ...and the kudos count within
$('.KudosButton .MessageKudosCount').attr('itemprop', 'userInteractionCount');
// ...and finally define the interaction as like
$('.KudosButton .lia-button-image-kudos-label').attr('itemprop', 'interactionType').attr('content', 'https://schema.org/LikeAction');
// These two calls add ImageObject type markup
$('.lia-message-image-wrapper').attr('itemtype', 'https://schema.org/ImageObject').attr('itemscope', '');
$('.lia-message-image-wrapper img').attr('itemprop', 'contentUrl');
});
})(LITHIUM.jQuery);
</@liaAddScript>
Here's a live example topic that you can validate in Rich Results: Solved: Not ALL elements move when I use bold marquee - Graphisoft Community
NB: Some warnings get thrown in Google Search Console for anonymous (closed account) authors since they lack the URL and unique name.
Bonus: This markup works best if you also deploy the How to add ProfilePage Structured Data markup
Let me know if you have any follow up questions about implementing this and please share any improvements you are building on top.