idea
[ikiwiki] / doc / todo / blogpost_plugin.mdwn
1 This is a plugin that prompts the user for a title for a post, and then 
2 redirects the user to post in a hierarchically organized directory
3 structure. It supports limiting blog posts only to certain users, and 
4 this applies to creating new as well as editing old ones. It's a little
5 clumsy so far:
6
7 * Although Joey said specifically not to, I export the printheader
8   function so that the plugin can create a form.
9 * The form doesn't invoke the formbuilder hooks; I couldn't figure
10   out a way to do that easily from inside the plugin (unless I
11   exported run_hooks and that didn't seem right).
12 * This invokes a new hook, authcgi, although Joey said that
13   "the best approach was adding a flag that makes a cgi hook get 
14   postponed and called after a session is set up". I don't know
15   if this is a good idea; authenticated CGI plugins need sessions,
16   and unauthenticated CGI plugins don't, so it seems like a new hook
17   is a better idea.
18 * This creates a lot of broken parents unless you use something 
19   like [[missingparents.pm]].
20
21 I don't expect that this will be applied; it's more like a first draft.
22 I would like to hear good ideas on how to solve the first two problems.
23 Maybe make the hook return a form, which is printed by CGI.pm? --Ethan
24
25 <pre>
26 Index: IkiWiki/CGI.pm
27 ===================================================================
28 --- IkiWiki/CGI.pm      (revision 3968)
29 +++ IkiWiki/CGI.pm      (working copy)
30 @@ -684,6 +684,9 @@
31                 }
32         }
33         
34 +       run_hooks(authcgi => sub { shift->($q, $session); });
35 +       my $do=$q->param('do'); # in case the hook changed it
36 +
37         if (defined $session->param("name") &&
38             userinfo_get($session->param("name"), "banned")) {
39                 print $q->header(-status => "403 Forbidden");
40 Index: IkiWiki/Plugin/blogpost.pm
41 ===================================================================
42 --- IkiWiki/Plugin/blogpost.pm  (revision 0)
43 +++ IkiWiki/Plugin/blogpost.pm  (revision 0)
44 @@ -0,0 +1,97 @@
45 +#!/usr/bin/perl
46 +# blogpost plugin: interprets cgi "blogpost" commands as create commands.
47 +package IkiWiki::Plugin::blogpost;
48 +
49 +use warnings;
50 +use strict;
51 +use POSIX;
52 +use IkiWiki 2.00;
53 +
54 +sub import {
55 +       hook(type => "checkconfig", id => "blogpost", call => \&checkconfig);
56 +       hook(type => "authcgi", id => "blogpost", call => \&authcgi);
57 +       hook(type => "canedit", id => "blogpost", call => \&canedit);
58 +}
59 +
60 +sub checkconfig () {
61 +       if (! defined $config{blogformat}){
62 +               $config{blogformat} = 'posts/%Y/%m/%d/$title';
63 +       }
64 +
65 +       if (! defined $config{blogpagespec}){
66 +               my $spec = $config{blogformat};
67 +               $spec =~ s/%./\*/g;
68 +               $spec =~ s/\$title/*/;
69 +               $config{blogpagespec} = "$spec and ! $spec/*";
70 +       }
71 +       
72 +       if (! defined $config{blogusers}) {
73 +               $config{blogusers} = (); # disallow all posting by default
74 +       }
75 +}
76 +
77 +sub authcgi ($$) {
78 +       my $cgi=shift;
79 +       my $session=shift;
80 +
81 +       return unless (defined $cgi->param('do') && $cgi->param('do') eq "blogpost");
82 +       my $user=$session->param("name");
83 +       error ("not allowed to blog, $user") unless
84 +           $config{blogusers} eq "*" ||
85 +               grep {$_ eq $user} $config{blogusers};
86 +       eval q{use CGI::FormBuilder};
87 +       error($@) if $@;
88 +       my @fields=qw(title);
89 +       my $form = CGI::FormBuilder->new(
90 +               fields => \@fields,
91 +               title => "post title",
92 +               name => "post title",
93 +               header => 1,
94 +               charset => "utf-8",
95 +               method => 'POST',
96 +               required => 'NONE',
97 +               javascript => 0,
98 +               params => $cgi,
99 +               action => $config{cgiurl},
100 +               header => 0,
101 +               template => {type => 'div'},
102 +               stylesheet => $config{url}."/style.css",
103 +       );
104 +       my $buttons=["Blog!"];
105 +       $form->field(name => "do", type => "hidden", value => "blogpost",
106 +               force => 1);
107 +       if (! $form->submitted){
108 +               printheader($session);
109 +               print misctemplate($form->title, $form->render(submit => $buttons));
110 +               exit;
111 +       }
112 +       else {
113 +               my $page = blogpage($form->field("title"));
114 +               $cgi->param("do", "create");
115 +               $cgi->param("page", $page);
116 +       }
117 +
118 +}
119 +
120 +sub blogpage ($) {
121 +       my $title=shift;
122 +       my $page=POSIX::strftime $config{blogformat}, localtime;
123 +       $page =~ s/\$title/$title/;
124 +       return $page;
125 +}
126 +
127 +sub canedit ($$$) {
128 +       my $page=shift;
129 +       my $cgi=shift;
130 +       my $session=shift;
131 +
132 +       return undef unless pagespec_match($page, $config{blogpagespec});
133 +       my $user=$session->param("name");
134 +       IkiWiki::needsignin($cgi, $session) unless defined $user;
135 +
136 +       return "" if ($config{blogusers} eq "*" ||
137 +                     grep {$_ eq $user} $config{blogusers});
138 +       return ("not allowed to blog, $user");
139 +}
140 +
141 +1
142 Index: IkiWiki.pm
143 ===================================================================
144 --- IkiWiki.pm  (revision 3968)
145 +++ IkiWiki.pm  (working copy)
146 @@ -17,6 +17,7 @@
147  our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
148                   bestlink htmllink readfile writefile pagetype srcfile pagename
149                   displaytime will_render gettext urlto targetpage
150 +                 misctemplate printheader
151                   %config %links %renderedfiles %pagesources %destsources);
152  our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
153  our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE
154 </pre>
155
156 [[!tag patch patch/core]]