Merge branch 'master' of ssh://git.ikiwiki.info/srv/git/ikiwiki.info
[ikiwiki] / doc / todo / progressbar_plugin.mdwn
1 I would like to add next plugin to Ikiwiki. It's `progressbar` or simply `progress`.
2 I'm not sure what plugin name better is, probably that shorter ;) I know that
3 [DokuWiki](http://wiki.splitbrain.org/plugin:progressbar) has similar plugin,
4 so I think it can be useful also for Ikiwiki users.
5
6 Here is proposition of the plugin syntax:
7
8     \[[!progress done=50]]
9
10 Of course, `done` argument is integer from 0 to 100. 
11
12 A here is its HTML result:
13
14     <div class="progress">
15       <div class="progress-done" style="width: 50%">50%</div>
16     </div>
17
18 Note: I was trying with `<span>` tags too, but that tag is inline, so I can't
19 set `width` property for it.
20
21 Default CSS styles for the plugin can be like below:
22
23     div.progress {
24             border: 1px solid #ddd;
25             /* border: 2px solid #ddd; */
26             width: 200px;
27             background: #fff;
28             padding: 2px;
29             /* padding: 0px; */
30             border: 2px solid #aaa;
31             background: #eee;
32     }
33     div.progress-done {
34             height: 14px;
35             background: #ff6600;
36             font-size: 12px;
37             text-align: center;
38             vertical-align: middle;
39     }
40
41 You can use alternative, commented CSS code for `div.progress` if you dislike
42 padding around done strip.
43
44 Any comments? --[[Paweł|ptecza]]
45
46 > This looks like a nice idea.  If I could add one further suggestion: Allow your
47 > ratio to be a pair of pagespecs.  Then you could have something like:
48
49     \[[!progress totalpages="bugs/* and backlink(milestoneB)" donepages="bugs/* and backlink(milestoneB) and !link(bugs/done)"]]
50
51 > to have a progress bar marking how many bugs were compete for a
52 > particular milestone.  -- [[Will]]
53
54 >> Thanks a lot for your comment, Will! It seems very interesting for me.
55 >> I need to think more about improving that plugin. --[[Paweł|ptecza]]
56
57 >> Attached is a [[patch]] (well, source) for this.  You also need to add the proposed CSS above to `style.css`.
58 >> At the moment this plugin interacts poorly with the [[plugins/htmlscrubber]] plugin.
59 >> HTMLScrubber plugin removes the `style` attribute from the `progress-done` `div` tag, and so it defaults
60 >> to a width of 100%. -- [[Will]]
61
62 >>> Thank you for the code! I know how to fix that problem, because I had
63 >>> the same issue while writing [[todo/color_plugin]] :) --[[Paweł|ptecza]]
64
65     #!/usr/bin/perl
66     package IkiWiki::Plugin::progress;
67     
68     use warnings;
69     use strict;
70     use IkiWiki 2.00;
71     
72     my $percentage_pattern = qr/[0-9]+\%/; # pattern to validate percentages
73     
74     sub import { #{{{
75         hook(type => "getsetup", id => "progress", call => \&getsetup);
76         hook(type => "preprocess", id => "progress", call => \&preprocess);
77     } # }}}
78     
79     sub getsetup () { #{{{
80         return 
81                 plugin => {
82                         safe => 1,
83                         rebuild => undef,
84                 },
85     } #}}}
86     
87     sub preprocess (@) { #{{{
88         my %params=@_;
89         
90         my $fill;
91         
92         if (defined $params{percent}) {
93                 $fill = $params{percent};
94                 ($fill) = $fill =~ m/($percentage_pattern)/; # fill is untainted now
95         }
96         elsif (defined $params{totalpages} and defined $params{donepages}) {
97                 add_depends($params{page}, $params{totalpages});
98                 add_depends($params{page}, $params{donepages});
99     
100                 my @pages=keys %pagesources;
101                 my $totalcount=0;
102                 my $donecount=0;
103                 foreach my $page (@pages) {
104                         $totalcount++ if pagespec_match($page, $params{totalpages}, location => $params{page});
105                         $donecount++ if pagespec_match($page, $params{donepages}, location => $params{page});
106                 }
107                 
108                 if ($totalcount == 0) {
109                         $fill = "100%";
110                 } else {
111                         my $number = $donecount/$totalcount*100;
112                         $fill = sprintf("%u%%", $number);
113                 }
114         }
115         else {
116                 error("Missing parameters to progress plugin.  Need either `percent` or `totalpages` and `donepages` parameters.");
117         }
118     
119         return <<EODIV
120     <div class="progress">
121       <div class="progress-done" style="width: $fill">$fill</div>
122     </div>
123     EODIV
124     
125     } # }}}
126     
127     1