tagging: Allow using titles in for related stories.
[matthijs/upstream/blosxom-plugins.git] / general / permalink
1 # Blosxom Plugin: permalink 
2 # Author(s): Mark Ivey <zovirl@zovirl.com> 
3 # Version: 0.0.2
4 # Documentation: See the bottom of this file or type: perldoc permalink
5
6 package permalink;
7
8 # --- Configurable variables -----
9 # Pick one set of formats, or modify them to make your own
10
11 # Blosxom Date based
12 #$root_format            = '$url/';
13 #$root_flavor_format     = '$url/index.$flavour';
14 #$category_format        = '$url$path/';
15 #$category_flavor_format = '$url$path/index.$flavour';
16 #$file_format            = '$url/$yr/$mo_num/$da#$fn.$default_flavour';
17 #$file_flavor_format     = '$url/$yr/$mo_num/$da#$fn.$flavour';
18
19 # Blosxom Category based
20 #$root_format            = '$url/';
21 #$root_flavor_format     = '$url/index.$flavour';
22 #$category_format        = '$url$path/';
23 #$category_flavor_format = '$url$path/index.$flavour';
24 #$file_format            = '$url$path/$fn.$default_flavour';
25 #$file_flavor_format     = '$url$path/$fn.$flavour';
26
27 # Cool URI 2
28 #$root_format            = '$url/';
29 #$root_flavor_format     = '$url/index.$flavour';
30 #$category_format        = '$url/$yr/$mo_num/$da$path/';
31 #$category_flavor_format = '$url/$yr/$mo_num/$da$path/index.$flavour';
32 #$file_format            = '$url/$yr/$mo_num/$da$path/$fn';
33 #$file_flavor_format     = '$url/$yr/$mo_num/$da$path/$fn.$flavour';
34
35 # Cool URI 2 (Year-only)
36 $root_format            = '$url/';
37 $root_flavor_format     = '$url/index.$flavour';
38 $category_format        = '$url/$yr$path/';
39 $category_flavor_format = '$url/$yr$path/index.$flavour';
40 $file_format            = '$url/$yr$path/$fn';
41 $file_flavor_format     = '$url/$yr$path/$fn.$flavour';
42
43 # --------------------------------
44
45 use File::stat;
46
47 use vars qw($story $category);
48
49 my $debug = 0;  # log debug messages or not?
50
51 my $interpolate = $blosxom::interpolate || sub {
52       package blosxom;
53       my $template = shift;
54       $template =~
55       s/(\$\w+(?:::)?\w*)/"defined $1 ? $1 : ''"/gee;
56       return $template;
57 };
58
59 # see perldoc for description of get_link()
60 sub get_link
61 {        
62     # temporarily override existing blosxom variables & match variables
63     local ($blosxom::fn, $blosxom::flavour, $blosxom::path);
64     local ($1, $2);
65     
66     $blosxom::path = shift || "/";
67     warn "permalink::get_link([$blosxom::path])\n" if $debug > 0;
68     
69     $blosxom::path =~ s!^([^/])!/$1!;    # add a leading / if needed
70     $blosxom::path =~ s!/*$!!;           # remove any slashes from the end
71     
72     # strip off filename & extension
73     my $fn  = ($blosxom::path =~ s[(.*)/(.*)$][$1]) ? $2 : "";
74     my $extension = ($fn =~ s!(.*)(\..*)!$1!) ? $2 : "";
75     
76     my $fullpath = "$blosxom::datadir$blosxom::path";
77     
78     warn "permalink::get_link() fp[$fullpath] fn[$fn] ext[$extension]\n" 
79         if $debug > 0;
80
81     # We look several different places trying to find a matching file.  We
82     # check from the most specific to the least specific.
83     my @places = 
84     (
85         "$fullpath/$fn$extension",                  # exact match
86         "$fullpath/$fn.$blosxom::file_extension",   # story
87         "$fullpath/$fn"                             # category (with flavor)
88     );
89     push @places, "$fullpath/" if ($fn eq "index"); # category (with index)
90
91     my ($out, $location);
92     while (defined ($location = shift @places))
93     {
94         next unless (-e "$location");
95         warn "permalink::get_link() found $location\n" if $debug > 0;
96         
97         if ($extension)
98         {
99             $blosxom::flavour = $extension;
100             $blosxom::flavour =~ s/^\.//;   # remove leading .
101         }
102         
103         if (-d "$location")
104         {
105             # filename is part of the path for categories...
106             $blosxom::path .= "/$fn" if ($fn and $fn ne "index");
107             
108             # check to see if we are working on the root or not
109             if ($location =~ m!^$blosxom::datadir/*$!)
110             {
111                 $out=($extension) ? $root_flavor_format : $root_format;
112             }
113             else
114             {
115                 $out=($extension) ? $category_flavor_format : $category_format;
116             }
117         }
118         else
119         {
120             $blosxom::fn = $fn;
121             $out = ($extension) ? $file_flavor_format : $file_format
122         }
123         last;
124     }
125
126     unless (defined $location)
127     {
128         warn "permalink::get_link() can't find $fullpath/$fn$extension\n";
129         return "";
130     }
131     
132     # look up the date on the file
133     my $mtime = $blosxom::files{"$location"}  ||
134                 $blosxom::others{"$location"} || 
135                 $metadate::dirs{"$location"}  ||
136                 $metadate::all{"$location"} ||
137                 stat("$location")->mtime;
138     local ($blosxom::dw, $blosxom::mo, $blosxom::mo_num, $blosxom::da, 
139         $blosxom::ti, $blosxom::yr) = blosxom::nice_date($mtime);
140
141     # use interpolate() to fill in all the variables in our template
142     $out = &$interpolate($out);
143
144     warn "permalink::get_link() returning [$out]\n" if $debug > 0;
145     return $out;
146 }
147
148 sub head
149 {    
150     my($pkg, $currentdir, $head_ref) = @_;
151
152     $story = "";
153     $category = get_link("/$currentdir");
154     return 1;
155 }
156
157 sub start
158 {    
159     return 1;
160 }
161
162 sub date
163 {    
164     my ($pkg, $currentdir, $date_ref, $mtime, $dw,$mo,$mo_num,$da,$ti,$yr) = @_;
165     $story = "";
166     $category = get_link("/$currentdir");
167     return 1;
168 }
169
170 sub story
171 {    
172     my ($pkg, $path, $fn, $story_ref, $title_ref, $body_ref) = @_;
173     $story = get_link("$path/$fn");
174     $category = get_link("$path");
175     return 1;
176 }
177
178 sub foot
179 {    
180     my($pkg, $currentdir, $foot_ref) = @_;
181     $story = "";
182     $category = get_link("/$currentdir");
183     return 1;
184 }
185
186 1;
187
188 __END__
189
190 =head1 NAME
191
192 Blosxom Plug-in: permalink 
193
194 =head1 SYNOPSIS
195
196 Generate permalinks
197
198 =head1 VERSION
199
200 0.0.2
201
202 =head1 AUTHOR
203
204 Mark Ivey <zovirl1@zovirl.com>, http://zovirl.com
205
206 This plugin is now maintained by the Blosxom Sourceforge Team,
207 <blosxom-devel@lists.sourceforge.net>.
208
209 =head1 DESCRIPTION
210
211 This plugin generates permalinks to help make it easier to use a consistent
212 format throughout a site.  For use in flavor files, two variables are
213 exported: $permalink::story and $permalink::category.  These link to the
214 current story and category, respectively.  For other plugins which may
215 wish to generate links, $permalink::get_link() is provided.  Given a path
216 to a file, story, or category, it returns the correct permalink.
217
218 $permalink::get_link() expects the path to a file, category, or story 
219 (starting from $blosxom::datadir).  If there is an extension present it 
220 is used as flavor.
221
222 =head1 SEE ALSO
223
224 Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/
225
226 Blosxom Plugin Docs: http://blosxom.sourceforge.net/documentation/users/plugins.html
227
228 =head1 BUGS
229
230 get_link() can't be used for files outside the $blosxom::datadir directory.  
231 This might be a problem if your $blosxom::datadir isn't publically available
232 (by being under the web-server's document root, by using the static_file plugin,
233 etc.)
234
235 None known; please send bug reports and feedback to the Blosxom
236 development mailing list <blosxom-devel@lists.sourceforge.net>.
237
238 =head1 LICENSE
239
240 permalink Blosxom Plugin Copyright 2003, Mark Ivey
241
242 (This plugin is release under the same license as Blosxom itself)
243
244 Permission is hereby granted, free of charge, to any person obtaining a copy of 
245 this software and associated documentation files (the "Software"), to deal in 
246 the Software without restriction, including without limitation the rights to 
247 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
248 the Software, and to permit persons to whom the Software is furnished to do so,
249 subject to the following conditions:
250
251 The above copyright notice and this permission notice shall be included in all 
252 copies or substantial portions of the Software.
253
254 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
255 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
256 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
257 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
258 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
259 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
260