Gossamer Forum
Home : General : Perl Programming :

sorting in 'threaded view', revisited

Quote Reply
sorting in 'threaded view', revisited
A couple months ago I posted a message with the same general topic. I eventually made it so that when a post is added to the database, it loops through and adds the record immediately after the post it was in reply to. This works okay, for the most part, but I'd really like a better method.

Jerry suggested using 'Father' and 'Child' ids and to loop through those, but I'm having a hard time fathoming how exactly to do that. Any ideas?

--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
Create an "intersection" database, junko. (Better to use MySQL in my opinion)...

You create a flat file called replies.db that would contain the following fields/columns:

Code:

TopicID
ReplyID


You could also create a separate database file for replies themselve like the following:

Code:

ReplyID
UserID
Subject
Body


And then have a topics.db file:

Code:

TopicID
UserID
Subject
Body


Then of course, have a user table:

Code:

UserID
Name
Username
Password
Email_Address


Basically, what you would then do is "loop" through the replies.db based on the TopicID and ReplyID.

Really easy to do with MySQL, both with designing the appropriate tables and also writing the scripts...

Regards,

Eliot Lee
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
Eliot, I am well aware that SQL would be better for this. I do not know SQL and this is intended for Links 2.0 (flatfile) users anyway.

I am already using multiple databases for this since of course SQL is out of the question.

Each category has it's own database which contains only header info (ie, id, subject, user id) for the original post in a thread. Each thread has its own database for replies, and each message is in a seperate file as well.

What I'am getting at is how to get a 'threaded view' of the replies database.

In Reply To:
Basically, what you would then do is "loop" through the replies.db based on the TopicID and ReplyID.
How? That's what I'm asking help with... except what I have is "ReplyID" and "ReplyTo".

--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
ugh.. after thinking about this several times.. i couldn't figure it out flatfile style.. it'd require some kind of loop.. thats all that i can say..

Jerry Su
http://www.jsu07.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
Stumpted, jerry? That's not cool. Let me start over... here is my currect code for adding messages:
Code:
open (INDEX, "forum/threads/$thread.db") or die "$!";
open (NEW, ">forum/threads/$thread.db") or die "$!";
while (<INDEX>) {
/^\s*$/ and last;
print NEW;
if (/^$post\|/) {
chomp;
my @prev = split /\|/, $_;
my $depth = pop @prev;
$depth++;
print NEW join ('|', ($id, $title, $date, $author, $depth)), "\n";
}
}
close (NEW);
close (INDEX);
When a reply is added, find the referring post and add the new post after it. use $depth so we know how many subtopics down the message is. This works out fine, except that new subtopics are added above older subtopics, and I'd like the opposite. This is the real issue here. if you know of a way to do that, please post! I should have been much more specific in my first post.

--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
And, out of curiosity, Jerry, how would you handle doing a 'threaded' view with SQL database? What would the query look like and how would you loop through the results to create the replies index?

--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
I'd get a list of all IDs of the messages in the thread... this can easily be achieved because the flat view should do this..

then foreach of these.. i'd get the IDs of their replies using an SQL query.. and i'd put them into a list.. like

@{$replies{$ID}}

(both of these steps can be easily done with the style of db that eliot mentioned..

ie:

ID|ReplyID

then.......

i'd make a loop like this..

Code:
thread_display ($IDofMAINPOST);

sub thread_display {
my $id = shift;
my %rec = get_record ($id);
print "$rec{subject} $rec{name} $rec{date}\n";
#get_reply IDs into @reply
foreach (@reply) {
thread_display ($_);
}
}
muaahhaha.. i think i did it.. thats not really SQL style.. its just code that works if you plug everything in correct.. also.. everyone wants their threads to be indented at each level. .i'm sure you can use the Lists HTML thing like<ol> <ul> or whatever to get it to work..

so it wasn't really a fancy loop.. it was just a loop where a subroutine calls itself over and over..

Jerry Su
http://www.jsu07.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
hmm.. make sure you

my @reply = adfadflajf;

otherwise it will get deleted.. or maybe you should just do..

@{$replies{$ID}} for the replies..

Jerry Su
http://www.jsu07.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
Thanks a lot! Worked like a charm... here's the code I used:
Code:
my @post_def = ('ReplyID', 'Title', 'Author', 'Email', 'Date', 'Referer');

my %thread;
open (INDEX, "test.db");
while (<INDEX>) {
chomp;
my @rec = split /\|/, $_;
my $referer = pop @rec;
push @{$thread{$referer}}, $rec[0];
}
close (INDEX);

sub get_post {
my $id = shift;
my %rec;
open (INDEX, "test.db");
while (<INDEX>) {
/^$id\|/ or next;
chomp;
my @rec = split /\|/, $_;
for (my $i = 0; $i <= $#post_def; $i++) {
$rec{$post_def[$i]} = $rec[$i];
}
$rec{'Date'} = convert($rec{'Date'});
}
close (INDEX);
return (%rec);
}

print header();
print qq|
<html>
<head><title>index view of replies</title></head>
<body bgcolor="white">
<table width="100%" border="1" cellspacing="0" cellpading="5" bordercolor="black">
<tr>
<td width="100%" align="center">Subject</td>
<td width="150"><table width="150"><tr><td width="150" align="center">Author</td></tr></table></td>
<td width="200"><table width="200"><tr><td width="200" align="center">Date</td></tr></table></td>
</tr>
|;
display('',0,1);
print " </table>\n";
print end_html();

sub display {
my ($width, $index, $id) = @_;
my %rec = get_post($id);
print qq|
<tr>
<td align="left">
$width
<a href="post.cgi?$rec{'ReplyID'}">$rec{'Title'}</a>
</td>
<td align="center">
<a href="mailto:$rec{'Email'}">$rec{'Author'}</a>
</td>
<td align="center">
$rec{'Date'}
</td>
</tr>
|;
$index++;
foreach my $reply (@{$thread{$id}}) {
my $width = "&nbsp;" x ($index * 3);
display($width, $index, $reply);
}
}
--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
yay! i can't believe i couldn't figure this one out at first..

anyways.. here is the html method i was talking about..

Code:
print qq|<ul type="square">\n|;
display (1);
print "</ul>\n";

sub display {
my $id = shift;
my %rec = get_post ($id);
print qq|<li><a href="post.cgi?$rec{'ReplyID'}">$rec{'Title'}</a>
Posted by <a href="mailto:$rec{'Email'}">$rec{'Author'}</a>
at $rec{'Date'}\n|;
if (@{$thread{$id}} > 0) {
print qq|<ul type="square">\n|;
display ($_) foreach (@{$thread{$id}});
print "</ul>\n";
}
}
that would do all the indenting without the use of the $width and $index variables..

Jerry Su
http://www.jsu07.com
Quote Reply
Re: sorting in 'threaded view', revisited In reply to
I used <UL> at first, but there are a couple of issues with that.
1) All those <UL>'s take up a lot of space.
2) I wanted to use tables to seperate the subject, author, and date into columns, so the use of definition lists was out of the question.

I've now changed it so that it just stretches a transparent gif 20 pixels times $index.

--Drew
Free, hot camel soup for Links hackers...
http://www.camelsoup.com