]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/flexible_relationships_between_pages.mdwn
wishlist: ask about using ikiwiki as ML
[ikiwiki.git] / doc / todo / flexible_relationships_between_pages.mdwn
1 it has been some years since the [[matching different kinds of links]] issue
2 was tackled, but hardly a plugin is using it.
3
4 in order to enhance on the [[todo/rel attribute for links]] and [[todo/better bug tracking support]]
5 issues and to provide a more general infrastructure, i'd like to propose a
6 generic plugin for typed links. it can be also viewed of a way to have
7 [[todo/structured page data]] that consists of URLs inside the wiki.
8
9 following the use case i've developed it for, i'll call it `blocks` for the
10 moment (but am open to better suggestions).
11
12 outline
13 =======
14
15 the plugin has a **configuration option** called `blocks_names`, which consists
16 of pairs of verbs; the typical example is `blocks/blockedby`, but other values
17 could be `next/prev up/down` or `owner/owns`.
18
19 for each verb in the options, there is a **directive** which is used to state
20 the relationship; relationships can be declared on both ends, so a page `bugA`
21 with the contents `\[[!blocks bugB]]` is semantically equivalent to a page
22 `bugB` with the contents `\[[!blockedby bugA]]`.
23
24 for each verb, there is also a **pagespec** which matches all pages that are
25 the origin of a relationship to a given page. if `developerA` `\[[!owns
26 bug1]]`, then if `bug1` contains `\[[!map pages="owns(.)"]]`, it will show the
27 owning developer. these specs match both ways, ie. if `bug1` `\[[!owner
28 developerA]]`, the said map directive will still produce the same result.
29
30 details
31 =======
32
33 * single word relationships vs. symmetric relationships
34
35   with some verbs, it is possible that a relationship is only used in one
36   direction (eg `index`, even though one could declare it as
37   `index/isindexof`).
38
39   > isindexof is not a very interesting relationship - it just clogs up
40   > the link-map, since the index is "the index of" all pages. I can't
41   > see any situation in which you'd want to do pagespec matching
42   > on it? --[[smcv]]
43
44   >> that's why i used `index` as an example of a one-direction relationship.
45   >>
46   >> it wouldn't clog up the link map, though: in order to cleanly match both
47   >> directions, when the "inverse" term of a relationship is used, the link in
48   >> taggedlinks uses the "forward" term, but switches the objects.
49   >>
50   >> --[[chrysn]]
51
52   other verbs are symmetric, eg. `equivalent`, which need different treatment.
53
54 * "taglink" style directives
55
56   the [[plugins/tag]] plugin would be a special case for this plugin (apart
57   from the autotag and tagdir features). as there is a `\[[!taglink ...]]`
58   directive, there could be an analogous directive for every single directive.
59
60   > This is basically the traillink/trailitem duality, too.
61   > I'd be quite tempted to generalize to something like this:
62   >
63   >     We can't fix [[!link blocks="bug123" text="Bug 123"]] until we do this.
64   >
65   >     [[!hiddenlink owner="smcv"]]
66   >
67   > but perhaps that's too wordy?
68   >
69   > I think both trail and tag need their own special processing beyond the
70   > general case, but maybe not? --[[smcv]]
71
72   >> i'd be all in favor of having this unified and deeper; there has been the
73   >> idea of a `\[[!link]]` directive [[again|todo/link plugin perhaps too general__63__]]
74   >> and [[again|todo/do not make links backwards]].
75   >>
76   >> i like the `\[[!link text=""]]` and `[[!hiddenlink]]` conventions, but
77   >> think that ${REL}="${TARGET}" isn't ideal because it implies that a single
78   >> link can have more than one target. instead, i'd go for
79   >> `\[[!link to="bug123" rel="blocks" text="Bug 123"]]; as with the html rel
80   >> parameter, rel would be a list of whitespace separated values.
81   >>
82   >> positional parameters (`\[[!link bug123 rel="blocks" text="Bug 123"]]` or
83   >> even `\[[!link Bug 123|bug123 rel="blocks"]]`) would be possible, but i
84   >> prefer explicit syntax and not joining stings back again with the
85   >> whitespace that was split off it before.
86   >>
87   >> if the '|' character is not widespread in page names (which i assume it is
88   >> not), instead of using positional parameters in `\[[!link]]` for
89   >> shortcuts, we could extend the regular link syntax; the same relationship
90   >> could then be declared as `\[[Bug 123|bug123|blocks]]`; this would be an
91   >> easy extension to the original link syntax. it would even work for hidden links
92   >> (`\[[|smcv|owner]]`), which previously made no sense because a link with
93   >> neither a physicial representation nor metadat is of no use.
94   >>
95   >> --[[chrysn]]
96
97 * implementation notes
98
99   the way pagespec hooks are implemented required some nasty perl tricks, for
100   which the people who showed me felt very bad for having spoilt me. indeed,
101   `no strict refs;` and `*$forward_name = $forward_match;` are not exactly
102   ideal. a change in the pagespec declaration api (why not just `hook` like
103   everything else) would make the implementation cleaner.
104
105   > How about replacing `blockedby(bug*)` with `linktype(blockedby bug*)` or
106   > something? Then you'd only need one pseudo-hook. --[[smcv]]
107
108   >> there has been the topic of pagespecs like `typedlink(type glob)` back in
109   >> the [[matching different kinds of links]] discussion, but it was removed
110   >> in favor of per-type matchers. --[[chrysn]]
111
112   >>> note to self: should use the ``inject`` function to avoid `no strict refs`. --[[chrysn]]
113
114 * configuration location
115
116   i aimed for static configuration of the `block_names` in the setup file. this
117   could be made more general like in the [[plugins/shortcut]] plugin, but that
118   would make things more complex.
119
120 * no html links with `rel=` yet
121
122   as there are no taglink style links between the articles so far, no htmllink
123   gets rendered that could carry the relationship name in its rel field.
124
125   having the inverse relationship description in backlinks (as in the link
126   created by the map directive in the example above) would be hard to
127   implement. (actually, i think it'd be easier to determine the rel values from
128   the taggedlinks for *every* htmllink than to influence the backlinks in this
129   plugin).
130
131 * one direction also creates a normal link
132
133   due to the way add\_link treats relationships, the forward relationship is
134   always going to be reflected in the links/backlinks. a section of
135   [[todo/matching different kinds of links]] was dismissed with "let's not
136   worry about it", this plugin might be reason to worry about it again. (i'd
137   consider what is in @links to be a representation of which hyperlinks are
138   there, and in this case, none are generated).
139
140   > taglink and traillink already count as wikilinks without generating
141   > any visible HTML. --[[smcv]]
142
143 implementation
144 ==============
145
146 there is a working but slightly incomplete (basically where it comes to the
147 details mentioned above) implementation in [[blocks.pm]].
148
149 --[[chrysn]]