also tag 'patch/core', considering that over half of the changes are there
[ikiwiki] / 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 _tag.pm from version 3.01_
19
20
21         --- tag.pm      2009-02-06 10:26:03.000000000 -0700
22         +++ tag_new.pm  2009-02-06 12:17:19.000000000 -0700
23         @@ -14,6 +14,7 @@
24                         hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
25                         hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
26                         hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
27         +       hook(type => "change", id => "tag", call => \&change);
28          }
29          
30          sub getopt () {
31         @@ -36,6 +37,36 @@
32                                                         safe => 1,
33                                                         rebuild => 1,
34                                         },
35         +               tag_autocreate => {
36         +                       type => "boolean",
37         +                       example => 0,
38         +                       description => "Auto-create the new tag pages, uses autotagpage.tmpl ",
39         +                       safe => 1,
40         +                       rebulid => 1,
41         +               },
42         +}
43         +
44         +my $autocreated_page = 0;
45         +
46         +sub gen_tag_page($)    {
47         +       my $tag=shift;
48         +
49         +       my $tag_file=$tag.'.'.$config{default_pageext};
50         +       return if (-f $config{srcdir}.$tag_file);
51         +
52         +       my $template=template("autotagpage.tmpl");
53         +       $template->param(tag => $tag);
54         +       writefile($tag_file, $config{srcdir}, $template->output);
55         +       $autocreated_page = 1;
56         +
57         +       if ($config{rcs}) {
58         +               IkiWiki::disable_commit_hook();
59         +               IkiWiki::rcs_add($tag_file);
60         +               IkiWiki::rcs_commit_staged(
61         +                       gettext("Automatic tag page generation"),
62         +                       undef, undef);
63         +               IkiWiki::enable_commit_hook();
64         +       }
65          }
66          
67          sub tagpage ($) {
68         @@ -47,6 +78,10 @@
69                                         $tag=~y#/#/#s; # squash dups
70                         }
71          
72         +       if (defined $config{tag_autocreate} && $config{tag_autocreate} ) {
73         +               gen_tag_page($tag);
74         +       }
75         +
76                         return $tag;
77          }
78          
79         @@ -125,4 +160,18 @@
80                         }
81          }
82          
83         +sub change(@) {
84         +       return unless($autocreated_page);
85         +       $autocreated_page = 0;
86         +
87         +       # This refresh/saveindex is to complie the autocreated tag pages
88         +       IkiWiki::refresh();
89         +       IkiWiki::saveindex();
90         +
91         +       # This refresh/saveindex is to fix the Tags link
92         +       # With out this additional refresh/saveindex the tag link displays ?tag
93         +       IkiWiki::refresh();
94         +       IkiWiki::saveindex();
95         +}
96         +
97
98
99 This uses a [[template|wikitemplates]] called `autotagpage.tmpl`, here is my template file:
100
101     \[[!inline pages="link(<TMPL_VAR TAG>)" archive="yes"]]
102
103
104 A quirk I have not figured out is during the `sub change`, see my comments in the code.
105 I am not sure if that is the best way to handle it.
106
107 [[!tag patch]]
108 -- Jeremy Schultz <jeremy.schultz@uleth.ca>
109
110 No, this doesn't help:
111
112         +       # This refresh/saveindex is to fix the Tags link
113         +       # With out this additional refresh/saveindex the tag link displays ?tag
114         +       IkiWiki::refresh();
115         +       IkiWiki::saveindex();
116
117 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: 
118
119                 if (! $pagemtime{$page}) {
120                    ...
121                                 push @add, $file;
122                    ...
123                 }
124
125 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.
126
127 ---
128
129 I've made another attempt at fixiing this
130
131 The current progress can be found at my [git repository][gitweb] on branch
132 `autotag`:
133
134         git://git.liegesta.at/git/ikiwiki
135
136 [gitweb]: http://git.liegesta.at/?p=ikiwiki.git;a=shortlog;h=refs/heads/autotag (gitweb for branch autotag)
137
138 It's not entirely finished yet, but already quite usable. Testing and comments
139 on code quality, implementation details, as well as other patches would be
140 appreciated.
141
142 Here's what it does right now:
143
144 * enabled by setting `tag_autocreate=1` in the configuration.
145 * Tag pages will be created in `tagbase` from the template `autotag.tmpl`.
146 * Will correctly render all links, and dependencies. Well, AFAIK.
147 * When a tag page is deleted it will automatically recreated from template. (I
148 consider this a feature, not a bug)
149 * Requires a rebuild on first use.
150 * Adds a function `add_autofile()` to the plugin API, to do all this.
151
152 Todo/Bugs:
153
154 * Will still create a page even if there's a page other than `$tag` under
155 `tagbase` satisfying the tag link.
156 * Call from `IkiWiki.pm` to `Render.pm`, which adds a module dependency in the
157 wrong direction.
158 * Add files to RCS.
159 * Unit tests.
160 * Proper documentation.
161
162 --[[David_Riebenbauer]]