From f35b62d4547c2c42373584016bcbf97472e3ae3a Mon Sep 17 00:00:00 2001 From: Louis Date: Mon, 7 Jul 2014 14:54:10 +0200 Subject: [PATCH] Calendar pages are now rebuilt when previous or next page have changed --- IkiWiki/Plugin/calendar.pm | 117 ++++++++++++++++++++++++++++--------- doc/plugins/calendar.mdwn | 11 +++- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm index 185026d20..65ed16ed4 100644 --- a/IkiWiki/Plugin/calendar.pm +++ b/IkiWiki/Plugin/calendar.pm @@ -25,6 +25,7 @@ use Time::Local; my $time=time; my @now=localtime($time); +my %changed; sub import { hook(type => "checkconfig", id => "calendar", call => \&checkconfig); @@ -32,6 +33,7 @@ sub import { hook(type => "needsbuild", id => "calendar", call => \&needsbuild); hook(type => "preprocess", id => "calendar", call => \&preprocess); hook(type => "scan", id => "calendar", call => \&scan); + hook(type => "build_affected", id => "calendar", call => \&build_affected); IkiWiki::loadplugin("transient"); } @@ -104,6 +106,26 @@ sub month_days { return $days_in_month; } +sub build_affected { + my %affected; + my ($ayear, $amonth, $valid); + + foreach my $year (keys %changed) { + ($ayear, $valid) = nextyear($year, $config{archivebase}); + $affected{calendarlink($ayear)} = sprintf(gettext("building calendar for %s, its previous or next year has changed"), $ayear) if ($valid); + ($ayear, $valid) = previousyear($year, $config{archivebase}); + $affected{calendarlink($ayear)} = sprintf(gettext("building calendar for %s, its previous or next year has changed"), $ayear) if ($valid); + foreach my $month (keys $changed{$year}) { + ($ayear, $amonth, $valid) = nextmonth($year, $month, $config{archivebase}); + $affected{calendarlink($ayear, sprintf("%02d", $amonth))} = sprintf(gettext("building calendar for %s/%s, its previous or next month has changed"), $amonth, $ayear) if ($valid); + ($ayear, $amonth, $valid) = previousmonth($year, $month, $config{archivebase}); + $affected{calendarlink($ayear, sprintf("%02d", $amonth))} = sprintf(gettext("building calendar for %s/%s, its previous or next month has changed"), $amonth, $ayear) if ($valid); + } + } + + return %affected; +} + sub autocreate { my ($page, $pagefile, $year, $month) = @_; my $message=sprintf(gettext("creating calendar page %s"), $page); @@ -196,6 +218,66 @@ sub gencalendaryear { } } +sub previousmonth($$$) { + my $year = shift; + my $month = shift; + my $archivebase = shift; + + my $pmonth = $month; + my $pyear = $year; + while ((not exists $pagesources{"$archivebase/$pyear/" . sprintf("%02d", $pmonth)}) or ($pmonth == $month and $pyear == $year)) { + $pmonth -= 1; + if ($pmonth == 0) { + $pyear -= 1; + $pmonth = 12; + return ($pyear, $pmonth, 0) unless $pyear >= $wikistate{calendar}{minyear}; + } + } + return ($pyear, $pmonth, 1); +} + +sub nextmonth($$$) { + my $year = shift; + my $month = shift; + my $archivebase = shift; + + my $nmonth = $month; + my $nyear = $year; + while ((not exists $pagesources{"$archivebase/$nyear/" . sprintf("%02d", $nmonth)}) or ($nmonth == $month and $nyear == $year)) { + $nmonth += 1; + if ($nmonth == 13) { + $nyear += 1; + $nmonth = 1; + return ($nyear, $nmonth, 0) unless $nyear <= $wikistate{calendar}{maxyear}; + } + } + return ($nyear, $nmonth, 1); +} + +sub previousyear($$) { + my $year = shift; + my $archivebase = shift; + + my $pyear = $year - 1; + while (not exists $pagesources{"$archivebase/$pyear"}) { + $pyear -= 1; + return ($pyear, 0) unless ($pyear >= $wikistate{calendar}{minyear}); + } + return ($pyear, 1); +} + +sub nextyear($$) { + my $year = shift; + my $archivebase = shift; + + my $nyear = $year + 1; + while (not exists $pagesources{"$archivebase/$nyear"}) { + $nyear += 1; + return ($nyear, 0) unless ($nyear <= $wikistate{calendar}{maxyear}); + } + return ($nyear, 1); +} + sub format_month (@) { my %params=@_; @@ -222,25 +304,8 @@ sub format_month (@) { $archivebase = $config{archivebase} if defined $config{archivebase}; $archivebase = $params{archivebase} if defined $params{archivebase}; - my $pmonth = $params{month}; - my $pyear = $params{year}; - while (((not exists $pagesources{"$archivebase/$pyear/" . sprintf("%02d", $pmonth)}) and ($pyear >= $wikistate{calendar}{minyear})) or ($pmonth == $params{month} and $pyear == $params{year})) { - $pmonth -= 1; - if ($pmonth == 0) { - $pyear -= 1; - $pmonth = 12; - } - } - - my $nmonth = $params{month}; - my $nyear = $params{year}; - while (((not exists $pagesources{"$archivebase/$nyear/" . sprintf("%02d", $nmonth)}) and ($nyear <= $wikistate{calendar}{maxyear})) or ($nmonth == $params{month} and $nyear == $params{year})) { - $nmonth += 1; - if ($nmonth == 13) { - $nyear += 1; - $nmonth = 1; - } - } + my ($pyear, $pmonth, $pvalid) = previousmonth($params{year}, $params{month}, $archivebase); + my ($nyear, $nmonth, $nvalid) = nextmonth($params{year}, $params{month}, $archivebase); # Add padding. $pmonth=sprintf("%02d", $pmonth); @@ -427,14 +492,8 @@ sub format_year (@) { $archivebase = $config{archivebase} if defined $config{archivebase}; $archivebase = $params{archivebase} if defined $params{archivebase}; - my $pyear = $params{year} - 1; - while ((not exists $pagesources{"$archivebase/$pyear"}) and ($pyear > $wikistate{calendar}{minyear})) { - $pyear -= 1; - } - my $nyear = $params{year} + 1; - while ((not exists $pagesources{"$archivebase/$nyear"}) and ($nyear < $wikistate{calendar}{maxyear})) { - $nyear += 1; - } + my ($pyear, $pvalid) = previousyear($params{year}, $archivebase); + my ($nyear, $nvalid) = nextyear($params{year}, $archivebase); my $thisyear = $now[5]+1900; my $future_month = 0; @@ -569,6 +628,10 @@ sub preprocess (@) { } $params{month} = sprintf("%02d", $params{month}); + if (not exists $changed{$params{year}}) { + $changed{$params{year}} = (); + } + $changed{$params{year}}{$params{month}} = 1; if ($params{type} eq 'month' && $params{year} == $thisyear && $params{month} == $thismonth) { diff --git a/doc/plugins/calendar.mdwn b/doc/plugins/calendar.mdwn index 5aa20a211..d55c21a62 100644 --- a/doc/plugins/calendar.mdwn +++ b/doc/plugins/calendar.mdwn @@ -19,9 +19,14 @@ pages from templates (overriding the existing ones). * `calendar_fill_gaps` - If set (and `calendar_autocreate` is set as well), build calendar pages of emty years and months (but does not build pages older than the older page, and younger than the younger page of the pagespec). If - not, thoses empty calendar pages will be skipped. *Note:* The archive pages - will not be automatically updated if this option changes. It is up to the - user to delete relevant pages, and rebulid the wiki. + not, thoses empty calendar pages will be skipped. *Please note:* + * The archive pages will not be automatically updated if this option changes. + It is up to the user to delete relevant pages, and rebuild the wiki. + * When `calendar_fill_gaps` is set, and post is deleted, making the + corresponding year/month empty, the corresponding page is left, and shows + an empty calendar. This is on purpose, not to break any external link + pointing to this particular page. If you do not like it, delete the + relevant pages, and rebuild the wiki. ## CSS