Apache-Blog
view release on metacpan or search on metacpan
use vars qw( $VERSION );
$VERSION = '0.03';
use Apache::Constants; # qw(:common);
use Apache::Request;
use HTML::Template;
use File::Basename;
use strict;
# this pretty much just dispatches the request to a different handler,
# depending on what's actually been requested.
sub handler {
my $r = shift;
return &handle_comment($r) if ($r->filename =~ /post-comment$/ );
return &handle_older($r) if ( $r->filename =~ /older\.html$/ );
if (-d $r->filename) {
# they've just asked for the directory - need to send newest entry
my @entries = Apache::Blog::Entry->get_all( $r->filename );
my $latest = $entries[0];
$r->filename( $latest->filepath );
}
return handle_file($r);
return DECLINED;
} # end handler
# we do this if it's an entry we want to show
sub handle_file {
my $r = shift;
my $dir = dirname( $r->filename );
my $template = $dir."/entry-template.html";
# return declined if the entry template doesn't exist
if (!-e $template) {
return DECLINED;
} # end if
$template = HTML::Template->new( filename => $template, die_on_bad_params => 0 );
my $entry = Apache::Blog::Entry->new( $r->filename );
# this is cheating, and breaking OO encapsulation, but i think
# it's fair enough in this case.
$template->param( %$entry );
# entry is the only method that actually does something, rather
# than doing "return shift->{'whatever'}", so we need explicitly
# run it.
$template->param( entry => $entry->entry);
# need to find the next and previous entries too
my @all = Apache::Blog::Entry->get_all( dirname($r->filename) );
# this looks like an overly complicated way of finding out the
# index in @all (which was got in the last line) of this entry
# is. we do that so we can tell what the one after it, and the
# one before it are, so we can have links to them.
my $this_index = 0;
$this_index++ while (defined($all[$this_index]) && $all[ $this_index ]->filename ne $entry->filename);
# previous
if (defined($all[$this_index+1])){
$template->param( prev => $all[$this_index+1]->filename );
} else {
$template->param( prev => $entry->filename );
} #end previous
# next
if ($this_index == 0) {
$template->param( next => $entry->filename );
} else {
$template->param( next => $all[$this_index-1]->filename );
} # end next
# make the clever comments thing work
my @out_comments;
foreach my $comment ($entry->comments) {
push @out_comments, { who => $comment->short_name,
date => $comment->date,
entry => $comment->entry,
};
} # end foreach
$template->param( comments => \@out_comments );
$r->content_type( 'text/html' );
$r->send_http_header;
$r->print( $template->output );
return OK;
} # end handle_file
sub handle_older {
my $r = shift;
# display all the entries
# is there a template?
my $template = dirname($r->filename)."/older.html";
if (!-e $template) {
return DECLINED;
} # end if
$template = HTML::Template->new( filename => $template, die_on_bad_params=>0 );
my @out_entries = Apache::Blog::Entry->get_all( dirname($r->filename) );
$template->param( older_entries => \@out_entries );
my $total_words = 0;
$total_words += $_->wc for @out_entries;
$template->param( total_words => $total_words );
$r->content_type( 'text/html' );
$r->send_http_header;
$r->print( $template->output );
return OK;
} # end handle_directory
sub handle_comment {
my $r = shift;
my $apr = Apache::Request->new($r);
my $name = $apr->param('name');
my $comment = $apr->param('comment');
my $filename = $apr->param('filename');
# if the comment directory doesn't exist, we should create it
my $comment_dir = dirname($r->filename)."/$filename-comment";
if (!-d $comment_dir) {
# looks like perl 5.6.1 doesn't need the permissions bit
# on mkdir, but perl 5.005_03 does. great fun when your
# perl -c is 5.6.1, but your mod_perl is 5.005_03.
# perhaps this should tell me something about my
# development environment. perhaps i shouldn't be so
# liberal here with the permissions either.
unless (mkdir($comment_dir, 0755)) {
$r->log_reason("Can't create $comment_dir: $!");
return SERVER_ERROR;
} # end mkdir
} # end no directory
# need a filename. we start at 1 and move upwards. there's
# almost certainly a race condition here, but this is written
# for my site where i get about one comment a week. if yours is
# so busy you're worried about this breaking, then feel free to
# fix it.
my @existing_files = glob("$comment_dir/*");
my $new_basename = scalar(@existing_files) + 1;
open (COMMENT, ">$comment_dir/$new_basename");
print COMMENT "$name\n";
print COMMENT scalar(localtime)."\n";
print COMMENT $comment;
close COMMENT;
# not quite sure what this will do if the user is being a bitch
# and have proxied away the referer header. this could be
# construed as a bug.
$r->header_out( 'Location' => $r->header_in( 'Referer' ));
return 302;
} # end handle_comment
1;
__END__
=head1 NAME
Apache::Blog - mod_perl weblog handler
=head1 SYNOPSIS
In httpd.conf
Alias /blog/ /home/daniel/blog/
<Location /blog>
SetHandler perl-script
PerlHandler +Apache::Blog
</Location>
=head1 DESCRIPTION
Apache::Blog is a simple handler for online diaries. At the moment it
works on the one-entry-one-page paradigm, but would be easy to apapt to
multiple entries per page if this is prefered. In the future this will
be a configuration option.
It is inspired by the service offered at http://www.diaryland.com/
( run in 1.505 second using v1.01-cache-2.11-cpan-39bf76dae61 )