I am trying to add an additional RSS feed, using a different template, to my blog. Most documentation on WordPress.org seems to be aimed at replacing an existing feed, or alter its contents.
The additional feed is meant to fulfill Peter’s request to have a comments feed that shows only real comments, not all the likes, reposts etc I also receive through WebMentions. It is a very logical request, but I also want to keep the original comments RSS feed that includes all interaction with content on this site. So I need to add a new RSS feed.
WordPress.org doesn’t really contain any complete step-by-step explanations for anything, including for adding customised RSS feeds. It also doesn’t have any info on excluding pingbacks from comment feeds, which would be similar to what I’m trying to do. I tried stuff based on snippets of documentation I did find, but couldn’t put those snippets together into a coherent path to a solution.
Then I found a guide at WPBeginner dot com (WP beginner, that’s me, even though I’ve been a WP user and tinkerer since 2004) It’s from 2016 so maybe not concurrent with today’s version of WP. Following their explanation, I added the following to my child theme’s functions.php:
add_action('init', 'extracommentsRSS');
function extracommentsRSS(){
add_feed('commentsdupe', 'extracommentsrssFunc');
}
function extracommentsrssFunc() {
get_template_part('rss2', 'commentsdupe');
}
The first part adds the new feed to WP, the second function tells it where to look for the template for the feed. That template, named rss2-commentsdupe.php
, is located within the child-theme folder.
The URL for the feed now works, however it first prompted a download of an empty file due to the template file having a wrong name. With that name corrected (based on Jan’s comments below), it does load the template correctly.
The template itself still has issues (meaning it doesn’t work as intended at all): the while has_comments() loop provides no results, as it does not get passed any variables. Because the get_template_part is not provided with those variables before getting called. Jan suggested adding the query to the template. Did that, but now struggle to find a way to lift the comments from the query result.
The query below gets the latest 20 approved reactions on my site of the type ‘comment’ (as opposed to e.g. pingback or webmention):
$query = new WP_Comment_Query( array( 'status' => 'approve', 'type' => 'comment', 'number' => 20, 'orderby' => 'commentdate_date' ) );
The result if I print it as arrays, contains 7 elements (the query, the query arguments, default query arguments (?), an empty one, an array with the 20 requested WP comment objects, and two more empty ones).
The query works as intended, but now I do not know how a) to access the 5th element, and b) handle the WP comment objects within it. What seems to be intended functions for it (have_comments(), the_comment()) don’t seem to work.
The below code at least does not work. If I test it like this, it never enters the while loop, so never echoes ‘BOE’
while ( $query->have_comments() ) :
echo 'BOE';
$query->the_comment();
$comment_post = get_post( $comment->comment_post_ID );
$GLOBALS['post'] = $comment_post;
?> etc.
After some more suggestions by Jan Boddez, ao that have_comments()
doesn’t work for wp_comment_query
, I then established that get_comments
to query the comments, and then a foreach
to loop through them works the way I need it to.
$query = get_comments( array( 'status' => 'approve', 'type' => 'comment', 'number' => 20, 'orderby' => 'commentdate_date' ) );
foreach ($query as $comment):
$comment_post = get_post( $comment->comment_post_ID );
$GLOBALS['post'] = $comment_post;
Once I had that the original feed template could be fully re-used, and now validates:
@ton Deze comment is alvast ook op je nieuwe feed van toepassing: https://developer.wordpress.org/reference/functions/add_feed/#comment-2086 (je moet m.a.w. met die `header` browsers even vertellen welk type bestand ze mogen verwachten). Ook zou ik even proberen om i.p.v. meteen die template aan te roepen, even gewoon ‘Hello world!’ te echoën (of ‘aye!’, zoals in het voorbeeld). Als dat werkt, scheelt er dus toch nog wat met je template. (Uit het artikel op WPBeginner maak ik trouwens op dat die `rss2-commentsdupe.php` zou moeten heten.)
add_feed() | Function | WordPress Developer Resources
@ton Terzijde: dit (https://developer.wordpress.org/reference/functions/get_template_part/#comment-357) voorbeeld toont iets beter hoe `get_template_part()` werkt. (Laat je toe om een PHP-bestand in te sluiten, maar valt, wanneer het bestand met de exacte ‘suffix’ niet bestaat, terug op een algemenere variant. Handig voor ‘templating purposes’.)
get_template_part() | Function | WordPress Developer Resources
@ton I see. Misschien werkt wat voor WP_Query werkt dan toch niet zomaar voor WP_Comment_Query … Dan moet je ‘t misschien maar gewoon zo doen: https://developer.wordpress.org/reference/classes/wp_comment_query/#basic-usage
WP_Comment_Query | Class | WordPress Developer Resources
@ton Dus met `foreach` elk array-element aflopen. Kun je denk ik wel niet zonder meer de functies uit de standaard-template overnemen, of toch niet allemaal, maar je kunt natuurlijk wel steeds (cf. `$comment->comment_content`) de publieke comment-properties aanroepen. (De meeste template-functies werken trouwens waarschijnlijk wél als je er steeds het comment ID aan meegeeft. Zou je even moeten nagaan.)
@ton Voor de volledigheid: WP_Comment_Query doet inderdaad niet aan `have_comments()` en verschilt op dat vlak dus van post queries. Wel kent het een methode `query` die, zoals in het voorbeeld, een array retourneert. Je kunt, zo blijkt, ook gewoon `get_comments()` gebruiken, die maakt dan een query-object voor je, en retourneert dezelfde array.
@ton M’n eerdere uitleg klopte dus niet helemaal, waarvoor excuses. Ik had gehoopt functies als `comment_text()` gewoon te kunnen gebruiken. Daar ga je nu dus overal `comment_text( $comment->comment_ID )` van moeten maken. Of je moet aan het begin van elke iteratie de globale comment var instellen: `$GLOBALS[‘comment’] = $comment`. Da’s misschien nog het gemakkelijkst.
@jan get_comments() met een foreach levert de gewenste resultaten. dank je wel voor het meedenken en je suggesties!
@ton Ha, super! (Eerlijk gezegd, Mastodon is misschien niet het ideale medium om zoiets te bespreken. Ik bedoel, geef me een lege testsite en ik heb het waarschijnlijk binnen ‘t half uur in orde gebracht. Al wil ik je natuurlijk zelf ook wat plezier gunnen.)