]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/auto-create_tag_pages_according_to_a_template.mdwn
move the patch into my repository
[ikiwiki.git] / doc / todo / auto-create_tag_pages_according_to_a_template.mdwn
1 It would be great if I could tell ikiwiki to automatically instantiate pages for each [[tag|/tags]], according to a template, especially when `$tagbase` is set.
2
3 Tags are mainly specific to the object to which they’re stuck. However, I often use them the other way around, too: as concepts. And sometimes I’d like to see all pages related to a given concept (“tagged with a given tag”). The only way to do this with ikiwiki is to instantiate a page for each tag and slap a map on it. This is quite tedious and I’d really love to see Ikiwiki do so by default for all tags.
4
5 Also see: <http://madduck.net/blog/2008.01.06:new-blog/> and <http://users.itk.ppke.hu/~cstamas/code/ikiwiki/autocreatetagpage/>
6
7 [[!tag wishlist plugins/tag patch patch/core]]
8
9 I would love to see this as well. -- dato
10
11 ---
12
13 I have create a patch to [[tag.pm|plugins/tag]] for add the option for auto create tag pages.
14 A new setting is used to enable or disable auto-create tag pages, `tag_autocreate`.
15 The new tag file is created during the preprocess phase. 
16 The new tag file is then complied during the change phase.
17
18 *see git history of this page if you want the patch --[[smcv]]*
19
20 This uses a [[template|templates]] called `autotagpage.tmpl`, here is my template file:
21
22     \[[!inline pages="link(<TMPL_VAR TAG>)" archive="yes"]]
23
24
25 A quirk I have not figured out is during the `sub change`, see my comments in the code.
26 I am not sure if that is the best way to handle it.
27
28 [[!tag patch]]
29 -- Jeremy Schultz <jeremy.schultz@uleth.ca>
30
31 No, this doesn't help:
32
33         +       # This refresh/saveindex is to fix the Tags link
34         +       # With out this additional refresh/saveindex the tag link displays ?tag
35         +       IkiWiki::refresh();
36         +       IkiWiki::saveindex();
37
38 On the second extra pass, it doesn't notice that it has to update the "?"-link. If I run ikiwiki once more, it is updated. I don't know yet how this should be fixed, because I don't know the internals of ikiwiki well enough. Something inhibits detecting the need to update in refresh() in Render.pm; perhaps, this condition: 
39
40                 if (! $pagemtime{$page}) {
41                    ...
42                                 push @add, $file;
43                    ...
44                 }
45
46 is not satisfied for the newly created tag page. I shall put debug msgs into Render.pm to find out better how it works. --Ivan Z.
47
48 ---
49
50 I've made another attempt at fixing this
51
52 The current progress can be found at my [git repository][gitweb] on branch
53 `autotag`:
54
55         git://git.liegesta.at/git/ikiwiki
56
57 [gitweb]: http://git.liegesta.at/?p=ikiwiki.git;a=shortlog;h=refs/heads/autotag (gitweb for branch autotag)
58
59 It's not entirely finished yet, but already quite usable. Testing and comments
60 on code quality, implementation details, as well as other patches would be
61 appreciated.
62
63 Here's what it does right now:
64
65 * enabled by setting `tag_autocreate=1` in the configuration.
66 * Tag pages will be created in `tagbase` from the template `autotag.tmpl`.
67 * Will correctly render all links, and dependencies. Well, AFAIK.
68 * When a tag page is deleted it will automatically recreated from template. (I
69 consider this a feature, not a bug)
70 * Requires a rebuild on first use.
71 * Adds a function `add_autofile()` to the plugin API, to do all this.
72
73 Todo/Bugs:
74
75 * Will still create a page even if there's a page other than `$tag` under
76 `tagbase` satisfying the tag link. (details? --[[Joey]])
77 * Call from `IkiWiki.pm` to `Render.pm`, which adds a module dependency in the
78 wrong direction. (fixed --[[Joey]] )
79 * Add files to RCS.
80 * Unit tests.
81 * Proper documentation. (fixed (mostly) --[[Joey]])
82
83 --[[David_Riebenbauer]]
84
85 > Starting review of this. Some of your commits are to very delicate,
86 > optimised, and security-sensitive ground, so I have to look at them very
87 > carefully. --[[Joey]]
88
89 >> First of, sorry that it took me so damn long to answer. I didn't lose
90 >> interest but it took a while for me to find the time and motivation
91 >> to address you suggestions. --[[David_Riebenbauer]]
92
93 > * In the refactoring in [f3abeac919c4736429bd3362af6edf51ede8e7fe][],
94 >   you introduced at least 2 bugs, one a possible security hole.
95 >   Now one part of the code tests `if ($file)` and the other
96 >   caller tests `if ($f)`. These two tests both tested `if (! defined $f)`
97 >   before. Notice that the variable needs to be the untainted variable
98 >   for both. Also notice that `if ($f)` fails if `$f` contains `0`,
99 >   which is a very common perl gotcha.
100 > * Your refactored code changes `-l $_ || -d _` to `-l $file || -d $file`.
101 >   The latter makes one more stat system call; note the use of a
102 >   bare `_` in the first to make perl reuse the stat buffer.
103 > * (As a matter of style, could you put a space after the commas in your
104 >   perl?)
105
106 >> The first two points should be addressed in
107 >> [da5d29f95f6e693e8c14be1b896cf25cf4fdb3c0][]. And sure, I can add the
108 >> spaces. --[[David_Riebenbauer]]
109
110 > I'd like to cherry-pick the above commit, once it's in shape, before
111 > looking at the rest in detail. So just a few other things that stood out.
112
113 > * Commit [4af4d26582f0c2b915d7102fb4a604b176385748][] seems unnecessary.
114 >   `srcfile($file, 1)` already is documented to return undef if the
115 >   file does not exist. (But without the second parameter, it throws
116 >   an error.)
117
118 >> You're right. I must have been some confused by some other promplem I
119 >> introduced then. Reverted. --[[David_Riebenbauer]]
120
121 > * Commit [f58f3e1bec41ccf9316f37b014ce0b373c8e49e1][] adds a line
122 >   that is intented by a space, not a tab.
123
124 >> Sorry, That one was reverted anyway. --[[David_Riebenbauer]]
125
126 > * Commit [f58f3e1bec41ccf9316f37b014ce0b373c8e49e1][] says that auto-added
127 >   files will be recreated if the user deletes them. That seems bad.
128 >   `autoindex` goes to some trouble to not recreate deleted files.
129
130 >> I reverted the commit and addressed the issue in
131 >> [a358d74bef51dae31332ff27e897fe04834571e6][] and
132 >> [981400177d68a279f485727be3f013e68f0bf691][].
133  --[[David_Riebenbauer]]
134
135 >>> This doesn't seem to have all the refinements that autoindex has:
136 >>>
137 >>> * `autoindex` attaches the record of deletions to the `index` page, which
138 >>>   is (nearly) guaranteed to exist; this one attaches the record of
139 >>>   deletions to the deleted page's page state. Won't that tend to result
140 >>>   in losing the record along with the deleted page?
141
142 >>>> This is probably on of the harder things to do, 'cause there are (most of the
143 >>>> time) several pages that are responsible for the creation of a single tag page.
144 >>>> Of course I could attach the info to all of them.
145
146 >>>> With current behaviour I think the information in `%pagestate` is kept around
147 >>>> regardless whether the corresponding page exists or not.
148 >>>> --[[David_Riebenbauer]]
149
150 >>>>> Sorry, I'll try to be clearer: `autoindex` hard-codes that the index page
151 >>>>> of the entire wiki is the one responsible for storing the page state. That
152 >>>>> page isn't responsible for the creation of the tag page, it's just an
153 >>>>> arbitrary page that's (more or less) guaranteed to exist. --[[smcv]]
154
155 >>>>> I don't like that [[plugins/autoindex]] has to do that,
156 >>>>> but `%pagestate` values are only stored for pages that exist,
157 >>>>> so it was necessary. (Another way to look at this is that
158 >>>>> `%pagestate` is not the ideal data structure.) --[[Joey]]
159
160 >>>>>> Aha! Having looked at [[plugins/write]] again, it turns out that what this
161 >>>>>> feature should really use is `%wikistate`, I think? :-) --[[smcv]]
162
163 >>>>>>> Ah, indeed, that came after I wrote autoindex. I've fixed autoindex to
164 >>>>>>> use it. --[[Joey]]
165
166 >>>>> Ok, now I know what you mean. --[[David_Riebenbauer]]
167
168 >>> * `autoindex` forgets that a page was deleted when that page is
169 >>>   re-created
170
171 >>>> Yes, I forgot about that and that is a bug. I'll fix that.
172 >>>> --[[David_Riebenbauer]]
173
174 >>>>> In my branch, it keeps a list of autofiles that were created,
175 >>>>> not deleted. And I think that turns out to be necessary, really.
176 >>>>> However, I see no way to clean out that list on deletion and
177 >>>>> manual recreation -- it still needs to remember it was once an autofile,
178 >>>>> in order to avoid recreating it if it's deleted yet again. --[[Joey]]
179
180 >>>>>> Are these really the semantics we want? It seems strange to me
181 >>>>>> that this:
182 >>>>>>
183 >>>>>> * tag a page as foo
184 >>>>>> * tags/foo automatically appears
185 >>>>>> * delete tags/foo
186 >>>>>> * create tags/foo manually
187 >>>>>> * delete tags/foo again
188 >>>>>> * tags/foo isn't automatically created
189 >>>>>>
190 >>>>>> isn't the same as this:
191 >>>>>>
192 >>>>>> * create tags/foo
193 >>>>>> * delete tags/foo
194 >>>>>> * tag a page as foo
195 >>>>>> * tags/foo automatically appears
196 >>>>>>
197 >>>>>> or even this:
198 >>>>>>
199 >>>>>> * create tags/foo
200 >>>>>> * tag a page as foo
201 >>>>>> * delete tags/foo
202 >>>>>> * tags/foo automatically appears (?)
203 >>>>>>
204 >>>>>> --[[smcv]]
205
206 >>>>>>> I agree that the last of these is not desired. It could be avoided
207 >>>>>>> by extending the list of autofiles to include those that were not
208 >>>>>>> created due to the file/page already existing.
209 >>>>>>> 
210 >>>>>>> Hmm, that would fix the previous scenario too. --[[Joey]] 
211
212 >>> * `autoindex` forgets that a page was deleted when it's no longer needed
213 >>>   anyway (this may be harder for `autotag`?)
214
215 >>>> I don't think so. AFAIK ikiwiki can detect whether there are taglinks to a page
216 >>>> anyway, so it should be quite easy. I'll try to implement that too.
217 >>>> --[[David_Riebenbauer]]
218
219 >>> It'd probably be an interesting test of the core change to port
220 >>> `autoindex` to use it? (Adding the file to the RCS would be
221 >>> necessary to get parity with `autoindex`.) --[[smcv]]
222
223 >>>> Good suggestion. Adding the files to RCS is on my todo list anyway.
224 >>>> --[[David_Riebenbauer]]
225
226 >>>>> I think it may be better to allow the `add_autofile` caller
227 >>>>> to specify if it is added to RCS. In my branch, it can do
228 >>>>> so by just making the callback it registers call `rcs_add`; 
229 >>>>> and I have tag do this. Other plugins might want autofiles
230 >>>>> that do not get checked in, conceivably.
231 >>>>> --[[Joey]] 
232
233 > Regarding the call from `IkiWiki.pm` to `Render.pm`, wouldn't this be
234 > quite easy to solve by moving `verify_src_file` to IkiWiki.pm? --[[smcv]]
235
236 >> True. I'll do that. --[[David_Riebenbauer]]
237 >> Fixed in my branch --[[Joey]]
238
239 [[!template id=gitbranch branch=origin/autotag author="[[Joey]]"]]
240 I've pushed an autotag branch of my own, which refactors
241 things a bit and fixes bugs around deletion/recreation.
242 I've tested it fairly thouroughly. --[[Joey]]
243
244 [f3abeac919c4736429bd3362af6edf51ede8e7fe]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=f3abeac919c4736429bd3362af6edf51ede8e7fe (commitdiff for f3abeac919c4736429bd3362af6edf51ede8e7fe)
245 [4af4d26582f0c2b915d7102fb4a604b176385748]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=4af4d26582f0c2b915d7102fb4a604b176385748 (commitdiff for 4af4d26582f0c2b915d7102fb4a604b176385748)
246 [f58f3e1bec41ccf9316f37b014ce0b373c8e49e1]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=f58f3e1bec41ccf9316f37b014ce0b373c8e49e1 (commitdiff for f58f3e1bec41ccf9316f37b014ce0b373c8e49e1)
247 [da5d29f95f6e693e8c14be1b896cf25cf4fdb3c0]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=da5d29f95f6e693e8c14be1b896cf25cf4fdb3c0 (commitdiff for da5d29f95f6e693e8c14be1b896cf25cf4fdb3c0)
248 [a358d74bef51dae31332ff27e897fe04834571e6]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=a358d74bef51dae31332ff27e897fe04834571e6 (commitdiff for a358d74bef51dae31332ff27e897fe04834571e6)
249 [981400177d68a279f485727be3f013e68f0bf691]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=981400177d68a279f485727be3f013e68f0bf691 (commitdiff for 981400177d68a279f485727be3f013e68f0bf691)
250
251 -------------------
252
253 Even if this is already marked as done, I'd like to suggest an alternative
254 solution:
255
256 Instead of creating a file that gets checked in into the RCS, the source files
257 could be left out and the output files be written as long as there is no
258 physical source file (think of a virtual underlay). Something similar would be
259 required to implement [[todo/alias directive]], which couldn't be easily done
260 by writing to the RCS as the page's contents can change depending on which
261 other pages claim it as an alias. --[[chrysn]]
262
263 I agree with [[chrysn]]. In fact, is there any good reason that the core tag
264 plugin doesn't do this? The current usability is horrible, to the point that
265 I have gone 2.5 years with Ikiwiki and haven't yet started using tags.
266 --[Eric](http://wiki.pdxhub.org/people/eric)
267
268 > See [[todo/transient_pages]] for progress on this. --[[smcv]]
269
270 [[!tag done]]