2 package IkiWiki::Plugin::ikistrap;
9 hook(type => "checkconfig", id => "ikistrap", call => \&checkconfig);
10 hook(type => "getsetup", id => "ikistrap", call => \&getsetup);
11 hook(type => "refresh", id => "ikistrap", call => \&refresh);
12 hook(type => "pagetemplate", id => "ikistrap", call => \&pagetemplate);
13 hook(type => "preprocess", id => "progress", call => \&progress);
17 if (! defined $config{bootstrap_js}) {
18 $config{bootstrap_js} = 1;
25 description => "Bootstrap 5 theme support",
30 description => "Install Bootstrap css and js files locally instead of using jsDelivr?",
37 description => "Load Bootstrap's Javascript helpers?",
46 my($basename, $href) = @_;
47 my $filename = "$config{destdir}/$basename";
48 return if(-e $filename);
49 debug("Fetching missing $basename...");
50 system("/usr/bin/curl -# \"$href\" -o \"$filename\"");
54 return 0 unless($config{bootstrap_local});
55 mkdir("$config{destdir}");
58 mkdir("$config{destdir}/css");
59 check("css/bootstrap.min.css", "https://cdn.jsdelivr.net/npm/bootstrap\@5.0.0/dist/css/bootstrap.min.css");
60 check("css/bootstrap-icons.css", "https://cdn.jsdelivr.net/npm/bootstrap-icons\@1.4.1/font/bootstrap-icons.css");
63 mkdir("$config{destdir}/css/fonts");
64 check("css/fonts/bootstrap-icons.woff2", "https://cdn.jsdelivr.net/npm/bootstrap-icons\@1.4.1/font/fonts/bootstrap-icons.woff2");
66 # JavaScript (if enabled)
67 return 0 unless($config{bootstrap_js});
68 mkdir("$config{destdir}/js");
69 check("js/bootstrap.bundle.min.js", "https://cdn.jsdelivr.net/npm/bootstrap\@5.0.0/dist/js/bootstrap.bundle.min.js");
74 my $template = $params{template};
76 $template->param(bootstrap_js => $config{bootstrap_js});
77 $template->param(bootstrap_local => $config{bootstrap_local});
80 # Emulate the progress plugin, but do it the HTML5 + Bootstrap way.
81 # Also allow setting an extra class attribute.
84 my $percentage_pattern = qr/[0-9]+\%?/; # pattern to validate percentages
85 my ($fill, $value, $max);
87 if (defined $params{percent}) {
88 $fill = $params{percent};
89 ($fill) = $fill =~ m/($percentage_pattern)/; # fill is untainted now
91 if (! defined $fill || ! length $fill || $fill > 100 || $fill < 0) {
92 error(sprintf(gettext("illegal percent value %s"), $params{percent}));
97 } elsif (defined $params{totalpages} and defined $params{donepages}) {
98 $max = pagespec_match_list($params{page}, $params{totalpages}, deptype => deptype("presence"));
99 $value = pagespec_match_list($params{page}, $params{donepages}, deptype => deptype("presence"));
104 $fill = sprintf("%u%%", $value / $max * 100);
107 error(gettext("need either `percent` or `totalpages` and `donepages` parameters"));
110 my $class = "progress-bar";
111 if (defined $params{class}) {
112 $class .= " $params{class}";
116 <p><div class="progress"><div class="$class" role="progressbar" style="width: $value%" aria-valuenow="$value" aria-valuemin="0" aria-valuemax="$max">$fill</div></div></p>