Calendar pages are now rebuilt when previous or next page have changed
authorLouis <spalax@gresille.org>
Mon, 7 Jul 2014 12:54:10 +0000 (14:54 +0200)
committerLouis <spalax@gresille.org>
Mon, 7 Jul 2014 13:12:36 +0000 (15:12 +0200)
IkiWiki/Plugin/calendar.pm
doc/plugins/calendar.mdwn

index 185026d202a151bd9b210964491c60b69d6988df..65ed16ed485e6fd08aa5049c6a86e2a1dc93dd53 100644 (file)
@@ -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) {
index 5aa20a211391437a2788e0f9a5a8dd88a111099f..d55c21a62b06e37aebeead1d986dd76b211ce22e 100644 (file)
@@ -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