Responses
[ikiwiki.git] / doc / todo / Add_a_plugin_to_list_available_pre-processor_commands.mdwn
1 I've found myself wanting to know which [[plugins]] are switched on so I know which pre-processor commands I can use.  The attached [[patch]] adds a new plugin that generates the list of available plugins. -- [[Will]]
2
3 > Good idea, I do see a few problems:
4
5 > - preprocessor directives do not necessarily have the same name as the
6 >   plugin that contains them (for example, the graphviz plugin adds a graph
7 >   directive). Won't keys `%{IkiWiki::hooks{preprocess}}` work?
8
9 >>> Er, yeah - that's a much better solution. :)
10
11 > - "listplugins" is a bit misnamed since it only does preprocessor directives.
12
13 >>> Yes.  Initially this was going to list all enabled plugins.  Then when searching
14 >>> for enabled plugins I changed my mind and decided that a list of pre-processor
15 >>> directives was more useful.  I'll fix that too.
16
17 > - comment was copied from version plugin and still mentions version :-)
18
19 >>> :-)
20
21 > - Seems like [[ikiwiki/formatting]] could benefit from including the
22 >   list.. however, just a list of preprocessor directive names is not
23 >   the most user-friendly thing that could be put on that page. It would
24 >   be nice if there were also a short description and maybe an example of
25 >   use. Seems like the place to include that info would be in the call
26 >   to `hook()`.
27 >   (Maybe adding that is more involved than you want to go though..)
28
29 > --[[Joey]]
30
31 >> Adding a whole new hook for a usage example is more effort than I
32 >> wanted to go to.  I was thinking of either:
33 >>
34 >>    - Adding a configuration for a wiki directory.  If a matching page is in the
35 >>      specified wiki directory then the plugin name gets turned into a link to that
36 >>      page
37 >>    - Adding configuration for an external URL.  Each plugin name is added as
38 >>       a link to the plugin name appended to the URL.
39
40 >>The first option is easier to navigate and wouldn't produce broken links,
41 >>but requires all the plugin documentation to be local.  The second option
42 >>can link back to the main IkiWiki site, but if you have any non-standard
43 >>plugins then you'll get broken links.
44 >>
45 >>Hrm.  After listing all of that, maybe your idea with the hooks is the better
46 >>solution.  I'll think about it some more. -- [[Will]]
47
48     #!/usr/bin/perl
49     # Ikiwiki listplugins plugin.
50     package IkiWiki::Plugin::listplugins;
51     
52     use warnings;
53     use strict;
54     use IkiWiki 2.00;
55     
56     sub import { #{{{
57         hook(type => "getsetup", id => "listplugins", call => \&getsetup);
58         hook(type => "needsbuild", id => "listplugins", call => \&needsbuild);
59         hook(type => "preprocess", id => "listplugins", call => \&preprocess);
60     } # }}}
61     
62     sub getsetup () { #{{{
63         return
64                 plugin => {
65                         safe => 1,
66                         rebuild => undef,
67                 },
68     } #}}}
69     
70     my @pluginlist;
71     my $pluginString;
72     
73     sub needsbuild (@) { #{{{
74         my $needsbuild=shift;
75     
76         my @rawpluginlist = sort(IkiWiki::listplugins());
77         @pluginlist = ();
78         
79         foreach my $plugin (@rawpluginlist) {
80                 if ( exists $IkiWiki::hooks{preprocess}{$plugin} ) {
81                         push(@pluginlist,$plugin);
82                 }
83         }
84     
85         $pluginString = join (' ', @pluginlist);
86     
87         foreach my $page (keys %pagestate) {
88                 if (exists $pagestate{$page}{listplugins}{shown}) {
89                         if ($pagestate{$page}{listplugins}{shown} ne $pluginString) {
90                                 push @$needsbuild, $pagesources{$page};
91                         }
92                         if (exists $pagesources{$page} &&
93                             grep { $_ eq $pagesources{$page} } @$needsbuild) {
94                                 # remove state, will be re-added if
95                                 # the version is still shown during the
96                                 # rebuild
97                                 delete $pagestate{$page}{listplugins}{shown};
98                         }
99                 }
100         }
101     } # }}}
102     
103     sub preprocess (@) { #{{{
104         my %params=@_;
105         
106         $pagestate{$params{destpage}}{listplugins}{shown}=$pluginString;
107         
108         my $result = "<ul class=\"pluginlist\">";
109         my $thisPlugin;
110         foreach $thisPlugin (@pluginlist) {
111                 $result .= "<li class=\"pluginlist\">$thisPlugin</li>";
112         }
113         $result .= "</ul>";
114         
115         return $result;
116     } # }}}
117     
118     1