# Blosxom3 Plugin: Calendar
# Author: Bernie Simon
# Version: 2005-03-02
# More notes at the bottom of this file or type: perldoc Calendar
use strict;
package Blosxom::Plugin::Calendar;
#----------------------------------------------------------------------
# Configuration Section
use constant USE_PATH => 1;
use constant MONTH_NAMES => ['January', 'February', 'March', 'April', 'May',
'June', 'July', 'August', 'September', 'October', 'November', 'December'];
use constant MONTH_ABBREV => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
use constant MONTH_LENGTH => [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
use constant DATE_CLASS => 'caldate';
use constant CALENDAR_HEAD => <<'EOQ';
EOQ
;
#----------------------------------------------------------------------
# call from handlers.flow
sub run {
my $self = shift;
return 1 unless $self->{request}->{flavour} eq 'html';
# Determine which days in the month have entries
my @time = localtime();
my $this_year;
if ($self->{request}->{yr}) {
$this_year = $self->{request}->{yr} - 1900;
} else {
$this_year = $time[5];
}
my $this_month;
if ($self->{request}->{mo_num}) {
$this_month = $self->{request}->{mo_num} - 1;
} else {
$this_month = $time[4];
}
my $base_url = $self->{request}->{url};
if (USE_PATH && $self->{request}->{path_info} ne '/') {
$base_url .= $self->{request}->{path_info};
}
my $event = {};
foreach my $entry_id ( @{$self->{entries_sorted}} ) {
my $entry = $self->{entries}->{$entry_id};
@time = localtime ($entry->{mtime});
last if $time[5] < $this_year ||
($time[5] == $this_year && $time[4] < $this_month);
# Next line fixed 2005-03-02 by Peter Richard
next unless $time[5] == $this_year && $time[4] == $this_month;
next if USE_PATH && $entry->{path} !~ /^$self->{request}->{path_info}/;
$event->{$time[3]} ||= sprintf ('%s/%d/%02d/%02d',
$base_url,
($this_year + 1900),
($this_month + 1),
$time[3])
}
# Calculate weekday of start of month
my $week_day = zeller ($this_year+1900, $this_month+1, 1);
# Get length of month
my $month_length_array = MONTH_LENGTH;
my $month_length = $month_length_array->[$this_month];
$month_length ++ if $this_year % 4 == 0 && $this_month == 1;
# Create hash of variables that can be used in the calendar head and foot
my $dclass = DATE_CLASS;
my $month_name_array= MONTH_NAMES;
my $month_abbrev_array = MONTH_ABBREV;
my $dict = {dclass => $dclass};
my $year = $this_year;
my $month = $this_month - 1;
for my $tag (qw (prev this next)) {
if ($month < 0) {
$month = $month + 12;
$year = $year - 1;
} elsif ($month > 11) {
$month = $month - 12;
$year = $year + 1;
}
$dict->{"${tag}_month_year"} = $year + 1900;
$dict->{"${tag}_month_name"} = $month_name_array->[$month];
$dict->{"${tag}_month_abbrev"} = $month_abbrev_array->[$month];
$dict->{"${tag}_month_url"} = sprintf ('%s/%d/%02d',
$base_url,
($year + 1900),
($month + 1));
$month ++;
}
# Create calendar header
my $head = CALENDAR_HEAD;
$head =~ s/\$(\w+)/$dict->{$1}/g;
my $calendar = $head;
# Create body of calendar
$calendar .="\n";
if ($week_day) {
$calendar .=" ";
$calendar .=" | \n"
}
for (my $day = 1; $day <= $month_length; $day ++) {
$calendar .= "
\n\n"
if $week_day % 7 == 0 && $day != 1;
$calendar .= "";
if ($event->{$day}) {
$calendar .= " {$day}\">$day";
} else {
$calendar .= $day;
}
$calendar .= " | \n";
$week_day ++;
}
$week_day = $week_day % 7;
if ($week_day) {
$week_day = 7 - $week_day;
$calendar .= " ";
$calendar .= " | \n";
}
$calendar .= "
\n";
# Create calendar foot
my $foot = CALENDAR_FOOT;
$foot =~ s/\$(\w+)/$dict->{$1}/g;
$calendar .= $foot;
# Assign calendar to variable that can be used a flavour template
$self->{state}->{current_entry}->{Plugin}->{Calendar}->{Month} = $calendar;
return 1;
}
#----------------------------------------------------------------------
# Compute weekday by Zeller's congruence
sub zeller {
my ($y, $m, $d) = @_;
my @d = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4);
$y-- if $m < 3;
return ($y+ int($y/4) - int($y/100) + int($y/400) + $d[$m-1] + $d) % 7;
}
1;
__END__
=head1 NAME
Blosxom Plug-in: Calendar.pm
=head1 SYNOPSIS
Create a calendar for the month with links to entries on that day
=head1 DESCRIPTION
This plugin creates an html table representing a month's
calendar. Dates in the calendar are links to entries made on that day,
if any were made that day. The calendar is for the current month
unless the url for the web page contains a date, in which case that
day's month is used instead. Add the variable $Plugin::Calendar::Month
to the head.html or foot.html template file to include the calendar in
your Blosxom weblog. The look of the calendar can be modified by
changing the configuration variables CALENDAR_HEAD and CALENDAR_FOOT.
=head1 CONFIGURABLE VARIABLES
=over 4
=item USE_PATH
If this is set to one, the calendar will only link to entries in the
current path, effectively filtering entries by category. If it is set
to zero, the calendar will link to all articles created in the month.
=item MONTH_NAMES
The names of the twelve months
=item MONTH_ABBREV
Abbreviations for the twelve month names.
=item MONTH_LENGTH
The number of days in each month.
=item DATE_CLASS
The html tag of each calendar date is given this class. You can assign
CSS styles to this class to configure the look of the calendar.
=item CALENDAR_HEAD
The html code for the top of the calendar. The html can contain
variables, which start with a "$", just like in Blosxom flavour
templates. The variables are listed below. Edit the lines up to but
not including the EOQ.
=tem CALENDAR_FOOT
The html code for the bottom of the calendar. It can contain
variables, just like CALENDAR_HEAD.
=back
The following variables can be included in the CALENDAR_HEAD and
CALENDAR_FOOT. Most variables come in threes: one for the prvious,
current and next month.
=over 4
=item $date_class
The date class, as set in the configuration variable DATE_CLASS
=item $prev_month_year, $this_month_year, and $next_month_year
The year of the previous, current, and next month.
=item $prev_month_name, $this_month_nae, and $next_month_name
The names of the previous, current, and next months.
=item $prev_month_abbrev, $this_month_abbrev, and $next_month_abbrev
The abbreviated name for the previous, current, and next months
=item $prev_month_url, $this_month_url, and $next_month_url
The url for the entries for the previous, current, and next months
=back
=head1 INSTALLATION
Place this file in the plugins directory and add the line
Blosxom::Plugin::Calendar::run
to the .settings/handlers.flow file between the lines
Blosxom::run_entries
and
Blosxom::render_response
Edit the .templates/head.html or .templates/foot.html file and add the
variable
$Plugin::Calendar::Month
where you want the calendar to appear.
=head1 BUGS
Because the version of Blosxom 3 that is currently being distributed
ignores the handlers.flow file, you need to first install a patch to
Blosxom 3 to fix this problem, such as the one distributed on my
site in order for changes to the handlers.flow file to be recognized.
=head1 AUTHOR
Bernie Simon (http://carelesshand.net)
=head1 LICENSE
Copyright Bernard Simon, 2005. You may use this file as you wish as
long as this copyright notice is maintained.