Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2014-07-03 15:50:32

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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:

  1. Write a plugin that simply pulls the most recent articles and comments and combines them
  2. 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

#2 2014-07-03 15:58:53

gaekwad
Server grease monkey
From: People's Republic of Cornwall
Registered: 2005-11-19
Posts: 4,241
GitHub

Re: Combine comments and articles in a single stream

Could you use recent_comments with a custom form?

Offline

#3 2014-07-03 16:13:35

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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

#4 2014-07-03 16:18:55

gaekwad
Server grease monkey
From: People's Republic of Cornwall
Registered: 2005-11-19
Posts: 4,241
GitHub

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

#5 2014-07-03 16:19:53

etc
Developer
Registered: 2010-11-11
Posts: 5,157
Website GitHub

Re: Combine comments and articles in a single stream

Like this?

Offline

#6 2014-07-03 16:31:25

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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

#7 2014-07-03 16:50:10

etc
Developer
Registered: 2010-11-11
Posts: 5,157
Website GitHub

Re: Combine comments and articles in a single stream

jdueck wrote #281879:

I’m not sure I want to depend on something I don’t fully understand

Totally agree, but it takes 30 minutes to understand, don’t hesitate if you need help. Otherwise, you’ll have to dig into sql/php.

Offline

#8 2014-07-03 21:57:35

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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

#9 2014-07-04 09:01:53

etc
Developer
Registered: 2010-11-11
Posts: 5,157
Website GitHub

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() &lt; 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

#10 2014-07-04 20:27:43

etc
Developer
Registered: 2010-11-11
Posts: 5,157
Website GitHub

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

#11 2014-07-07 21:37:06

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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

#12 2014-08-30 21:02:53

jdueck
Plugin Author
From: Minneapolis, MN
Registered: 2004-02-27
Posts: 147
Website

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

Board footer

Powered by FluxBB