tagging: Allow using titles in for related stories.
[matthijs/upstream/blosxom-plugins.git] / general / wikieditish
1 # Blosxom Plugin: wikieditish
2 # Author(s): Rael Dornfest <rael@oreilly.com> 
3 # Version: 2003-05-29
4 # Documentation: See the bottom of this file or type: perldoc wikieditish
5
6 package wikieditish;
7
8 # --- Configurable variables -----
9
10 # Should I attempt to preserve the last modified date/time when
11 # editing an existing file?  (May not work on your operating system.)
12 # 0 = no (default), 1 = yes
13 $preserve_lastmodified = 0;
14
15 # Should editing this blog require a password?
16 # 0 = no, 1 = yes (default)
17 $require_password = 1;
18
19 # What is the password for editing this blog?
20 my $blog_password = '';
21
22 # Should editing this blog be restricted to a particular set of IPs?
23 # 0 = no (default), 1 = yes
24 $restrict_by_ip = 0;
25
26 # To what IPs should editing this blog be restricted?
27 @ips = qw/ 127.0.0.1 /;
28
29 # What file extension should I use for edited pages? 
30 # (Not sure why you'd change this, but just in case...)
31 my $file_extension = $blosxom::file_extension;
32
33 # --------------------------------
34  
35 # Response to wikieditish; use as $wikieditish::response in 
36 # flavour templates
37 $response = '';
38
39 # The raw title and body
40 ($title, $body) = ('', '');
41
42 # The password entered into the form (for prepopulating the form upon Save)
43 $password = '';
44
45 # --------------------------------
46
47 use vars qw/$require_password/;
48
49 use CGI qw/:standard/;
50 use FileHandle;
51
52 my $fh = new FileHandle;
53
54 # Strip potentially confounding bits from user-configurable variables
55 $file_extension =~ s!^\.!!;
56
57 sub start {
58
59   # Only spring into action if POSTing to the wikieditish  plug-in
60   if ( request_method() eq 'POST' and param('plugin') eq 'wikieditish' ) {
61
62     my($path,$fn) = $blosxom::path_info =~ m!^(?:(.*)/)?(.*)\.$blosxom::flavour!;
63     $path =~ m!^/! or $path = "/$path";
64
65     $password = param('password');
66     $title = param('title');
67     $body = param('body');
68
69     # Something's fishy with the path
70     $path =~ /[^\/\w\-]/
71       and warn "blosxom : wikieditish plugin : something's fishy with the path, $path\n"
72       and $response = "Something didn't go as expected; page not saved."
73         and return 1;
74
75     # password required, but not set
76     $require_password and !$blog_password
77       and warn "blosxom : wikieditish plugin : password required but is not yet set; trying to > $blosxom::datadir$path/$fn.file_extension\n"
78       and $response = "A password is required to edit this page but one has not yet been set; page not saved."
79         and return 1;
80
81     # password required, set, but not correctly supplied
82     $require_password and (!param('password') or (param('password') and param('password') ne $blog_password))
83       and warn "blosxom : wikieditish plugin : incorrect password supplied for > $blosxom::datadir$path/$fn.file_extension\n"
84       and $response = "Incorrect password supplied; page not saved."
85         and return 1;
86
87     # restricted by ip
88     $restrict_by_ip and !grep(/^\Q$ENV{'REMOTE_ADDR'}\E$/, @ips)
89       and warn "blosxom : wikieditish plugin : incorrect IP address > $blosxom::datadir$path/$fn.file_extension\n"
90       and $response = "Incorrect IP address; page not saved."
91         and return 1;
92
93     # blosxom's $datadir is not writeable
94     !-w  $blosxom::datadir
95       and warn "blosxom : wikieditish plugin > \$blosxom::datadir, $blosxom::datadir, is not writeable.\n" 
96         and $response = "Something didn't go as expected; page not saved."
97           and return 1;
98
99     # the destination directory for this blog entry does not yet exist
100     unless ( -d "$blosxom::datadir$path" and -w "$blosxom::datadir$path" ) {
101       warn "blosxom : wikieditish plugin : mkdir $blosxom::datadir$path\n";
102       foreach ( ('', split /\//, $path) ) {
103         $p .= "/$_";
104         $p =~ s!^/!!;
105         -d "$blosxom::datadir/$p" or mkdir "$blosxom::datadir/$p", 0755
106           or ( warn "blosxom : wikieditish plugin : couldn't mkdir $blosxom::datadir/$p." and return 1 );
107       }
108     }
109
110     # If file already exists, memorize the lastmodified date/time
111     my $mtime = (stat "$blosxom::datadir$path/$fn.$file_extension")[9];
112
113     # If file is writeable
114     if ( $fh->open("> $blosxom::datadir$path/$fn.$file_extension") ) {
115       print $fh join "\n", $title, $body;
116       $fh->close();
117       $response = "Page saved successfully.";
118       
119       # reset lastmodified date/time to memorized value (if possible)
120       $preserve_lastmodified 
121         and utime(time, $mtime, "$blosxom::datadir$path/$fn.$file_extension")
122           ? $response .= "  Preserved last modified date/time."  
123           : warn "blosxom : wikieditish plugin : couldn't reset lastmodified time on $blosxom::datadir$path/$fn.$file_extension.";
124
125     } else {
126       warn "couldn't > $blosxom::datadir$path/$fn.file_extension";
127       $response = "There was a problem saving this page.";
128     }
129   }
130
131   1;
132 }
133
134 sub story {
135   my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
136    
137   unless ( param('plugin') eq 'wikieditish' ) {
138     my @body;
139     ($title, @body) = split /\n/, $blosxom::raw;
140     $body = join "\n", @body;
141   }
142
143   1;
144 }
145
146
147 1;
148
149 __END__
150
151 =head1 NAME
152
153 Blosxom Plug-in: wikieditish
154
155 =head1 SYNOPSIS
156
157 Edit a Blosxom blog wiki-style, from right in the browser.
158
159 =head2 QUICK START
160
161 Drop this wikieditish plug-in file into your plug-ins directory 
162 (whatever you set as $plugin_dir in blosxom.cgi).
163
164 Wikieditish, being a well-behaved plug-in, won't do anything until you 
165 either set a password or turn off the password requirement 
166 (set $require_password = 0).
167
168 Move the contents of the flavours folder included in this distribution 
169 into your Blosxom data directory (whatever you set as $datadir in blosxom.cgi).
170 Don't move the folder itself, only the files it contains!  If you don't
171 have the the sample flavours handy, you can download them from:
172
173 http://www.raelity.org/apps/blosxom/downloads/plugins/wikieditish.zip
174
175 Point your browser at one of your Blosxom entries, specifying the wikieditish 
176 flavour (e.g. http://localhost/cgi-bin/blosxom.cgi/path/to/a/post.wikieditish)
177
178 Edit the entry, supply your password (if required -- the default), and hit the Save button to save your changes.  
179
180 You can just as easily create a new blog entry by pointing your browser at a non-existent filename, potentially on a non-existent path (e.g. http://localhost/cgi-bin/blosxom.cgi/path/to/a/nonexistent_post.wikieditish).  Give the entry a
181 title and body, supply your password (again, if required), and hit the Save 
182 button.  The wikieditish plug-in will create a new blog entry for you on 
183 your specified path, creating the supplied path's directory structure for you
184 on the fly if necessary.
185
186 Enjoy!
187
188 =back
189
190 =head2 SAMPLE FLAVOUR TEMPLATES
191
192 I've made sample flavour templates available to you to help with any
193 learning curve this plug-in might require.
194
195 Take a gander at the source HTML for:
196
197 =item * head.wikieditish, a basic head template -- nothing special.
198
199 =item * story.wikieditish, a basic story template -- nothing special.
200
201 =item * foot.wikieditish, a basic foot template just about like any other.
202 The big difference is the "edit this blog" form for editing the current
203 blog entry or creating a fresh one.
204
205 NOTE: The wikieditish plug-in requires the presence of a "plugin" form 
206 variable with the value set to "wikieditish"; this tells the plug-in 
207 that it should handle the incoming POSTing data rather than leaving it 
208 for another plug-in.
209
210 =back
211
212 =head2 FLAVOURING WIKIEDITISH
213
214 While there's not much in the way of template variables and the sample
215 foot.wikieditish provides about everything you'll need, here's a list of
216 variables and their purposes for your reference:
217
218 =item * $wikieditish::title and $wikieditish::body prepopulate the form with the values from the existing blog entry file.
219
220 =item * $wikieditish::password is prepopulated with the password you just entered into and submitted in the "edit this blog" form or preferences stored in a 'wikieditish' cookie, if you've the cookie plug-in installed and enabled.
221
222 =back
223
224 =head2 INVITING CONTRIBUTIONS
225
226 The wikieditish plug-in serves dual purposes: as a browser-based editor for 
227 your Blosxom blog and as a wiki-style community blog, allowing contributions
228 by a particular group of bloggers (using a shared password) or passers-by 
229 (without need of a password -- true Wiki-style).
230
231 If you'd like to invite contribution, you can assocate  an "edit" button with
232 each entry like so:
233
234 <a href="$url$path/$fn.wikieditish">edit this blog</a>
235
236 HERE
237
238 =head1 INSTALLATION
239
240 Drop wikieditish into your plug-ins directory ($blosxom::plugin_dir).
241
242 =head1 CONFIGURATION
243
244 =head2 PRESERVING LAST MODIFIED DATE/TIME ON EDITED ENTRY
245
246 The wikieditish plug-in can attempt to maintain the last modified date/time 
247 stamp on any blog entry you're editing.  Otherwise, editing an entry will
248 cause it to rise to the top of your blog like so much cream.
249
250 I say "attempt" since this doesn't work on every operating system 
251 (it doesn't do any harm, though).
252
253 To turn this feature on -- it's off by default -- set the 
254 $preserve_lastmodified variable to 1.
255
256 =head2 RESTRICTING BY PASSWORD
257
258 By default, the wikieditish plug-in requires a password.  You'll need to
259 set one before being able to edit anything.  Set the $blog_password 
260 configuration variable to anything you wish 
261 (e.g.  my $blog_password = 'abc123';).  Just be
262 sure to use something you'll remember and other's won't guess.
263
264 You can disable password-protection if you wish, allowing passers-by to
265 contribute to your blog, Wiki-style.  Be sure this is something you want to
266 do.  It has some possible security implications, anyone being able to write
267 to your server's hard drive, post to your public-facing blog, and edit
268 (read: alter, spindle, contort) any blog postings.  Those warning's out of
269 the way, to turn off password-protection, set $require_password to 0.
270
271 =head2 RESTRICTING BY IP
272
273 You can alternatively decide to restrict editing to a particular IP address
274 or addresses -- those in your office, for example, or the machine actually
275 running Blosxom (127.0.0.1).  
276
277 To do so, set $restrict_by_ip to 1 (it's off, or 0, by default), and 
278 populate the @ips array with a list of approved IP addresses.  By default,
279 this is set to "this machine", the machine running Blosxom; shorthand for
280 "this machine" in IP-speak is 127.0.0.1.  The following example restricts
281 editing to those coming from three IPs, including 127.0.0.1:
282
283   # Should editing this blog be restricted to a particular set of IPs?
284   # 0 = no (default), 1 = yes
285   $restrict_by_ip = 1;
286
287   # To what IPs should editing this blog be restricted?
288   @ips = qw/ 127.0.0.1 10.0.0.3 140.101.22.10/;
289
290 Of course, you can use a combination of password-protection and IP 
291 restriction if you so wish.
292
293 =head1 VERSION
294
295 2003-05-29
296
297 Version number is the date on which this version of the plug-in was created.
298
299 =head1 AUTHOR
300
301 Rael Dornfest  <rael@oreilly.com>, http://www.raelity.org/
302
303 This plugin is now maintained by the Blosxom Sourceforge Team,
304 <blosxom-devel@lists.sourceforge.net>.
305
306 =head1 SEE ALSO
307
308 The wikieditish plug-in plays nicely with the wikiwordish plug-in
309 [http://www.raelity.org/apps/blosxom/plugins/text/wikiwordish.individual]
310 for wiki-style linking action.  And for wiki-style markup, be sure to try the 
311 textile [http://www.raelity.org/apps/blosxom/plugins/text/textile.individual]
312 or tiki [http://www.raelity.org/apps/blosxom/plugins/text/tiki.individual]
313 plug-ins.
314
315 Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/
316
317 Blosxom Plugin Docs: http://blosxom.sourceforge.net/documentation/users/plugins.html
318
319 =head1 BUGS
320
321 None known; please send bug reports and feedback to the Blosxom
322 development mailing list <blosxom-devel@lists.sourceforge.net>.
323
324 =head1 LICENSE
325
326 Blosxom and this Blosxom Plug-in
327 Copyright 2003, Rael Dornfest 
328
329 Permission is hereby granted, free of charge, to any person obtaining a
330 copy of this software and associated documentation files (the "Software"),
331 to deal in the Software without restriction, including without limitation
332 the rights to use, copy, modify, merge, publish, distribute, sublicense,
333 and/or sell copies of the Software, and to permit persons to whom the
334 Software is furnished to do so, subject to the following conditions:
335
336 The above copyright notice and this permission notice shall be included
337 in all copies or substantial portions of the Software.
338
339 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
340 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
341 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
342 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
343 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
344 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
345 OTHER DEALINGS IN THE SOFTWARE.