Change plugin loading to use @INC instead of fixed $plugin_dir.
[pkg/blosxom.git] / blosxom.cgi
index 43afa7d..2a36656 100755 (executable)
@@ -2,8 +2,8 @@
 
 # Blosxom
 # Author: Rael Dornfest <rael@oreilly.com>
-# Version: 2.0.1
-# Home/Docs/Licensing: http://www.blosxom.com/
+# Version: 2.0.2
+# Home/Docs/Licensing: http://blosxom.sourceforge.net/
 # Development/Downloads: http://sourceforge.net/projects/blosxom
 
 package blosxom;
@@ -76,7 +76,7 @@ use File::stat;
 use Time::localtime;
 use CGI qw/:standard :netscape/;
 
-$version = "2.0";
+$version = "2.0.2";
 
 my $fh = new FileHandle;
 
@@ -84,8 +84,17 @@ my $fh = new FileHandle;
 @num2month = sort { $month2num{$a} <=> $month2num{$b} } keys %month2num;
 
 # Use the stated preferred URL or figure it out automatically
-$url ||= url();
-$url =~ s/^included:/http:/; # Fix for Server Side Includes (SSI)
+$url ||= url(-path_info => 1);
+$url =~ s/^included:/http:/ if $ENV{SERVER_PROTOCOL} eq 'INCLUDED';
+
+# NOTE: Since v3.12, it looks as if CGI.pm misbehaves for SSIs and
+# always appends path_info to the url. To fix this, we always
+# request an url with path_info, and always remove it from the end of the
+# string.
+my $pi_len = length $ENV{PATH_INFO};
+my $might_be_pi = substr($url, -$pi_len);
+substr($url, -length $ENV{PATH_INFO}) = '' if $might_be_pi eq $ENV{PATH_INFO};
+
 $url =~ s!/$!!;
 
 # Drop ending any / from dir settings
@@ -134,26 +143,43 @@ $template =
       return join '', <$fh> if $fh->open("< $datadir/$path/$chunk.$flavour");
     } while ($path =~ s/(\/*[^\/]*)$// and $1);
 
-    return join '', ($template{$flavour}{$chunk} || $template{error}{$chunk} || '');
+    # Check for definedness, since flavour can be the empty string
+    if (defined $template{$flavour}{$chunk}) {
+       return $template{$flavour}{$chunk};
+    } elsif (defined $template{error}{$chunk}) {
+       return $template{error}{$chunk} 
+    } else {
+       return '';
+    }
   };
 # Bring in the templates
 %template = ();
 while (<DATA>) {
-  last if /^(__END__)?$/;
-  my($ct, $comp, $txt) = /^(\S+)\s(\S+)\s(.*)$/;
+  last if /^(__END__)$/;
+  my($ct, $comp, $txt) = /^(\S+)\s(\S+)(?:\s(.*))?$/ or next;
   $txt =~ s/\\n/\n/mg;
-  $template{$ct}{$comp} = $txt;
+  $template{$ct}{$comp} .= $txt . "\n";
 }
 
 # Plugins: Start
 if ( $plugin_dir and opendir PLUGINS, $plugin_dir ) {
-  foreach my $plugin ( grep { /^\w+$/ && -f "$plugin_dir/$_"  } sort readdir(PLUGINS) ) {
+  unshift @INC, $plugin_dir;
+  foreach my $plugin ( grep { /^[\w:]+$/ && -f "$plugin_dir/$_"  } sort readdir(PLUGINS) ) {
     next if ($plugin =~ /~$/);   # Ignore emacs backups
-    my($plugin_name, $off) = $plugin =~ /^\d*(\w+?)(_?)$/;
+    my($plugin_name, $off) = $plugin =~ /^\d*([\w:]+?)(_?)$/;
     my $on_off = $off eq '_' ? -1 : 1;
-    require "$plugin_dir/$plugin";
+    # Allow perl module plugins
+    if ($plugin =~ m/::/ && -z "$plugin_dir/$plugin") {
+      # For Blosxom::Plugin::Foo style plugins, we need to use a string require
+      eval "require $plugin_name";
+    }
+    else {
+      eval { require $plugin };
+    }
+    $@ and warn "error finding or loading blosxom plugin $plugin_name - skipping\n" and next;
     $plugin_name->start() and ( $plugins{$plugin_name} = $on_off ) and push @plugins, $plugin_name;
   }
+  shift @INC;
   closedir PLUGINS;
 }
 
@@ -247,7 +273,9 @@ if (!$ENV{GATEWAY_INTERFACE} and param('-password') and $static_password and par
         if ($indexes{$path} == 1) {
           # category
           $path_info = $p;
-          print $fh_w &generate('static', $p, '', $flavour, $content_type);
+          # individual story
+          $path_info =~ s!\.$file_extension$!\.$flavour!;
+          print $fh_w &generate('static', $path_info, '', $flavour, $content_type);
         } else {
           # date
           local ($path_info_yr,$path_info_mo,$path_info_da, $path_info) = 
@@ -437,18 +465,73 @@ sub nice_date {
 # Default HTML and RSS template bits
 __DATA__
 html content_type text/html
-html head <html><head><link rel="alternate" type="type="application/rss+xml" title="RSS" href="$url/index.rss" /><title>$blog_title $path_info_da $path_info_mo $path_info_yr</title></head><body><center><font size="+3">$blog_title</font><br />$path_info_da $path_info_mo $path_info_yr</center><p />
-html story <p><a name="$fn"><b>$title</b></a><br />$body<br /><br />posted at: $ti | path: <a href="$url$path">$path</a> | <a href="$url/$yr/$mo_num/$da#$fn">permanent link to this entry</a></p>\n
-html date <h3>$dw, $da $mo $yr</h3>\n
-html foot <p /><center><a href="http://www.blosxom.com/"><img src="http://www.blosxom.com/images/pb_blosxom.gif" border="0" /></a></body></html>
+
+html head <html>
+html head     <head>
+html head         <link rel="alternate" type="type="application/rss+xml" title="RSS" href="$url/index.rss" />
+html head         <title>$blog_title $path_info_da $path_info_mo $path_info_yr
+html head         </title>
+html head     </head>
+html head     <body>
+html head         <center>
+html head             <font size="+3">$blog_title</font><br />
+html head             $path_info_da $path_info_mo $path_info_yr
+html head         </center>
+html head         <p />
+
+html story        <p>
+html story            <a name="$fn"><b>$title</b></a><br />
+html story            $body<br />
+html story            <br />
+html story            posted at: $ti | path: <a href="$url$path">$path </a> | <a href="$url/$yr/$mo_num/$da#$fn">permanent link to this entry</a>
+html story        </p>
+
+html date         <h3>$dw, $da $mo $yr</h3>
+
+html foot
+html foot         <p />
+html foot         <center>
+html foot             <a href="http://blosxom.sourceforge.net/"><img src="http://blosxom.sourceforge.net/images/pb_blosxom.gif" border="0" /></a>
+html foot         </center>
+html foot     </body>
+html foot </html>
+
 rss content_type text/xml
-rss head <?xml version="1.0"?>\n<!-- name="generator" content="blosxom/$version" -->\n<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">\n\n<rss version="0.91">\n  <channel>\n    <title>$blog_title $path_info_da $path_info_mo $path_info_yr</title>\n    <link>$url</link>\n    <description>$blog_description</description>\n    <language>$blog_language</language>\n
-rss story   <item>\n    <title>$title</title>\n    <link>$url/$yr/$mo_num/$da#$fn</link>\n    <description>$body</description>\n  </item>\n
-rss date \n
-rss foot   </channel>\n</rss>
+
+rss head <?xml version="1.0"?>
+rss head <!-- name="generator" content="blosxom/$version" -->
+rss head <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">
+rss head 
+rss head <rss version="0.91">
+rss head   <channel>
+rss head     <title>$blog_title $path_info_da $path_info_mo $path_info_yr</title>
+rss head     <link>$url</link>
+rss head     <description>$blog_description</description>
+rss head     <language>$blog_language</language>
+
+rss story   <item>
+rss story     <title>$title</title>
+rss story     <link>$url/$yr/$mo_num/$da#$fn</link>
+rss story     <description>$body</description>
+rss story   </item>
+
+rss date 
+
+rss foot   </channel>
+rss foot </rss>
+
 error content_type text/html
-error head <html><body><p><font color="red">Error: I'm afraid this is the first I've heard of a "$flavour" flavoured Blosxom.  Try dropping the "/+$flavour" bit from the end of the URL.</font>\n\n
-error story <p><b>$title</b><br />$body <a href="$url/$yr/$mo_num/$da#fn.$default_flavour">#</a></p>\n
-error date <h3>$dw, $da $mo $yr</h3>\n
-error foot </body></html>
+
+error head <html>
+error head <body>
+error head     <p><font color="red">Error: I'm afraid this is the first I've heard of a "$flavour" flavoured Blosxom.  Try dropping the "/+$flavour" bit from the end of the URL.</font>
+
+
+error story <p><b>$title</b><br />
+error story $body <a href="$url/$yr/$mo_num/$da#fn.$default_flavour">#</a></p>
+
+error date <h3>$dw, $da $mo $yr</h3>
+
+error foot     </body>
+error foot </html>
 __END__