X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=general%2Fextensionless;fp=general%2Fextensionless;h=33df8dc3391313c9561cefea84ff8822087c79a6;hb=fca3198611f04b221a988c7bf2df19cb4a08402b;hp=0000000000000000000000000000000000000000;hpb=e7287283e68baf7fef5a415a05d1168f9dc7ea98;p=matthijs%2Fupstream%2Fblosxom-plugins.git diff --git a/general/extensionless b/general/extensionless new file mode 100644 index 0000000..33df8dc --- /dev/null +++ b/general/extensionless @@ -0,0 +1,279 @@ +# Blosxom Plugin: extensionless +# Author(s): Frank Hecker +# Version: 0.4 +# Documentation: See the bottom of this file or type: perldoc extensionless + +package extensionless; + +use strict; + +use CGI qw/:standard :netscape/; + + +# --- Configurable variables ----- + +my $hide_category = 0; # set to 1 to have an extensionless + # entry URI hide a category of the + # same name as the entry + +my $hide_year = 0; # set to 1 to have an extensionless + # URI with 4-digit entry name hide an + # archive page for a year + +my $debug = 0; # set to 1 to print debug messages + +# -------------------------------- + +sub start { + warn "extensionless: \$path_info: '$blosxom::path_info' (before)\n" + if $debug > 0; + + # Recover the original path passed to Blosxom, in order to properly + # handle extensionless URIs where the entry name starts with a digit + # and was parsed by Blosxom as a date reference, not as part of the path. + + my $path_info = path_info() || param('path'); + $path_info =~ s!(^/*)|(/*$)!!g; + + # Check for the following situation: + # + # * the requested URI does not include a file extension + # * the requested URI does not *exactly* name a category OR + # we want the URI to always resolve to an entry if one exists + # * the requested URI does not appear to refer to an archive for a year + # OR we want the URI to always resolve to an entry if one exists + # * there is an entry corresponding to the URI + # + # If the above conditions hold then we update the URI (more specifically, + # the path component of the URI) to include the flavour's file extension. + # (The flavour used will be the default flavour, a flavour specified + # using the flav parameter, or a flavour set by another plugin.) + # + # We also set $path_info_yr to be undefined in order to prevent Blosxom + # and other plugins (e.g., storystate) from considering this an archive + # page reference in the case where the entry name starts with a digit. + + if ($blosxom::path_info !~ m!\.! + and (! -d "$blosxom::datadir/$path_info" || $hide_category) + and ($path_info !~ m!(/19[0-9]{2}$)|(/2[0-9]{3}$)! || $hide_year) + and (-r "$blosxom::datadir/$path_info.$blosxom::file_extension")) { + $blosxom::path_info = "$path_info.$blosxom::flavour"; + $blosxom::path_info_yr = undef; + } + + warn "extensionless: \$path_info: '$blosxom::path_info' (after)\n" + if $debug > 0; + + 1; +} + +1; + +__END__ + +=head1 NAME + +Blosxom plugin: extensionless + +=head1 SYNOPSIS + +Make Blosxom recognize extensionless URIs corresponding to individual +entries. See http://www.w3.org/Provider/Style/URI for motivation. + +=head1 VERSION + +0.4 + +=head1 AUTHOR + +Frank Hecker , http://www.hecker.org/ + +=head1 DESCRIPTION + +This plugin allows Blosxom to recognize extensionless URIs for +entries, as recommended by http://www.w3.org/Provider/Style/URI and +elsewhere. In other words, if you are requesting a page for an +individual entry then you can omit the file extension that would +normally be required for specifying the flavour, unless the extension +is required to disambiguate the URI in the case where the entry has +the same name as a Blosxom category or looks like a 4-digit year +reference. + +For example, if you have an entry C in your Blosxom data +directory then by using this plugin you can use a URI like + + http://www.example.com/blog/foo/bar + +to request the entry rather than a URI like + + http://www.example.com/blog/foo/bar.html + +unless there is an existing category C (i.e., there is a +subdirectory of that name in the Blosxom data directory). If there is +such a name conflict then the plugin will cause Blosxom to display the +category and not the individual entry. + +(You can change this behavior using a configurable variable as +described below. The plugin's default behavior matches the behavior of +Apache when using the MultiViews option, where Apache will display the +index for an existing directory C in preference to displaying +a file C.) + +You can also use extensionless URIs like + + http://www.example.com/blog/foo/1st-post + +where the entry name starts with a digit, as long as the entry name +doesn't look like a 4-digit year (e.g., "2004") used as part of a +request for an archive page for that year. (Again, you can set a +configurable variable to override the default behavior and have entry +names that look like year references.) + +When an entry is requested using an extensionless URI the existing +value of the Blosxom C<$flavour> variable will determine the flavour +used for the entry. Normally this value will be either that specified +by the C parameter (if it is present) or the default flavour +configured into Blosxom; however another plugin could override this +value if desired. For example, a separate plugin could do content +negotiation (e.g., using the HTTP Accept header) to determine what +flavour should be served for an entry. (However see the discussion +below regarding plugin execution order.) + +Thus assuming that C exists in the Blosxom data directory +(and does not conflict with a category C) and the default +flavour is "html" then the following URIs are all equivalent: + + http://www.example.com/blog/foo/bar + http://www.example.com/blog/foo/bar.html + http://www.example.com/blog/foo/bar?flav=html + +=head1 INSTALLATION AND CONFIGURATION + +Copy this plugin into your Blosxom plugin directory. You do not +normally need to rename the plugin; however see the discussion below +regarding plugin execution order. + +Change the value of the configurable variable C<$hide_category> to 1 +if you want an extensionless URI to display an entry instead of a +category of the same name. As described above, the default behavior is +that in the event of a name conflict the category is displayed in +preference to the entry, so that displaying the entry in that case +requires explicitly adding a file extension to the URI. If you change +the plugin's behavior from the default then the category can be +displayed only by using a URI explicitly referencing an index page +(e.g., C<.../foo/index.html>) or by referencing an abbreviation for +the category. + +Change the value of the configurable variable C<$hide_year> to 1 if +you want an extensionless URI to display an entry in the case where +the URI otherwise appears to be a reference to an archive page for a +given year, for example, with the URI + + http://www.example.com/blog/elections/2004 + +where an entry C<2004.txt> exists under the category C. As +described above, the default behavior is that in the event of a +conflict the archive page is displayed in preference to the entry, so +that displaying the entry in that case requires explicitly adding a +file extension to the URI. If you change the plugin's behavior from +the default then the archive page for that year can be displayed only +by usng a URI explicitly referencing an index page (e.g., +C<.../elections/2004/index.html>). + +You can also change the value of the variable C<$debug> to 1 if you +need to debug the plugin's operation; the plugin will print to the web +server's error log the original path component of the URI and the +value after any modification is done. + +This plugin supplies only a start subroutine and can normally coexist +with other plugins with start subroutines; however if the other +plugins' start subroutines depend on the standard interpretation of +the Blosxom variable C<$path_info> (i.e., that requests for individual +entries have a period '.' in C<$path_info>) then you should rename +this plugin (e.g., to "00extensionless") to ensure that it is loaded +first and can modify C<$path_info> to match the standard +interpretation before other plugins reference its value. + +Also, if you have a plugin that overrides the value of the Blosxom +C<$flavour> variable then you should ensure that that plugin's code +runs prior to this plugin's start subroutine being executed. + +=head1 ACKNOWLEDGEMENTS + +This plugin was inspired by the cooluri plugin by Rob Hague +http://www.blosxom.com/plugins/link/cooluri.htm and the cooluri2 +plugin by Mark Ivey http://www.blosxom.com/plugins/link/cooluri2.htm +but has much less ambitious goals; the code is correspondingly much +simpler. + +Thanks also go to Stu MacKenzie, who contributed a patch to fix a +major bug preventing the use of extensionless URIs having entry names +beginning with digits. + +=head1 SEE ALSO + +Blosxom Home/Docs/Licensing: http://www.blosxom.com/ + +Blosxom Plugin Docs: http://www.blosxom.com/documentation/users/plugins.html + +=head1 BUGS + +In order to check whether a file extension was originally included in +the URI we check the value of C<$blosxom::path_info>. As noted in a +comment in the code, this value is not the actual URI path in the case +where the URI contains a component starting with a digit; however +checking C<$blosxom::path_info> works for the URIs of interest to us +and (unlike checking our local C<$path_info> value) does not produce +potentially spurious results on invalid Blosxom URIs like + + http://www.example.com/blog/foo/123bar/baz.html + +(Unlike entry names, Blosxom category names can never start with a +digit, and allowing them to do so is beyond the scope of this +plugin. For this example URI Blosxom would have set C<$path_info> to +C and attempted to parse C<123bar> and C as +C<$path_info_yr> and C<$path_info_mo> respectively.) + +Using an entry name that looks like a year reference is problematic +because of potential ambiguity regarding what actually is a year +reference and what is not. The code as presently written takes a +relatively (but not completely) conservative approach: values from +1900 through 2999 are considered to be year references, and by default +will hide references to entries of the same name (sans extension). + +Also note that versions of this plugin prior to 0.4 are not +compatible with Blosxom versions 2.0.1 and higher; in prior versions +this plugin executed its code in the filter subroutine, and in Blosxom +2.0.1 the execution of plugins' filter subroutines was moved in a way +that broke this plugin. This problem was fixed in version 0.4 of this +plugin by moving processing to the start subroutine. + +Finally note that this plugin assumes that you are storing Blosxom +entries in the standard manner, i.e., as text files in the file system +within the Blosxom data directory. It will not work if you are using +other plugins like svn-backend that use different storage mechanisms. + +Please address other bug reports and comments to the Blosxom mailing +list: http://www.yahoogroups.com/group/blosxom + +=head1 LICENSE + +extensionless Blosxom plugin Copyright 2004-2006 Frank Hecker + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE.