X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/83876a7da67cab7c76a4754f750e39f32e5702e4..795faec9c5f0b0036dd27c0c6d32e74e397b2f9a:/IkiWiki/Plugin/trail.pm diff --git a/IkiWiki/Plugin/trail.pm b/IkiWiki/Plugin/trail.pm index 330d2a31d..429f742ac 100644 --- a/IkiWiki/Plugin/trail.pm +++ b/IkiWiki/Plugin/trail.pm @@ -26,10 +26,12 @@ sub import { # # * $pagestate{$T}{trail}{contents} # Reference to an array of lists each containing either: -# - [link, "link"] +# - [pagenames => "page1", "page2"] +# Those literal pages +# - [link => "link"] # A link specification, pointing to the same page that [[link]] # would select -# - [pagespec, "posts/*", "age", 0] +# - [pagespec => "posts/*", "age", 0] # A match by pagespec; the third array element is the sort order # and the fourth is whether to reverse sorting # @@ -60,12 +62,20 @@ sub getsetup () { }, } +# Cache of pages' old titles, so we can tell whether they changed +my %old_trail_titles; + sub needsbuild (@) { my $needsbuild=shift; + foreach my $page (keys %pagestate) { if (exists $pagestate{$page}{trail}) { if (exists $pagesources{$page} && grep { $_ eq $pagesources{$page} } @$needsbuild) { + # Remember its title, so we can know whether + # it changed. + $old_trail_titles{$page} = title_of($page); + # Remove state, it will be re-added # if the preprocessor directive is still # there during the rebuild. {item} is the @@ -76,6 +86,7 @@ sub needsbuild (@) { } } } + return $needsbuild; } @@ -148,8 +159,8 @@ sub preprocess_trailitems (@) { } if (exists $params{pagenames}) { - my @list = map { [link => $_] } split ' ', $params{pagenames}; - push @{$pagestate{$params{page}}{trail}{contents}}, @list; + push @{$pagestate{$params{page}}{trail}{contents}}, + [pagenames => (split ' ', $params{pagenames})]; } return ""; @@ -217,6 +228,7 @@ my %trail_to_members; # trail2 => ["member0", undef], # } my %member_to_trails; +my %up_in_trail; # member => 1 my %rebuild_trail_members; @@ -228,6 +240,12 @@ sub trails_differ { if (! exists $new->{$trail}) { return 1; } + + if (exists $old_trail_titles{$trail} && + title_of($trail) ne $old_trail_titles{$trail}) { + return 1; + } + my ($old_p, $old_n) = @{$old->{$trail}}; my ($new_p, $new_n) = @{$new->{$trail}}; $old_p = "" unless defined $old_p; @@ -237,9 +255,20 @@ sub trails_differ { if ($old_p ne $new_p) { return 1; } + + if (exists $old_trail_titles{$old_p} && + title_of($old_p) ne $old_trail_titles{$old_p}) { + return 1; + } + if ($old_n ne $new_n) { return 1; } + + if (exists $old_trail_titles{$old_n} && + title_of($old_n) ne $old_trail_titles{$old_n}) { + return 1; + } } foreach my $trail (keys %$new) { @@ -263,6 +292,7 @@ sub prerender { next unless exists $pagestate{$trail}{trail}{contents}; my $members = []; + my $up_in_trail = 0; my @contents = @{$pagestate{$trail}{trail}{contents}}; foreach my $c (@contents) { @@ -271,6 +301,19 @@ sub prerender { $c->[1], sort => $c->[2], reverse => $c->[3]); } + elsif ($c->[0] eq 'pagenames') { + my @pagenames = @$c; + shift @pagenames; + foreach my $page (@pagenames) { + if (exists $pagesources{$page}) { + push @$members, $page; + } + else { + # rebuild trail if it turns up + add_depends($trail, $page, deptype("presence")); + } + } + } elsif ($c->[0] eq 'link') { my $best = bestlink($trail, $c->[1]); push @$members, $best if length $best; @@ -288,11 +331,14 @@ sub prerender { @$members = reverse @$members; } + + # uniquify my %seen; my @tmp; foreach my $member (@$members) { push @tmp, $member unless $seen{$member}; + $up_in_trail = 1 if $member eq $trail; $seen{$member} = 1; } $members = [@tmp]; @@ -303,8 +349,6 @@ sub prerender { $prev = $members->[$i - 1] if $i > 0; my $next = $members->[$i + 1]; - add_depends($member, $trail); - $member_to_trails{$member}{$trail} = [$prev, $next]; } @@ -314,13 +358,14 @@ sub prerender { } $trail_to_members{$trail} = $members; + $up_in_trail{$trail} = $up_in_trail; } foreach my $member (keys %pagestate) { if (exists $pagestate{$member}{trail}{item} && ! exists $member_to_trails{$member}) { $rebuild_trail_members{$member} = 1; - delete $pagestate{$member}{trailitem}; + delete $pagestate{$member}{trail}{item}; } } @@ -344,6 +389,12 @@ sub prerender { sub build_affected { my %affected; + # In principle we might not have done this yet, although in practice + # at least the trail itself has probably changed, and its template + # almost certainly contains TRAILS or TRAILLOOP, triggering our + # prerender as a side-effect. + prerender(); + foreach my $member (keys %rebuild_trail_members) { $affected{$member} = sprintf(gettext("building %s, its previous or next page has changed"), $member); } @@ -366,6 +417,8 @@ sub pagetemplate (@) { my $page = $params{page}; my $template = $params{template}; + return unless length $page; + if ($template->query(name => 'trails') && ! $recursive) { prerender(); @@ -391,28 +444,35 @@ sub pagetemplate (@) { my ($prevurl, $nexturl, $prevtitle, $nexttitle); if (defined $prev) { - add_depends($params{destpage}, $prev); $prevurl = urlto($prev, $page); $prevtitle = title_of($prev); } if (defined $next) { - add_depends($params{destpage}, $next); $nexturl = urlto($next, $page); $nexttitle = title_of($next); } - push @trails, { + my %trail_info = ( prevpage => $prev, prevtitle => $prevtitle, prevurl => $prevurl, nextpage => $next, nexttitle => $nexttitle, nexturl => $nexturl, - trailpage => $trail, - trailtitle => title_of($trail), - trailurl => urlto($trail, $page), + ); + + # the trail index is added as 'up' page, but only if it's + # not a page in the trail itself. This allows the definition of + # up-less trails by using e.g. the trailitems directive in one of the + # pages of the trail + unless ($up_in_trail{$trail}) { + $trail_info{trailpage} = $trail; + $trail_info{trailtitle} = title_of($trail); + $trail_info{trailurl} = urlto($trail, $page); }; + + push @trails, \%trail_info; } $template->param(trailloop => \@trails);