Merge branch 'master' of ssh://git.ikiwiki.info
[ikiwiki] / doc / bugs / trail_excess_dependencies.mdwn
1 I've just modified the trail plugin to use only presence, and not
2 content dependencies. Using content dependencies, particularly to the page
3 that defines the trail, meant that every time that page changed, *every*
4 page in the trail gets rebuilt. This leads to users setting up sites that
5 have horrible performance, if the trail is defined in, for example, the top
6 page of a blog.
7
8 Unfortunatly, this change to presence dependencies has
9 introduced a bug. Now when an existing trail is removed, the pages in the
10 trail don't get rebuilt to remove the trail (both html display and state).
11
12 > Actually, this particular case is usually OK. Suppose a trail `untrail`
13 > contains `untrail/a` (as is the case in the regression
14 > test I'm writing), and you build the wiki, then edit `untrail` to no
15 > longer be a trail, and refresh. `untrail` has changed, so it is
16 > rendered. Assuming that the template of either `untrail` or another
17 > changed page happens to contain the `TRAILS` variable (which is not
18 > guaranteed, but is highly likely), `I::P::t::prerender`
19 > is invoked. It notices that `untrail/a` was previously a trail
20 > member and is no longer, and rebuilds it with the diagnostic
21 > "building untrail/a, its previous or next page has changed".
22
23 > Strictly speaking, I should change `I::P::t::build_affected`
24 > so it calls `prerender`, so we're guaranteed to have done the
25 > recalculation. Fixed in my branch. --[[smcv]]
26
27 I think that to fix this bug, the plugin should use a hook to 
28 force rebuilding of all the pages that were in the trail, when
29 the trail is removed (or changed).
30
31 > The case of "the trail is changed" is still broken:
32 > if the order of items changes, or the trail is removed,
33 > then the logic above means it's OK, but if you
34 > change the `\[[!meta title]]` of the trail, or anything else
35 > used in the prev/up/next bar, the items won't show that
36 > change. Fixed in my branch. --[[smcv]]
37
38 There's a difficulty in doing that: The needsbuild hook runs before the scan
39 hook, so before it has a chance to see if the trail directive is still there.
40 It'd need some changes to ikiwiki's hooks.
41
42 > That's what `build_affected` is for, and trail already used it. --s
43
44 (An improvement in this area would probably simplify other plugins, which
45 currently abuse the needsbuild hook to unset state, to handle the case
46 where the directive that resulted in that state is removed.)
47
48 I apologise for introducing a known bug, but the dependency mess was too
49 bad to leave as-is. And I have very little time (and regrettably, even less
50 power) to deal with it right now. :( --[[Joey]] 
51
52 [[!template id=gitbranch branch=smcv/ready/trail author="[[Simon_McVittie|smcv]]"]]
53 [[!tag patch]]
54
55 > I believe my `ready/trail` branch fixes this. There are regression tests.
56 >
57 > Here is an analysis of how the trail pages interdepend.
58 >
59 > * If *trail* contains a page *member* which does exist, *member* depends
60 >   on *trail*. This is so that if the trail directive is deleted from
61 >   *trail*, or if *trail*'s "friendly" title or trail settings are changed,
62 >   the trail navigation bar in *member* will pick up that change. This is
63 >   now only a presence dependency, which isn't enough to make those happen
64 >   correctly. [Edited to add: actually, the title is the only thing that
65 >   can affect *member* without affecting the order of members.]
66 >
67 > * If *trail* contains consecutive pages *m1* and *m2* in that order,
68 >   *m1* and *m2* depend on each other. This is so that if one's
69 >   "friendly" title changes, the other is rebuilt. This is now only
70 >   a presence dependency, which isn't enough to make those happen
71 >   correctly. In my branch, I explicitly track the "friendly" title
72 >   for every page that's edited and is involved in a trail somehow.
73 >
74 > * If *trail* has *member* in its `pagenames` but there is no page called
75 >   *member*, then *trail* must be rebuilt if *member* is created. This
76 >   was always a presence dependency, and is fine.
77 >
78 > In addition, the `trail` plugin remembers the maps
79 > { trail => next item in that trail } and { trail => previous item in
80 > that trail } for each page. If either changes, the page gets rebuilt
81 > by `build_affected`, with almost the same logic as is used to update
82 > pages that link to a changed page. My branch extends this to track the
83 > "friendly title" of each page involved in a trail, either by being
84 > the trail itself or a member (or both).
85 >
86 > I think it's true to say that the trail always depends on every member,
87 > even if it doesn't display them. This might mean that we can use
88 > "render the trail page" as an opportunity to work out whether any of
89 > its members are also going to need re-rendering?
90 > [Edited to add: actually, I didn't need this to be true, but I made the
91 > regression test check it anyway.]
92 >
93 > --[[smcv]]
94
95 >>> Thanks **very** much! [[done]] --[[Joey]]