# 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 ; use constant CALENDAR_FOOT => <<'EOQ';
$this_month_name $this_month_year
S
M
T
W
T
F
S
$prev_month_abbrev     $next_month_abbrev
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.