Add Frank Hecker plugins to general.
[matthijs/upstream/blosxom-plugins.git] / general / noslashredir
1 # Blosxom Plugin: noslashredir
2 # Author(s): Frank Hecker <hecker@hecker.org>
3 # Version: 0.1
4 # Documentation: See the bottom of this file or type: perldoc noslashredir
5
6 package noslashredir;
7
8 use strict;
9
10 use CGI qw/:standard :netscape/; 
11
12 # --- Configurable variables -----
13
14 my $debug = 0;                          # set to 1 to print debug messages
15
16 # --------------------------------
17
18 use vars qw!$redirecting!;              # 1 if we are redirecting, 0 if not
19
20 sub start {
21     $redirecting = 0;
22     1;
23 }
24
25 sub filter {
26     my ($pkg, $files_ref) = @_;
27
28     warn "noslashredir: \$path_info: '" . $blosxom::path_info . "'\n"
29         if $debug > 0;
30     warn "noslashredir: path_info(): '" . path_info() . "'\n"
31         if $debug > 0;
32
33     # If the requested URI does not include a file extension (thus, it
34     # represents the blog root, a category, or a date-based archive page)
35     # and the requested URI does not end in a slash ('/') then add a slash
36     # to the URI and force a redirect.
37     #
38     # Note 1: We use $blosxom::path_info to check for the presence of a
39     # file extension because it may not have been present in the original
40     # URI but rather might have been added by the extensionless plugin.
41     #
42     # Note 2: We use path_info() to check for the presence of a trailing
43     # slash because the blosxom.cgi code strips trailing slashes from
44     # $blosxom::path_info and does not include the date components.
45
46     if ($blosxom::path_info !~ m!\.! && path_info() !~ m!/$!) {
47         my $uri = "$blosxom::url" . path_info() . "/";
48         $uri .= "?" . $ENV{QUERY_STRING} if $ENV{QUERY_STRING};
49
50         warn "noslashredir: redirecting to '$uri'\n"
51             if $debug > 0;
52
53         my $message =
54             qq!Trailing slash omitted, redirecting to <a href="$uri">$uri</a>.\n!;
55         $blosxom::output = $message;
56         print "Status: 301\n";
57         print "Location: $uri\n";
58         $redirecting = 1;
59         }
60
61     1;
62 }
63
64 sub skip {
65     return $redirecting;   # skip story generation if redirecting
66 }
67
68 1;
69
70 __END__
71
72 =head1 NAME
73
74 Blosxom plugin: noslashredir
75
76 =head1 SYNOPSIS
77
78 Have Blosxom force a redirect if a non-entry URI does not have a trailing
79 slash.
80
81 =head1 VERSION
82
83 0.1
84
85 =head1 AUTHOR
86
87 Frank Hecker <hecker@hecker.org>, http://www.hecker.org/
88
89 =head1 DESCRIPTION
90
91 This plugin checks to see if the requested URI corresponds to a
92 category or date-based archive page and forces a redirect if the URI
93 omits a trailing slash; it assumes that you are using URI rewriting
94 rules to hide use of "/cgi-bin/blosxom.cgi". (Otherwise using the
95 plugin wouldn't make much sense.)
96
97 For example, if you request the URI
98
99   http://www.example.com/blog/foo
100
101 where "foo" is a category, this plugin will force a redirect to the
102 URI
103
104   http://www.example.com/blog/foo/
105
106 This plugin was inspired by the redirect plugin by Fletcher T. Penny
107 http://www.blosxom.com/plugins/general/redirect.htm and adapts a bit
108 of its code.
109
110 =head1 INSTALLATION AND CONFIGURATION
111
112 Copy this plugin into your Blosxom plugin directory. You do not
113 normally need to rename the plugin; however see the discussion below.
114
115 You can change the value of the variable C<$debug> to 1 if you need to
116 debug the plugin's operation; the plugin will print to the web
117 server's error log the original path component of the URI and the new
118 URI if redirection is to be done.
119
120 This plugin supplies only a filter and skip subroutine and can
121 normally coexist with other plugins with filter subroutines. However
122 this plugin needs to be run after the extensionless plugin, since it
123 needs the file extension to distinguish between individual entry pages
124 and other pages.
125
126 Finally, note that this plugin is sensitive to the exact URI rewriting
127 rules you might have configured (e.g., in an Apache configuration file
128 or in a .htaccess file). In particular, when rewriting URIs to add the
129 name of the Blosxom CGI script (e.g., "/cgi-bin/blosxom.cgi") you need
130 to ensure that such rules preserve any trailing slash on the end of
131 the URI and pass it on to Blosxom.
132
133 =head1 SEE ALSO
134
135 Blosxom Home/Docs/Licensing: http://www.blosxom.com/
136
137 Blosxom Plugin Docs: http://www.blosxom.com/documentation/users/plugins.html
138
139 =head1 BUGS
140
141 At present the plugin forces a redirect for a date-based URI that
142 specifies a particular day, for example
143
144   http://www.example.com/blog/2004/10/25
145
146 This is arguably incorrect, since (unlike URIs specifying only the
147 year or only the year and month) such a URI is not analogous to a
148 directory.
149
150 Address other bug reports and comments to the Blosxom mailing list:
151 http://www.yahoogroups.com/group/blosxom
152
153 =head1 LICENSE
154
155 noslashredir Blosxom plugin Copyright 2004 Frank Hecker
156
157 Permission is hereby granted, free of charge, to any person obtaining a
158 copy of this software and associated documentation files (the "Software"),
159 to deal in the Software without restriction, including without limitation
160 the rights to use, copy, modify, merge, publish, distribute, sublicense,
161 and/or sell copies of the Software, and to permit persons to whom the
162 Software is furnished to do so, subject to the following conditions:
163
164 The above copyright notice and this permission notice shall be included
165 in all copies or substantial portions of the Software.
166
167 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
169 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
170 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
171 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
172 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
173 OTHER DEALINGS IN THE SOFTWARE.