late night thoughts on fixing aggregation locking
[ikiwiki] / doc / todo / supporting_comments_via_disussion_pages.mdwn
1 I would love to see more traditional support for comments in ikiwiki.   One
2 way would be to structure data on the discussion page in such a way that a
3 "comment" plugin could parse it and yet the discussion page would still be
4 a valid and usable wiki page.
5
6 For example if the discussion page looked like this:
7
8     # Subject of First Comment
9     Posted by [Adam Shand](http://adam.shand.net/) at 10:34PM on 14/04/2007
10
11     Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi consectetuer nunc quis 
12     magna.  Etiam non est eget sapien vulputate varius. Vivamus magna. Sed justo. Donec 
13     pellentesque ultrices urna.
14
15     # Subject of the Second Comment
16     Posted by [Foo Bar](http://foobar.net/) at 11:41PM on 14/04/2007
17
18     Quisque lacinia, lorem eget ornare facilisis, enim eros iaculis felis, id volutpat nibh
19     mauris ut felis. Vestibulum risus nibh, adipiscing volutpat, volutpat et, lacinia ut, 
20     pede. Maecenas dolor. Vivamus feugiat volutpat ligula.
21
22 Each header marks the start of a new comment and the line immediately
23 following is the comments meta data (author, email/url, datestamp).
24 Hopefully you could structure it in such a way that the scope 
25
26 This would allow:
27
28  * A comment plugin to render the comments in "traditional blog" format .  
29  * Possibly even support nesting comments by the header level?
30  * A comment plugin to create a form at the bottom of the page for people to add comments in the appropriate format to the discussion page
31  * Still remain usable and readable by people who work via svn.
32  * When there is ACL support you could mark the discussion page as read only so it could only be updated by the comment plugin (if that's what you wanted)
33
34 Is this simple enough to be sensible?
35
36 -- [[AdamShand]]
37
38 > Well, if it's going to look like a blog, why not store the data the same
39 > way ikiwiki stores blogs, with a separate page per comment? As already
40 > suggested in [[discussion_page_as_blog]] though there are some things to
41 > be worked out also discussed there.
42 > --[[Joey]]
43
44 >> I certainly won't be fussy about how it gets implemented, I was just trying to think of the lightest weight most "wiki" solution.  :-) -- Adam.
45
46 >>> As a side note, the feature described above (having a form not to add a page but to expand it in a formated way) would be useful for other things when the content is short (timetracking, sub-todo list items, etc..) --[[hb]]
47
48 I've been looking into this.  I'd like to implement a "blogcomments"
49 plugin.  Looking at the code, I think the way to go is to have a
50 formbuilder_setup hook that uses a different template instead of the
51 standard editpage one.  That template would not display the editcontent
52 field.  The problem that I'm running into is that I need to append the new
53 content to the old one.
54
55 -- [[MarceloMagallon]]
56
57 > Anything I can do to help? --[[Joey]]
58
59 >> Figured it out.  Can you comment on the code below?  Thanks. -- [[MarceloMagallon]]
60
61 So, I have some code, included below.  For some reason that I don't quite get it's not updating the wiki page after a submit.  Maybe it's something silly on my side...
62
63 What I ended up doing is write something like this to the page:
64
65     [[blogcomment from="""Username""" timestamp="""12345""" subject="""Some text""" text="""the text of the comment"""]]
66
67 Each comment is processed to something like this:
68
69     <div>
70         <dl>
71             <dt>From</dt><dd>Username</dd>
72             <dt>Date</dt><dd>Date (needs fixing)</dd>
73             <dt>Subject</dt><dd>Subject text</dd>
74         </dl>
75
76         <p>Text of the comment...</p>
77     </div>
78
79 .  In this way the comments can be styled using CSS.
80
81 -- [[MarceloMagallon]]
82
83 # Code
84
85     #!/usr/bin/perl
86     package IkiWiki::Plugin::comments;
87
88     use warnings;
89     use strict;
90     use IkiWiki '1.02';
91
92     sub import { #{{{
93         hook(type => "formbuilder_setup", id => "comments",
94             call => \&formbuilder_setup);
95         hook(type => "preprocess", id => "blogcomment",
96             call => \&preprocess);  
97     } # }}}
98
99     sub formbuilder_setup (@) { #{{{
100         my %params=@_;
101         my $cgi = $params{cgi};
102         my $form = $params{form};   
103         my $session = $params{session};
104
105         my ($page)=$form->field('page');
106         $page=IkiWiki::titlepage(IkiWiki::possibly_foolish_untaint($page));
107
108         # XXX: This needs something to make it blog specific
109         unless ($page =~ m{/discussion$} &&
110                 $cgi->param('do') eq 'edit' &&
111                 ! exists $form->{title})
112         {
113             return;
114         }
115
116         if (! $form->submitted)
117         {
118             $form->template(IkiWiki::template_file("makeblogcomment.tmpl"));
119             $form->field(name => "blogcomment", type => "textarea", rows => 20,
120                 cols => 80);
121             return;
122         }
123
124         my $content="";
125         if (exists $pagesources{$page}) {
126             $content=readfile(srcfile($pagesources{$page}));
127             $content.="\n\n";
128         }
129         my $name=defined $session->param('name') ?
130             $session->param('name') : gettext('Anonymous');
131         my $timestamp=time;
132         my $subject=defined $cgi->param('comments') ?
133             $cgi->param('comments') : '';
134         my $comment=$cgi->param('blogcomment');
135
136         $content.=qq{[[blogcomment from="""$name""" timestamp="""$timestamp""" subject="""$subject""" text="""$comment"""]]\n\n};
137         $content=~s/\n/\r\n/g;
138         $form->field(name => "editcontent", value => $content, force => 1);
139     } # }}}
140
141     sub preprocess (@) { #{{{
142         my %params=@_;
143
144         my ($text, $date, $from, $subject, $r);
145
146         $text=IkiWiki::preprocess($params{page}, $params{destpage},
147                 IkiWiki::filter($params{page}, $params{text}));
148         $from=exists $params{from} ? $params{from} : gettext("Anonymous");
149         $date=localtime($params{timestamp}) if exists $params{timestamp};
150         $subject=$params{subject} if exists $params{subject};
151
152         $r = qq{<div class="blogcomment"><dl>\n};
153         $r .= '<dt>' . gettext("From") . "</dt><dd>$from</dd>\n" if defined $from;
154         $r .= '<dt>' . gettext("Date") . "</dt><dd>$date</dd>\n" if defined $date;
155         $r .= '<dt>' . gettext("Subject") . "</dt><dd>$subject</dd>\n"
156             if defined $subject;
157         $r .= "</dl>\n" . $text . "</div>\n";
158
159         return $r;
160     } # }}}
161     
162     1;