abe5d5683987ad403c11dd2d40d3309b023b3556
[ikiwiki.git] / doc / bugs / listdirectives_doesn__39__t_register_a_link.mdwn
1 The [[ikiwiki/directive/listdirectives]]` directive doesn't register a link between the page and the subpages. This is a problem because then the [[ikiwiki/directive/orphans]] directive then marks the directives as orphans... Maybe it is a but with the orphans directive however... A simple workaround is to exclude those files from the orphans call... --[[anarcat]]
2
3 > There's a distinction between wikilinks (matched by `link()`,
4 > `backlink()` etc.) and other constructs that produce a
5 > hyperlink. Some directives count as a wikilink (like `tag`)
6 > but many don't (notably `inline`, `map`, `listdirectives`,
7 > and `orphans` itself). As documented in
8 > [[ikiwiki/directive/orphans]], orphans will tend to list
9 > pages that are only matched by inlines/maps, too.
10 >
11 > The rule of thumb seems to be that a link to a particular
12 > page counts as a wikilink, but a directive that lists
13 > pages matching some pattern does not; so I think
14 > `listdirectives` is working as intended here.
15 > `orphans` itself obviously shouldn't count as a wikilink,
16 > because that would defeat the point of it :-)
17 >
18 > Anything that uses a [[ikiwiki/pagespec]] to generate links,
19 > like `inline` and `map`, can't generate wikilinks, because
20 > wikilinks are gathered during the scan phase, and pagespecs
21 > can't be matched until after the scan phase has finished
22 > (otherwise, it'd be non-deterministic whether all wikilinks
23 > had been seen yet, and `link()` in pagespecs wouldn't work
24 > predictably).
25 >
26 > I suggest just using something like:
27 >
28 >     \[[!orphans pages="* and !blog/* and !ikiwiki/directive/*"]]
29 >
30 > This wiki's example of listing [[plugins/orphans]] has a
31 > more elaborate pagespec, which avoids bugs, todo items etc.
32 > as well.
33 >
34 > --[[smcv]]
35
36 > No follow-up or objection for a while, so considering this to
37 > be working as designed. --[[smcv]]
38
39 > > Seems I'm a bit late to butt in, but would it be possible to have two
40 > > further phases after the scan phase, the first running map and inline 
41 > > and the second orphan? Then map and inline could log or register their 
42 > > links (obviously somewhere were it won't change the result of the link function)
43 > > and orphan could take them into account. This logging could be
44 > > turned on by parameter to not waste time for users not needing this and 
45 > > make it tunable (i.e. so that the user can decide which map directives count and which don't)
46 > > 
47 > > For someone using map and especially autoindex the output of the orphans directive
48 > > is simply wrong/useless (at least it is for me). And there is no easy workaround like for listdirectives
49 > > -- [[holger]]
50
51 >>> Hmm. I think this can be done without introducing any "phases",
52 >>> even, but it would require each plugin that generates links according
53 >>> to a pagespec to have either a conditional call into the orphans plugin,
54 >>> or a call to a new core function in ikiwiki that exists solely to
55 >>> support the orphans plugin. Something like this, maybe:
56 >>>
57 >>>     # in map.pm, inline.pm, pagestats.pm etc., at scan time
58 >>>     if (IkiWiki::Plugin::orphans->can("add_reachable")) {
59 >>>         IkiWiki::Plugin::orphans::add_reachable($page, $pagespec);
60 >>>     }
61 >>>
62 >>>     # in orphans.pm (pseudocode; note that this does not *evaluate*
63 >>>     # $pagespec, only stores it, so it's OK to do this at scan time)
64 >>>     sub needsbuild ($pages)
65 >>>         for each page in $pages
66 >>>             clear $pagestate{location}{orphans}{reachable}
67 >>>     sub reachable ($location, $pagespec)
68 >>>         add $pagespec to @{$pagestate{location}{orphans}{reachable}}
69 >>>
70 >>>     # in preprocess function in orphans.pm (pseudocode)
71 >>>     # executed at build time, not at scan time, so pagespecs work
72 >>>
73 >>>     for each maybe_orphan with no links to it
74 >>>         for each location with a list of reachable pagespecs
75 >>>             make the page with the orphans directive depend on \
76 >>>                 the page that is the location
77 >>>             for each of those pagespecs
78 >>>                 if pagespec matches orphan
79 >>>                     take orphan off the list
80 >>>                     go to next orphan
81 >>>     output list of orphans
82 >>>
83 >>> (Maybe parentlinks should also annotate the parent/ancestors of
84 >>> each page as reachable from that page.)
85 >>>
86 >>> Do other people (mainly Joey) think that'd be acceptable, or
87 >>> too intrusive?
88 >>>
89 >>> Taking this off the list of resolved bugs again while we think about it.
90 >>>
91 >>> I suspect that in the presence of autoindex, what you really want might
92 >>> be less "there's a link to it" and more "there's a path to it from
93 >>> the root of the wiki", which is why I called the proposed function
94 >>> "add_reachable". On the other hand, maybe that's too computationally
95 >>> intensive to actually do; I haven't tried it.
96 >>> --[[smcv]]
97 >>>> 
98 >>>> (I'll interpet Joeys silence as a good sign ;-). Is there a difference between "link to it" and "path to it"? If we assume autoindex produces bonafide "first class" links there shouldn't be one!?
99 >>>>
100 >>>> So far your idea sounds great, says me without any knowledge of the source. I'll try to grok it. Is there a medium for silly questions, a wiki seems not the right fit for that? -- [[holger]]
101 >>>>> Yes, there *has* to be a difference between a first class wikilink
102 >>>>> and the thing to which `map` and `inline` can contribute.
103 >>>>> `map` and `inline` use a pagespec to decide what they include,
104 >>>>> and pagespecs can't be evaluated and get a correct answer until the
105 >>>>> set of links has been collected, because their results often depend
106 >>>>> on the set of links. Otherwise, suppose you had a page `foo` whose only
107 >>>>> contents were this:
108 >>>>>
109 >>>>>     \[[!inline pages="!backlink(foo)"]]
110 >>>>>
111 >>>>> If `inline` generated links, it would inline exactly those pages that
112 >>>>> it doesn't inline. That's never going to end well :-) --[[smcv]]
113 >>>>>> We have to differentiate between what users of ikiwiki consider first class links and what internally is happening. For the user any link contributing to the structured access tree is first class. The code on the other hand has to differentiate between the static links, then generated links, then orphan links. Three "passes", even your proposed solution could be seen as adding another pass since the orphan plugin has to run after all the plugins generating (first class user) links.   -- [[holger]]
114
115 >>>>>>> I think the difference between your point of view, and what ikiwiki
116 >>>>>>> currently implements / what its design is geared towards, is this:
117 >>>>>>> ikiwiki says A links to B if the *source code* of A contains an
118 >>>>>>> explicit link to B. You say A links to B if the *compiled HTML*
119 >>>>>>> of A contains a link to B.
120 >>>>>>>
121 >>>>>>> Would you agree with that characterization?
122 >>>>>>>
123 >>>>>>> I suspect that "link in the source code" may be the more useful concept
124 >>>>>>> when using links for backlinks (I think the original implementation is
125 >>>>>>> <http://c2.com/cgi/wiki?BackLink>) and as pseudo-tags
126 >>>>>>> (<http://c2.com/cgi/wiki?WikiCategories>). The fact that this is what
127 >>>>>>> `link()` and `backlink()` mean could be better-documented: it's
128 >>>>>>> entirely possible that the author of their documentation (Joey?)
129 >>>>>>> thought it was obvious that that's what they mean, because they
130 >>>>>>> were coming from a compiler/source-code mindset.
131 >>>>>>>
132 >>>>>>> Also, backlinks become rather all-engulfing if their presence in
133 >>>>>>> the compiled output counts as a link, since after a render pass, they
134 >>>>>>> would all become bidirectional; and as I noted previously, if pagespecs
135 >>>>>>> can match by linkedness (which we want) and plugins can generate lists
136 >>>>>>> of links according to pagespecs (which we also want), then links in the
137 >>>>>>> compiled output can certainly get into [[!wp Russell's paradox]]-like
138 >>>>>>> situations, such as the page that links to every page to which it
139 >>>>>>> does not link.
140 >>>>>>>
141 >>>>>>> For the special case of deciding what is orphaned, sure, it's the
142 >>>>>>> compiled HTML that is the more relevant thing;
143 >>>>>>> that's why I talked about "reachability" rather than "links".
144 >>>>>>>
145 >>>>>>> --[[smcv]]