X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/c96d672810ae524aedf9ffff08dcca773cd9a876..da205c3eaf8e9427531c0f83120be8ba96471868:/doc/todo/calendar_--_archive_browsing_via_a_calendar_frontend.mdwn diff --git a/doc/todo/calendar_--_archive_browsing_via_a_calendar_frontend.mdwn b/doc/todo/calendar_--_archive_browsing_via_a_calendar_frontend.mdwn index d52772a67..caff54780 100644 --- a/doc/todo/calendar_--_archive_browsing_via_a_calendar_frontend.mdwn +++ b/doc/todo/calendar_--_archive_browsing_via_a_calendar_frontend.mdwn @@ -35,567 +35,14 @@ ManojSrivastava Since this is a little bit er, stalled, I'll post here the stuff Manoj mailed me, and my response to it. --[[Joey]] -[[tag patch]] - -
-#! /usr/bin/perl -# -*- Mode: Cperl -*- -# calendar.pm --- -# Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com ) -# Created On : Fri Dec 8 16:05:48 2006 -# Created On Node : glaurung.internal.golden-gryphon.com -# Last Modified By : Manoj Srivastava -# Last Modified On : Sun Dec 10 01:53:22 2006 -# Last Machine Used: glaurung.internal.golden-gryphon.com -# Update Count : 139 -# Status : Unknown, Use with caution! -# HISTORY : -# Description : -# -# arch-tag: 2aa737c7-3d62-4918-aaeb-fd85b4b1384c -# -# Copyright (c) 2006 Manoj Srivastava-# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -require 5.002; -package IkiWiki::Plugin::calendar; - -use warnings; -use strict; -use IkiWiki '1.00'; -use Time::Local; - -our $VERSION = "0.1"; -my $file = __FILE__; - -my %calpages; -my %cache; -my %linkcache; - -my $index=1; -my @now=localtime(); - -=head1 NAME - -calendar - Add links for the current month's, current year's, and older archived postings - -=cut - -=head1 SYNOPSIS - -To invoke the calendar, just use the preprocessor directive (options -and variations are detailed below): - - [[calendar ]] - -or - - [[calendar type="month" pages="blog/* and !*/Discussion"]] - -or - - [[calendar type="year" year="2005" pages="blog/* and !*/Discussion"]] - -=cut - - -=head1 DESCRIPTION - -This plugin is inspired by the calendar plugin for Blosxom, but -derives no code from it. This plugin is essentially a fancy front end -to archives of previous pages, usually used for blogs. It can produce -a calendar for a given month, or a list of months for a given year. - -The year and month entities in the out put have links to archive index -pages, which are supposed to exist already. The idea is to create an -archives hierarchy, rooted in the subdirectory specified in the -site wide customization variable, I . I -defaults to C . Links are created to pages -C<$archivebase/$year> and C<$archivebase/$year/$month>. If one creates -annual and monthly indices, for example, by using something like this -sample from my I (warning: line split for -readability): - - \[[meta title="Archives for 2006/01"]] - \[[inline rootpage="blog" atom="no" rss="no" show="0" - pages="blog/* and !*/Discussion and creation_year(2006) - and creation_month(01)" - ]] - -=cut - -=head1 OPTIONS - -=over - -=item B - -Used to specify the type of calendar wanted. Can be one of C or -C . The default is a month view calendar. - -=item B - -Specifies the C used to get pages to match for -linking. Usually this should be something like C . -Defaults to C<*>. - -=item B - -The year for which the calendar is requested. Defaults to the current year. - -=item B - -The numeric month for which the calendar is requested, in the range -1..12. Used only for the month view calendar, and defaults to the -current month. - -=item B - -A number, in the range 0..6, which represents the day of the week that -the month calendar starts with. 0 is Sunday, 1 is Monday, and so -on. Defaults to 0, which is Sunday. - -=item B - -In the annual calendar, number of months to place in each row. Defaults to 3. - -=back - -=cut - -=head1 Classes for CSS control - -The output is liberally sprinkled with classes, for fine grained CSS -customization. - -=over - -=item C - -The month calendar as a whole - -=item C +> > I'm sending in an updated package, and have removed the older version you had here.--ManojSrivastava -The head of the month calendar (ie,"March"), localized to the environment. -=item C - -A column head in the month calendar (ie, a day-of-week abbreviation), -localized. - -=item C , C , - C , C , - C - -The day squares on the month calendar, for days that don't exist -(before or after the month itself), that don't have stories, that do -have stories, that are in the future, or are that currently selected, -respectively (today). - -=item Day-of-week-name - -Each day square is also given a class matching its day of week, this -can be used to high light weekends. This is also localized. - -=item C - -The year calendar as a whole - -=item C - -The head of the year calendar (ie, "2006") - -=item C - -For example, "Months" - -=item C , C , - C , C - -The month squares on the year calendar, for months with stories, -without, in the future, and currently selected, respectively. - -=back - -=cut - - -sub import { - hook(type => "preprocess", id => "calendar", call => \&preprocess); - hook(type => "format", id => "calendar", call => \&format); -} - -sub preprocess (@) { - my %params=@_; - $params{pages} = "*" unless defined $params{pages}; - $params{type} = "month" unless defined $params{type}; - $params{year} = 1900 + $now[5] unless defined $params{year}; - $params{month} = sprintf("%02d", $params{month}) if defined $params{month}; - $params{month} = 1 + $now[4] unless defined $params{month}; - $params{week_start_day} = 0 unless defined $params{week_start_day}; - $params{months_per_row} = 3 unless defined $params{months_per_row}; - - # Store parameters (could be multiple calls per page) - $calpages{$params{destpage}}{$index} = \%params; - - return "\n " . $index++ . "\n"; -} - -sub is_leap_year (@) { - my %params=@_; - return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 ==0)) ; -} - - -sub month_days { - my %params=@_; - my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1]; - if ($params{month} == 2 && is_leap_year(%params)) { - $days_in_month++; - } - return $days_in_month; -} - - -sub format_month (@) { - my %params=@_; - my $pagespec = $params{pages}; - my $year = $params{year}; - my $month = $params{month}; - - my $calendar="\n"; - - # When did this month start? - my @monthstart = localtime(timelocal(0,0,0,1,$month-1,$year-1900)); - - my $future_dom = 0; - my $today = 0; - $future_dom = $now[3]+1 if ($year == $now[5]+1900 && $month == $now[4]+1); - $today = $now[3] if ($year == $now[5]+1900 && $month == $now[4]+1); - - # Calculate month names for next month, and previous months - my $pmonth = $month - 1; - my $nmonth = $month + 1; - my $pyear = $year; - my $nyear = $year; - - # Adjust for January and December - if ($month == 1) { $pmonth = 12; $pyear--; } - if ($month == 12) { $nmonth = 1; $nyear++; } - - # Find out month names for this, next, and previous months - my $monthname=POSIX::strftime("%B", @monthstart); - my $pmonthname= - POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$pmonth-1,$pyear-1900))); - my $nmonthname= - POSIX::strftime("%B", localtime(timelocal(0,0,0,1,$nmonth-1,$nyear-1900))); - - # Calculate URL's for monthly archives, and article counts - my $archivebase = 'archives'; - $archivebase = $config{archivebase} if defined $config{archivebase}; - - my ($url, $purl, $nurl)=("$monthname",'',''); - my ($count, $pcount, $ncount) = (0,0,0); - - if (exists $cache{$pagespec}{"$year/$month"}) { - $url = htmllink($params{page}, $params{destpage}, - "$archivebase/$year/" . sprintf("%02d", $month), - 0,0," $monthname "); - } - - if (exists $cache{$pagespec}{"$pyear/$pmonth"}) { - $purl = htmllink($params{page}, $params{destpage}, - "$archivebase/$pyear/" . sprintf("%02d", $pmonth), - 0,0," $pmonthname "); - } - if (exists $cache{$pagespec}{"$nyear/$nmonth"}) { - $nurl = htmllink($params{page}, $params{destpage}, - "$archivebase/$nyear/" . sprintf("%02d", $nmonth), - 0,0," $nmonthname "); - } - - # Start producing the month calendar - $calendar=<- - $purl - $url - $nurl - --EOF - # Suppose we want to start the week with day $week_start_day - # If $monthstart[6] == 1 - my $week_start_day = $params{week_start_day}; - - my $start_day = 1 + (7 - $monthstart[6] + $week_start_day) % 7; - my %downame; - my %dowabbr; - for my $dow ($week_start_day..$week_start_day+6) { - my @day=localtime(timelocal(0,0,0,$start_day++,$month-1,$year-1900)); - my $downame = POSIX::strftime("%A", @day); - my $dowabbr = POSIX::strftime("%a", @day); - $downame{$dow % 7}=$downame; - $dowabbr{$dow % 7}=$dowabbr; - $calendar.= - qq{ $dowabbr \n}; - } - - $calendar.=<-EOF - - my $wday; - # we start with a week_start_day, and skip until we get to the first - for ($wday=$week_start_day; $wday != $monthstart[6]; $wday++, $wday %= 7) { - $calendar.=qq{ \n} if $wday == $week_start_day; - $calendar.= - qq{ \n} unless $day == 1; - $calendar.=qq{\n}; - } - - # At this point, either the first is a week_start_day, in which case nothing - # has been printed, or else we are in the middle of a row. - for (my $day = 1; $day <= month_days(year => $year, month => $month); - $day++, $wday++, $wday %= 7) { - # At tihs point, on a week_start_day, we close out a row, and start a new - # one -- unless it is week_start_day on the first, where we do not close a - # row -- since none was started. - if ($wday == $week_start_day) { - $calendar.=qq{ \n}; - } - my $tag; - my $mtag = sprintf("%02d", $month); - if (defined $cache{$pagespec}{"$year/$mtag/$day"}) { - if ($day == $today) { $tag='month-calendar-day-this-day'; } - else { $tag='month-calendar-day-link'; } - $calendar.=qq{ }; - $calendar.= - htmllink($params{page}, $params{destpage}, - pagename($linkcache{"$year/$mtag/$day"}), - 0,0,"$day"); - $calendar.=qq{ \n}; - } - else { - if ($day == $today) { $tag='month-calendar-day-this-day'; } - elsif ($day == $future_dom) { $tag='month-calendar-day-future'; } - else { $tag='month-calendar-day-nolink'; } - $calendar.=qq{$day \n}; - } - } - # finish off the week - for (; $wday != $week_start_day; $wday++, $wday %= 7) { - $calendar.=qq{\n}; - } - $calendar.=< - -EOF - - return $calendar; -} - -sub format_year (@) { - my %params=@_; - my $pagespec = $params{pages}; - my $year = $params{year}; - my $month = $params{month}; - my $calendar="\n"; - my $pyear = $year - 1; - my $nyear = $year + 1; - my $future_month = 0; - $future_month = $now[4]+1 if ($year == $now[5]+1900); - - # calculate URL's for previous and next years - my $archivebase = 'archives'; - $archivebase = $config{archivebase} if defined $config{archivebase}; - my ($url, $purl, $nurl)=("$year",'',''); - if (exists $cache{$pagespec}{"$year"}) { - $url = htmllink($params{page}, $params{destpage}, - "$archivebase/$year", - 0,0,"$year"); - } - - if (exists $cache{$pagespec}{"$pyear"}) { - $purl = htmllink($params{page}, $params{destpage}, - "$archivebase/$pyear", - 0,0,"\←"); - } - if (exists $cache{$pagespec}{"$nyear"}) { - $nurl = htmllink($params{page}, $params{destpage}, - "$archivebase/$nyear", - 0,0,"\→"); - } - # Start producing the year calendar - $calendar=< - - $purl - $url - $nurl - -- -EOF - - for ($month = 1; $month <= 12; $month++) { - my @day=localtime(timelocal(0,0,0,15,$month-1,$year-1900)); - my $murl; - my $monthname = POSIX::strftime("%B", @day); - my $monthabbr = POSIX::strftime("%b", @day); - $calendar.=qq{Months -\n} if ($month % $params{months_per_row} == 1); - my $tag; - my $mtag=sprintf("%02d", $month); - if ($month == $params{month}) { - if ($cache{$pagespec}{"$year/$mtag"}) {$tag = 'this_month_link'} - else {$tag = 'this_month_nolink'} - } - elsif ($cache{$pagespec}{"$year/$mtag"}) {$tag = 'month_link'} - elsif ($future_month && $month >=$future_month){$tag = 'month_future'} - else {$tag = 'month_nolink'} - if ($cache{$pagespec}{"$year/$mtag"}) { - $murl = htmllink($params{page}, $params{destpage}, - "$archivebase/$year/$mtag", - 0,0,"$monthabbr"); - $calendar.=qq{ \n} if ($month % $params{months_per_row} == 0); - } - $calendar.=<}; - $calendar.=$murl; - $calendar.=qq{ \n}; - } - else { - $calendar.=qq{$monthabbr \n}; - } - $calendar.=qq{-EOF - - return $calendar; -} - - -sub format (@) { - my %params=@_; - my $content=$params{content}; - return $content unless exists $calpages{$params{page}}; - - # Restore parameters for each invocation - foreach my $index (keys %{$calpages{$params{page}}}) { - my $calendar="\n"; - my %saved = %{$calpages{$params{page}}{$index}}; - my $pagespec=$saved{pages}; - - if (! defined $cache{$pagespec}) { - for my $page (sort keys %pagesources) { - next unless pagespec_match($page,$pagespec); - my $mtime; - my $src = $pagesources{$page}; - if (! exists $IkiWiki::pagectime{$page}) { - $mtime=(stat(srcfile($src)))[9]; - } - else { - $mtime=$IkiWiki::pagectime{$page} - } - my @date = localtime($mtime); - my $mday = $date[3]; - my $month = $date[4] + 1; - my $year = $date[5] + 1900; - my $mtag = sprintf("%02d", $month); - $linkcache{"$year/$mtag/$mday"} = "$src"; - $cache{$pagespec}{"$year"}++; - $cache{$pagespec}{"$year/$mtag"}++; - $cache{$pagespec}{"$year/$mtag/$mday"}++; - } - } - # So, we have cached data for the current pagespec at this point - if ($saved{type} =~ /month/i) { - $calendar=format_month(%saved); - } - elsif ($saved{type} =~ /year/i) { - $calendar=format_year(%saved); - } - $content =~ s/( \s*.?\s*$index\b)/$calendar/ms; - } - return $content; -} - - - -=head1 CAVEATS - -In the month calendar, for days in which there is more than one -posting, the link created randomly selects one of them. Since there is -no easy way in Bto automatically generate index pages, and -pregenerating daily index pages seems too much of an overhead, we have -to live with this. All postings can still be viewed in the monthly or -annual indices, of course. This can be an issue for very prolific -scriveners. - -=cut - -=head1 BUGS - -None Known so far. - -=head1 BUGS - -Since B eval's the configuration file, the values have to all -on a single physical line. This is the reason we need to use strings -and eval, instead of just passing in real anonymous sub references, -since the eval pass converts the coderef into a string of the form -"(CODE 12de345657)" which can't be dereferenced. - -=cut - -=head1 AUTHOR - -Manoj Srivastava - -=head1 COPYRIGHT AND LICENSE - -This script is a part of the Devotee package, and is - -Copyright (c) 2002 Manoj Srivastava - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -=cut - -1; - -__END__ - +[[tag patch]] ------- +---- -I've been looking over the calendar plugin. Some items: +'ve been looking over the calendar plugin. Some items: * Why did you need to use a two-stage generation with a format hook? That approach should only be needed if adding something to a page that @@ -661,7 +108,17 @@ I've been looking over the calendar plugin. Some items: ---- - And that's all I've heard so far. Hoping I didn't miss another patch? --[[Joey]] + +>No, you did not. But I am back to hacking on this, and I think I have discovered a major problem with my approach. One of the problems with the current plugin is that the goal of a calendar is to create a calendar, either a month >or year based on, that provides links to blogs for all the days in (for the month calendar), and all the months (in a year calendar) in which there have been blog postings. For the monthly calendar, it needs to know the previous >and next months where there is a posting, and for the year calendar, it needs to know which of the previous (next) years had entries. + +>Now, this means that it needs to know about at _all_ pages that meet the pagespec, and stash that information, before it begins generating the calandar in question, in order to calculate how to create the symlinks. And, of >course, all pages that have calendars on them might need to change anytime a page that meets the pagespec is added; and again at midnight, when the current day changes. + +>> I think I have solved the ""Need to look at all pages that match the spec"" issue; but the nightly rebuild to handle the current day changing still remain. I use cron. It is now, however, richly documented :) + + +--ManojSrivastava + +> Finally reviewed and applied this. [[done]]! --[[Joey]]