Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
Combine comments and articles in a single stream
At my site I have comments enabled, but I run them as “addendum submissions” to be considered for publication (rather than as a discussion board).
Consequently the comments that do get published are both few in number and often worthy little blog posts of their own. (Also, most of them (not all) are by me.)
So what I’d like to be able to do is to combine my blog posts and my comments as a single stream, sorted by date.
I can think of a couple of ways to achieve this kind of comment/article parity of importance:
- Write a plugin that simply pulls the most recent articles and comments and combines them
- Write a plugin that, when a comment is approved, automatically duplicates it as an article too
Is #1 feasible? Has anyone done it before, or is it possible with existing general-purpose plugins? I did try digging around of course but I haven’t turned up anything so far. Ideally I would be able to use separate forms for articles vs. blog posts. Theoretically this would also allow me to create a combined articles/comments RSS feed.
That second one could get into really interesting hairy recursion issues since each comment would then be able to have its own comments. I don’t think I’m really up for that kind of complexity.
Offline
Re: Combine comments and articles in a single stream
Could you use recent_comments with a custom form?
Offline
Re: Combine comments and articles in a single stream
gaekwad wrote #281875:
Could you use recent_comments with a custom form?
I don’t think that’ll do it, because it won’t interleave articles and comments in chronological order.
What I’m looking for is something roughly like
- Article One (Jul 2, 2014)
- Comment on "Article from March 2014" by Sam (Jul 1, 2014)
- Article Two (June 27, 2014)
- Article Three (June 26, 2014)
- Comment on "Article From Last Year" by Rachel (June 25, 2014)
- Article Four (June 23, 2014)
Notice how they’re all mixed together based on order of date. I don’t think recent_comments
would be able to do that, the best it would get me is something like this
- Comment on "Article from March 2014" by Sam (Jul 1, 2014)
- Comment on "Article From Last Year" by Rachel (June 25, 2014)
- Article One (Jul 2, 2014)
- Article Two (June 27, 2014)
- Article Three (June 26, 2014)
- Article Four (June 23, 2014)
Offline
Re: Combine comments and articles in a single stream
Ah, hmm – you’re right. Perhaps there’s scope to output the epoch time of each item and then sort according to that.
Perhaps look at etc_query to see if that can help you.
Offline
Offline
Re: Combine comments and articles in a single stream
etc wrote #281878:
Like this?
Well paint me green and call me Gumby. That is some nutso awesome stuff. I’m not terribly familiar with XSL so I’m not sure I want to depend on something I don’t fully understand, but that does look I might be able to hack it around to do exactly what I want…if I could come up with a more rigid structure for my own article/comment forms that would make it possible to select out the dates this way.
Offline
Offline
Re: Combine comments and articles in a single stream
I’m just not sure how I’d structure my page to work with this. I definitely don’t want to put entire blog posts into a definition list. Right now the posts are all contained in sibling article
elements.
Another thing that might be dicey is pagination; it might not be feasible to use this approach on any but the first page, because on page 2 most, or maybe all the “recent comments” will be newer than any of the articles to be shown.
Offline
Re: Combine comments and articles in a single stream
jdueck wrote #281883:
I’m just not sure how I’d structure my page to work with this. I definitely don’t want to put entire blog posts into a definition list. Right now the posts are all contained in sibling
article
elements.
That’s not a problem, any container with some timestamp markup will do. For example, if your article form is
<article data-timestamp='<txp:posted format="%s" />'>
... article stuff ...
</article>
and the comments form is
<div data-timestamp='<txp:comment_time format="%s" />'>
... comment stuff ...
</div>
then you can merge them like this:
<txp:etc_query
data='<body>
<txp:article_custom form="your_article_form" />
<txp:recent_comments form="your_comments_form" break="" />
</body>'
>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:template match="body">
<h4>Recent contributions</h4>
<xsl:for-each select="*">
<xsl:sort select="@data-timestamp" order="descending" />
<xsl:if test="position() < 11">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
</txp:etc_query>
Another thing that might be dicey is pagination; it might not be feasible to use this approach on any but the first page, because on page 2 most, or maybe all the “recent comments” will be newer than any of the articles to be shown.
Wait, the deal was to create a separate “recent contributions” list. :) If you need to totally assimilate comments to articles, with pagination and all, your public-side submission way #2 seems more appropriate, but risky, see this thread.
Offline
Re: Combine comments and articles in a single stream
jdueck wrote #281883:
Another thing that might be dicey is pagination; it might not be feasible to use this approach on any but the first page, because on page 2 most, or maybe all the “recent comments” will be newer than any of the articles to be shown.
Since you seem to use etc_pagination
, that’s actually not too hard:
<!-- extract articles and comments ids -->
<txp:etc_query globals="_GET"
data="SELECT GROUP_CONCAT(ID SEPARATOR ',') artids, GROUP_CONCAT(discussid SEPARATOR ',') dscids, COUNT(discussid) dscount FROM
(SELECT NULL ID, discussid, d.posted Posted FROM `txp_discuss` d JOIN `textpattern` txp ON d.parentid = txp.ID WHERE d.visible > 0 AND txp.Status = 4
UNION ALL
SELECT ID, NULL discussid, Posted FROM `textpattern` WHERE Status = 4
ORDER BY Posted DESC LIMIT {?page|0|intval.-1.*10},10) tmp"
>
<txp:variable name="artids" value="{artids?}" />
<txp:variable name="dscids" value="{dscids?}" />
<txp:variable name="dscount" value="{dscount?}" />
</txp:etc_query>
<!-- mix -->
<txp:etc_query
data='<body>
<txp:if_variable name="artids" value=""><txp:else />
<txp:article_custom id=''<txp:variable name="artids" />'' form="article_form_with_timestamps" />
</txp:if_variable>
<txp:if_variable name="dscids" value=""><txp:else />
<txp:recent_comments break="" sort=''FIELD(discussid, <txp:variable name="dscids" />) DESC'' limit=''<txp:variable name="dscount" />'' form="comments_form_with_timestamps" />
</txp:if_variable>
</body>'>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:template match="body">
<h4>Recent submissions</h4>
<xsl:for-each select="*">
<xsl:sort select="@data-timestamp" order="descending" />
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
</txp:etc_query>
<!-- pagination -->
<txp:etc_query name="numpages"
data="SELECT CEIL(SUM(c)/10) numpages FROM
(SELECT COUNT(*) c FROM `txp_discuss` JOIN `textpattern` txp ON parentid = txp.ID WHERE visible > 0 AND txp.Status = 4
UNION ALL
SELECT COUNT(*) c FROM `textpattern` WHERE Status = 4) tmp" />
<txp:etc_pagination pgcounter="page" pages='<txp:variable name="numpages" />' />
Edit: code simplified (edit: and corrected).
Last edited by etc (2014-08-31 10:38:54)
Offline
Re: Combine comments and articles in a single stream
This is awesome, thank you. Going to roll up my sleeves and adapt this as soon as I can. Will report back with results!
Offline
Re: Combine comments and articles in a single stream
Finally had a chance to work on this. I had to install and enable XSL on my server. Now I’m very close, except for a hangup with recent_comments
. If I use:
<txp:recent_comments break="" sort=''FIELD(discussid, <txp:variable name="dscids" />) DESC'' limit=''<txp:variable name="dscount" />'' form="comments_form_with_timestamps" />
…I get empty output. But if I manually enter the values like this:
<txp:recent_comments break="" sort=''FIELD(discussid, 313,311,310,309) DESC'' limit=''4'' form="comments_form_with_timestamps" />
I get the expected output. It’s as if recent_comments
objects to the use of txp:variable
within its attribute values.
Offline