tagging: Allow using titles in for related stories.
[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 This plugin is now maintained by the Blosxom Sourceforge Team,
90 <blosxom-devel@lists.sourceforge.net>.
91
92 =head1 DESCRIPTION
93
94 This plugin checks to see if the requested URI corresponds to a
95 category or date-based archive page and forces a redirect if the URI
96 omits a trailing slash; it assumes that you are using URI rewriting
97 rules to hide use of "/cgi-bin/blosxom.cgi". (Otherwise using the
98 plugin wouldn't make much sense.)
99
100 For example, if you request the URI
101
102   http://www.example.com/blog/foo
103
104 where "foo" is a category, this plugin will force a redirect to the
105 URI
106
107   http://www.example.com/blog/foo/
108
109 This plugin was inspired by the redirect plugin by Fletcher T. Penny
110 http://www.blosxom.com/plugins/general/redirect.htm and adapts a bit
111 of its code.
112
113 =head1 INSTALLATION AND CONFIGURATION
114
115 Copy this plugin into your Blosxom plugin directory. You do not
116 normally need to rename the plugin; however see the discussion below.
117
118 You can change the value of the variable C<$debug> to 1 if you need to
119 debug the plugin's operation; the plugin will print to the web
120 server's error log the original path component of the URI and the new
121 URI if redirection is to be done.
122
123 This plugin supplies only a filter and skip subroutine and can
124 normally coexist with other plugins with filter subroutines. However
125 this plugin needs to be run after the extensionless plugin, since it
126 needs the file extension to distinguish between individual entry pages
127 and other pages.
128
129 Finally, note that this plugin is sensitive to the exact URI rewriting
130 rules you might have configured (e.g., in an Apache configuration file
131 or in a .htaccess file). In particular, when rewriting URIs to add the
132 name of the Blosxom CGI script (e.g., "/cgi-bin/blosxom.cgi") you need
133 to ensure that such rules preserve any trailing slash on the end of
134 the URI and pass it on to Blosxom.
135
136 =head1 SEE ALSO
137
138 Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/
139
140 Blosxom Plugin Docs: http://blosxom.sourceforge.net/documentation/users/plugins.html
141
142 =head1 BUGS
143
144 At present the plugin forces a redirect for a date-based URI that
145 specifies a particular day, for example
146
147   http://www.example.com/blog/2004/10/25
148
149 This is arguably incorrect, since (unlike URIs specifying only the
150 year or only the year and month) such a URI is not analogous to a
151 directory.
152
153 Please send bug reports and feedback to the Blosxom development 
154 mailing list <blosxom-devel@lists.sourceforge.net>.
155
156 =head1 LICENSE
157
158 noslashredir Blosxom plugin Copyright 2004 Frank Hecker
159
160 Permission is hereby granted, free of charge, to any person obtaining a
161 copy of this software and associated documentation files (the "Software"),
162 to deal in the Software without restriction, including without limitation
163 the rights to use, copy, modify, merge, publish, distribute, sublicense,
164 and/or sell copies of the Software, and to permit persons to whom the
165 Software is furnished to do so, subject to the following conditions:
166
167 The above copyright notice and this permission notice shall be included
168 in all copies or substantial portions of the Software.
169
170 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
172 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
173 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
174 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
175 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
176 OTHER DEALINGS IN THE SOFTWARE.