Add a build_affected hook so trail doesn't have to inject
authorSimon McVittie <smcv@debian.org>
Sun, 18 Mar 2012 17:34:39 +0000 (17:34 +0000)
committerSimon McVittie <smcv@debian.org>
Sun, 18 Mar 2012 17:34:39 +0000 (17:34 +0000)
In principle, building any pages affected by links, backlinks etc.
could work the same way.

IkiWiki/Plugin/trail.pm
IkiWiki/Render.pm
doc/plugins/write.mdwn

index 4f309ea2ec68d47ecea074a879b4ff3669e4c38e..29830175e31c315800e236d8677729d8d41405f1 100644 (file)
@@ -17,6 +17,7 @@ sub import {
        hook(type => "preprocess", id => "trailitems", call => \&preprocess_trailitems, scan => 1);
        hook(type => "preprocess", id => "traillink", call => \&preprocess_traillink, scan => 1);
        hook(type => "pagetemplate", id => "trail", call => \&pagetemplate);
        hook(type => "preprocess", id => "trailitems", call => \&preprocess_trailitems, scan => 1);
        hook(type => "preprocess", id => "traillink", call => \&preprocess_traillink, scan => 1);
        hook(type => "pagetemplate", id => "trail", call => \&pagetemplate);
+       hook(type => "build_affected", id => "trail", call => \&build_affected);
 }
 
 =head1 Page state
 }
 
 =head1 Page state
@@ -275,14 +276,9 @@ sub trails_differ {
 
 my $done_prerender = 0;
 
 
 my $done_prerender = 0;
 
-my %origsubs;
-
 sub prerender {
        return if $done_prerender;
 
 sub prerender {
        return if $done_prerender;
 
-       $origsubs{render_backlinks} = \&IkiWiki::render_backlinks;
-       inject(name => "IkiWiki::render_backlinks", call => \&render_backlinks);
-
        %trail_to_members = ();
        %member_to_trails = ();
 
        %trail_to_members = ();
        %member_to_trails = ();
 
@@ -368,18 +364,14 @@ sub prerender {
        $done_prerender = 1;
 }
 
        $done_prerender = 1;
 }
 
-# This is called at about the right time that we can hijack it to render
-# extra pages.
-sub render_backlinks ($) {
-       my $blc = shift;
+sub build_affected {
+       my %affected;
 
        foreach my $member (keys %rebuild_trail_members) {
 
        foreach my $member (keys %rebuild_trail_members) {
-               next unless exists $pagesources{$member};
-
-               IkiWiki::render($pagesources{$member}, sprintf(gettext("building %s, its previous or next page has changed"), $member));
+               $affected{$member} = sprintf(gettext("building %s, its previous or next page has changed"), $member);
        }
 
        }
 
-       $origsubs{render_backlinks}($blc);
+       return %affected;
 }
 
 sub title_of ($) {
 }
 
 sub title_of ($) {
index 05132a8a81560a3ce0039b748ce0458d5742ad53..adb39a983475cd6107335c66568e4e4c87acb752 100644 (file)
@@ -800,6 +800,14 @@ sub refresh () {
                derender_internal($file);
        }
 
                derender_internal($file);
        }
 
+       run_hooks(build_affected => sub {
+               my %affected = shift->();
+               while (my ($page, $message) = each %affected) {
+                       next unless exists $pagesources{$page};
+                       render($pagesources{$page}, $message);
+               }
+       });
+
        my ($backlinkchanged, $linkchangers)=calculate_changed_links($changed,
                $del, $oldlink_targets);
 
        my ($backlinkchanged, $linkchangers)=calculate_changed_links($changed,
                $del, $oldlink_targets);
 
index dcab041dc285b0ae9214a629c692d1f8e747b7d9..d62ab6e63f21dcc4f1c026f5751ca7403755dcfd 100644 (file)
@@ -356,6 +356,22 @@ when the page is being previewed.)
 The function is passed named parameters: "page" and "content", and 
 should return the formatted content.
 
 The function is passed named parameters: "page" and "content", and 
 should return the formatted content.
 
+### build_affected
+
+       hook(type => "build_affected", id => "foo", call => \&build_affected);
+
+This hook is called after the directly changed pages have been built,
+and can cause extra pages to be built. If links and backlinks were provided
+by a plugin, this would be where that plugin would rebuild pages whose
+backlinks have changed, for instance. The [[trail]] plugin uses this hook
+to rebuild pages whose next or previous page has changed.
+
+The function should currently ignore its parameters. It returns a list with
+an even number of items (a hash in list context), where the first item of
+each pair is a page name to be rebuilt (if it was not already rebuilt), and
+the second is a log message resembling
+`building plugins/write because the phase of the moon has changed`.
+
 ### delete
 
        hook(type => "delete", id => "foo", call => \&delete);
 ### delete
 
        hook(type => "delete", id => "foo", call => \&delete);