All my plugins in the released stable versions, so the repository starts
[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 This plugin is now maintained by the Blosxom Sourceforge Team,
158 <blosxom-devel@lists.sourceforge.net>.
159
160 =head1 DESCRIPTION
161
162 Make Blosxom recognize date-based, extensionless URIs for everything (both
163 stories and categories).  http://www.w3.org/Provider/Style/URI.html explains
164 the motivation.  The main goal is to use URIs which never have to be broken 
165 (ever!).  The idea for this plugin came from the cooluri plugin
166 by Rob Hague <http://www.blosxom.com/plugins/link/cooluri.htm>.
167
168 With cooluri2, URIs like this will be recognized:
169  
170  http://example.com/2003/12/03/category
171  http://example.com/2003/12/14/category/story
172
173 Days and months can be left off if you prefer a shorter URI:
174
175  http://example.com/2003/12/category
176  http://example.com/2003/12/category/story
177  
178  http://example.com/2003/category
179  http://example.com/2003/category/story
180
181 The date part of the URI is the creation date for that document.
182 It is take from %blosxom::files, %blosxom::others, %metadate::dirs, or the
183 last-modification time of the file itself.  Note that stories may have
184 different creation dates then the categories they are in, so you may end
185 up with URIs like this:
186
187  http://example.com/2003/10/23/category
188  http://example.com/2003/12/14/category/story
189  
190 This means, unfortunately, that users probably won't be able to modify a URI 
191 to find another document.
192
193 Extensions can still be used to specify a flavor.  If no extension is present
194 the default flavor will be used.
195
196 =head1 SEE ALSO
197
198 Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/
199
200 Blosxom Plugin Docs: http://blosxom.sourceforge.net/documentation/users/plugins.html
201
202 =head2 If you use cooluri2, some of these other plugins might come in handy:
203
204 =over 4
205
206 =item permalink 
207
208 <http://zovirl.com/2003/software/blosxom/plugins/permalink_about>
209
210 makes your life easier by automatically generating Cool URI permalinks.
211
212 =item metadate
213
214 <http://zovirl.com/2003/software/blosxom/plugins/metadate_about>
215
216 allows you to have metadates for categories and non-story files (i.e. images,
217 binaries, etc.).
218
219
220 =back
221
222
223 =head1 BUGS
224
225 None known; please send bug reports and feedback to the Blosxom
226 development mailing list <blosxom-devel@lists.sourceforge.net>.
227
228 =head1 LICENSE
229
230 metadate Blosxom Plugin Copyright 2003, Mark Ivey
231
232 Permission is hereby granted, free of charge, to any person obtaining a
233 copy of this software and associated documentation files (the "Software"),
234 to deal in the Software without restriction, including without limitation
235 the rights to use, copy, modify, merge, publish, distribute, sublicense,
236 and/or sell copies of the Software, and to permit persons to whom the
237 Software is furnished to do so, subject to the following conditions:
238
239 The above copyright notice and this permission notice shall be included
240 in all copies or substantial portions of the Software.
241
242 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
243 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
244 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
245 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
246 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
247 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
248 OTHER DEALINGS IN THE SOFTWARE.
249