Add various plugins from Mark Ivey.
[matthijs/upstream/blosxom-plugins.git] / general / cooluri2
1 # Blosxom Plugin: cooluri2
2 # Author(s): Mark Ivey <zovirl@zovirl.com>
3 # Version: 0.0.1
4 # Documentation: See the bottom of this file or type: perldoc cooluri2
5
6 package cooluri2;
7 use strict;
8 use English;
9
10 use File::stat;
11 use CGI qw/:standard/;
12
13 my $debug = 0;   # log debug messages or not?
14
15 #FIXME: Should we return 0 in static mode?
16 sub start {1;}
17
18 sub filter
19 {
20     # get info from URI
21     my ($year, $month, $day, $blosxom_path, $path, $flavor) = 
22         parse_URI(path_info() || param('path'));
23     
24     # adjust blosxom's variables
25     $blosxom::path_info = $blosxom_path;
26     $blosxom::path_info_yr = '';
27     $blosxom::path_info_mo = '';
28     $blosxom::path_info_mo_num = '';
29     $blosxom::path_info_da = '';
30     $blosxom::flavour = $flavor;
31     
32     # delete stories not matching path
33     while (my ($file, $time) = each %blosxom::files)
34     {
35         delete $blosxom::files{$file} if ($file !~ /^$path/);
36     }
37     
38     # make sure path's date matches
39     my ($dw,$mo,$mo_num,$da,$ti,$yr) = get_date($path);
40     if (        ($year and $yr ne $year) or
41             ($month and $mo_num ne $month) or
42             ($day and $da ne $day)
43         )
44     {
45         %blosxom::files = ();
46     }
47     
48     return 1;
49 }
50
51 # break the URI up into pieces
52 sub parse_URI
53 {
54     my @uri = split '/', shift;
55     shift @uri; # throw away empty item before 1st slash
56     
57     # pull off the date, then the path 
58     my (@date_parts, @path_parts);
59     while (defined $uri[0] and $uri[0] =~ /^\d/)
60     {
61         push @date_parts, shift @uri;
62     }
63     
64     while (defined $uri[0] and $uri[0] =~ /^[a-zA-Z]/)
65     {
66         push @path_parts, shift @uri;
67     }
68     
69     # pull the .flavor off the story.
70     my $flavor = param('flav') || $blosxom::default_flavour;
71     my $story = pop @path_parts; # story = last part of path
72     if ($story =~ /(.*)\.(.*)$/)
73     {
74         $flavor = $2 if ($2);
75         $story = $1;  # toss flavor off story
76     }
77     push @path_parts, $story unless ($story eq 'index'); #throw away "index"
78     
79     my $path = join "/", (@path_parts);
80     
81     # Strip spurious slashes  FIXME: Will we ever even have spurious slashes?
82     $path =~ s!(^/*)|(/*$)!!g;
83     
84     my ($year, $month, $day) = @date_parts;
85     # FIXME: I don't think we can do this, since its hard to tell
86     # a month called "Dec" from a category called "Dec"
87     #my $month_num = $month ? 
88     #( 
89     #    $month =~ /\d{2}/ ? $month : ($month2num{ucfirst(lc$month)} || undef) 
90     #) : undef;
91
92
93     my $blosxom_path = $path;
94     $path = "$blosxom::datadir/$path"; # get full path AFTER we get blosxom_path
95     
96     # don't add flavor back on for index or if file exists user might be asking 
97     # for either a category or something to be served by static_file
98     $blosxom_path .= ".$flavor" if ($story ne 'index' and not -e "$path");
99
100     warn "cooluri2: Internally: date[$year/$month/$day] path[$path] " .
101         "story[$story] flavor[$flavor]\n" if $debug > 0;
102     warn "cooluri2: Externally: date[//] path[$blosxom_path] flavor[$flavor]\n"
103         if $debug > 0;
104
105     return ($year, $month, $day, $blosxom_path, $path, $flavor);
106 }
107
108 # get the date of a file.
109 sub get_date
110 {
111     my $path = shift;
112     my $file_time = 0;
113     
114     # check %files, %others, %metadate::dirs, finally check on the disk
115     if (exists $blosxom::files{"$path.$blosxom::file_extension"})
116     {
117         $file_time = $blosxom::files{"$path.$blosxom::file_extension"};
118     }
119     elsif (exists $blosxom::others{"$path.$blosxom::file_extension"})
120     {
121         $file_time = $blosxom::others{"$path.$blosxom::file_extension"};
122     }
123     elsif (exists $metadate::dirs{"$path"})
124     {
125         $file_time = $metadate::dirs{"$path"};
126     }
127     elsif (-e "$path")
128     {
129         $file_time = stat("$path")->mtime;
130     }
131
132     return blosxom::nice_date($file_time);
133 }
134
135 1;
136
137
138 __END__
139
140 =head1 NAME
141
142 Blosxom Plug-in: cooluri2
143
144 =head1 SYNOPSIS
145
146 Make Blosxom recognize date-based, extensionless URIs for everything.  See 
147 http://www.w3.org/Provider/Style/URI.html for motivation.
148
149 =head1 VERSION
150
151 0.0.1
152
153 =head1 AUTHOR
154
155 Mark Ivey <zovirl@zovirl.com>, http://zovirl.com
156
157 =head1 DESCRIPTION
158
159 Make Blosxom recognize date-based, extensionless URIs for everything (both
160 stories and categories).  http://www.w3.org/Provider/Style/URI.html explains
161 the motivation.  The main goal is to use URIs which never have to be broken 
162 (ever!).  The idea for this plugin came from the cooluri plugin
163 by Rob Hague <http://www.blosxom.com/plugins/link/cooluri.htm>.
164
165 With cooluri2, URIs like this will be recognized:
166  
167  http://example.com/2003/12/03/category
168  http://example.com/2003/12/14/category/story
169
170 Days and months can be left off if you prefer a shorter URI:
171
172  http://example.com/2003/12/category
173  http://example.com/2003/12/category/story
174  
175  http://example.com/2003/category
176  http://example.com/2003/category/story
177
178 The date part of the URI is the creation date for that document.
179 It is take from %blosxom::files, %blosxom::others, %metadate::dirs, or the
180 last-modification time of the file itself.  Note that stories may have
181 different creation dates then the categories they are in, so you may end
182 up with URIs like this:
183
184  http://example.com/2003/10/23/category
185  http://example.com/2003/12/14/category/story
186  
187 This means, unfortunately, that users probably won't be able to modify a URI 
188 to find another document.
189
190 Extensions can still be used to specify a flavor.  If no extension is present
191 the default flavor will be used.
192
193 =head1 SEE ALSO
194
195 Blosxom Home/Docs/Licensing: http://www.raelity.org/apps/blosxom/
196
197 Blosxom Plugin Docs: http://www.raelity.org/apps/blosxom/plugin.shtml
198
199 =head2 If you use cooluri2, some of these other plugins might come in handy:
200
201 =over 4
202
203 =item permalink 
204
205 <http://zovirl.com/2003/software/blosxom/plugins/permalink_about>
206
207 makes your life easier by automatically generating Cool URI permalinks.
208
209 =item metadate
210
211 <http://zovirl.com/2003/software/blosxom/plugins/metadate_about>
212
213 allows you to have metadates for categories and non-story files (i.e. images,
214 binaries, etc.).
215
216
217 =back
218
219
220 =head1 BUGS
221
222 Address bug reports and comments to the Blosxom mailing list 
223 [http://www.yahoogroups.com/group/blosxom].
224
225 =head1 LICENSE
226
227 metadate Blosxom Plugin Copyright 2003, Mark Ivey
228
229 Permission is hereby granted, free of charge, to any person obtaining a
230 copy of this software and associated documentation files (the "Software"),
231 to deal in the Software without restriction, including without limitation
232 the rights to use, copy, modify, merge, publish, distribute, sublicense,
233 and/or sell copies of the Software, and to permit persons to whom the
234 Software is furnished to do so, subject to the following conditions:
235
236 The above copyright notice and this permission notice shall be included
237 in all copies or substantial portions of the Software.
238
239 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
240 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
242 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
243 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
244 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
245 OTHER DEALINGS IN THE SOFTWARE.
246