summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/websetup.pm
blob: 2b9240a29dd50269cc08b9a6b985fbe9a016fc8a (plain)
  1. #!/usr/bin/perl
  2. package IkiWiki::Plugin::websetup;
  3. use warnings;
  4. use strict;
  5. use IkiWiki 2.00;
  6. my @rcs_plugins=(qw{git svn bzr mercurial monotone tla norcs});
  7. # amazon_s3 is not something that should be enabled via the web.
  8. # external is not a standalone plugin.
  9. my @default_force_plugins=(qw{amazon_s3 external});
  10. sub import { #{{{
  11. hook(type => "checkconfig", id => "websetup", call => \&checkconfig);
  12. hook(type => "getsetup", id => "websetup", call => \&getsetup);
  13. hook(type => "sessioncgi", id => "websetup", call => \&sessioncgi);
  14. hook(type => "formbuilder_setup", id => "websetup",
  15. call => \&formbuilder_setup);
  16. } # }}}
  17. sub getsetup () { #{{{
  18. return
  19. websetup_force_plugins => {
  20. type => "string",
  21. example => \@default_force_plugins,
  22. description => "list of plugins that cannot be enabled/disabled via the web interface",
  23. safe => 0,
  24. rebuild => 0,
  25. },
  26. } #}}}
  27. sub checkconfig () { #{{{
  28. if (! exists $config{websetup_force_plugins}) {
  29. $config{websetup_force_plugins}=\@default_force_plugins;
  30. }
  31. } #}}}
  32. sub formatexample ($) { #{{{
  33. my $example=shift;
  34. if (defined $example && ! ref $example && length $example) {
  35. return "<br/ ><small>Example: <tt>$example</tt></small>";
  36. }
  37. else {
  38. return "";
  39. }
  40. } #}}}
  41. sub showfields ($$$@) { #{{{
  42. my $form=shift;
  43. my $plugin=shift;
  44. my $enabled=shift;
  45. my @show;
  46. while (@_) {
  47. my $key=shift;
  48. my %info=%{shift()};
  49. # skip complex, unsafe, or internal settings
  50. next if ref $config{$key} || ! $info{safe} || $info{type} eq "internal";
  51. # these are handled specially, so don't show
  52. next if $key eq 'add_plugins' || $key eq 'disable_plugins';
  53. push @show, $key, \%info;
  54. }
  55. return 0 unless @show;
  56. my $section=defined $plugin ? $plugin." ".gettext("plugin") : gettext("main");
  57. if (defined $plugin) {
  58. if (! showplugintoggle($form, $plugin, $enabled, $section) && ! $enabled) {
  59. # plugin not enabled and cannot be, so skip showing
  60. # its configuration
  61. return 0;
  62. }
  63. }
  64. while (@show) {
  65. my $key=shift @show;
  66. my %info=%{shift @show};
  67. my $description=exists $info{description_html} ? $info{description_html} : $info{description};
  68. my $value=$config{$key};
  69. # multiple plugins can have the same field
  70. my $name=defined $plugin ? $plugin.".".$key : $key;
  71. if ($info{type} eq "string") {
  72. $form->field(
  73. name => $name,
  74. label => $description,
  75. comment => defined $value && length $value ? "" : formatexample($info{example}),
  76. type => "text",
  77. value => $value,
  78. size => 60,
  79. fieldset => $section,
  80. );
  81. }
  82. elsif ($info{type} eq "pagespec") {
  83. $form->field(
  84. name => $name,
  85. label => $description,
  86. comment => formatexample($info{example}),
  87. type => "text",
  88. value => $value,
  89. size => 60,
  90. validate => \&IkiWiki::pagespec_valid,
  91. fieldset => $section,
  92. );
  93. }
  94. elsif ($info{type} eq "integer") {
  95. $form->field(
  96. name => $name,
  97. label => $description,
  98. type => "text",
  99. value => $value,
  100. size => 5,
  101. validate => '/^[0-9]+$/',
  102. fieldset => $section,
  103. );
  104. }
  105. elsif ($info{type} eq "boolean") {
  106. $form->field(
  107. name => $name,
  108. label => "",
  109. type => "checkbox",
  110. value => $value,
  111. options => [ [ 1 => $description ] ],
  112. fieldset => $section,
  113. );
  114. }
  115. }
  116. return 1;
  117. } #}}}
  118. sub showplugintoggle ($$$$) { #{{{
  119. my $form=shift;
  120. my $plugin=shift;
  121. my $enabled=shift;
  122. my $section=shift;
  123. return 0 if (grep { $_ eq $plugin } @{$config{websetup_force_plugins}}, @rcs_plugins);
  124. $form->field(
  125. name => "enable.$plugin",
  126. label => "",
  127. type => "checkbox",
  128. options => [ [ 1 => sprintf(gettext("enable %s?"), $plugin) ] ],
  129. value => $enabled,
  130. fieldset => $section,
  131. );
  132. return 1;
  133. } #}}}
  134. sub showform ($$) { #{{{
  135. my $cgi=shift;
  136. my $session=shift;
  137. if (! defined $session->param("name") ||
  138. ! IkiWiki::is_admin($session->param("name"))) {
  139. error(gettext("you are not logged in as an admin"));
  140. }
  141. eval q{use CGI::FormBuilder};
  142. error($@) if $@;
  143. my $form = CGI::FormBuilder->new(
  144. title => "setup",
  145. name => "setup",
  146. header => 0,
  147. charset => "utf-8",
  148. method => 'POST',
  149. javascript => 0,
  150. reset => 1,
  151. params => $cgi,
  152. action => $config{cgiurl},
  153. template => {type => 'div'},
  154. stylesheet => IkiWiki::baseurl()."style.css",
  155. );
  156. my $buttons=["Save Setup", "Cancel"];
  157. IkiWiki::decode_form_utf8($form);
  158. IkiWiki::run_hooks(formbuilder_setup => sub {
  159. shift->(form => $form, cgi => $cgi, session => $session,
  160. buttons => $buttons);
  161. });
  162. IkiWiki::decode_form_utf8($form);
  163. $form->field(name => "do", type => "hidden", value => "setup",
  164. force => 1);
  165. showfields($form, undef, undef, IkiWiki::getsetup());
  166. # record all currently enabled plugins before all are loaded
  167. my %enabled_plugins=%IkiWiki::loaded_plugins;
  168. # per-plugin setup
  169. require IkiWiki::Setup;
  170. my %plugins=map { $_ => 1 } IkiWiki::listplugins();
  171. foreach my $pair (IkiWiki::Setup::getsetup()) {
  172. my $plugin=$pair->[0];
  173. my $setup=$pair->[1];
  174. # skip all rcs plugins except for the one in use
  175. next if $plugin ne $config{rcs} && grep { $_ eq $plugin } @rcs_plugins;
  176. delete $plugins{$plugin} if showfields($form, $plugin, $enabled_plugins{$plugin}, @{$setup});
  177. }
  178. # list all remaining plugins (with no setup options) at the end
  179. showplugintoggle($form, $_, $enabled_plugins{$_}, gettext("other plugins"))
  180. foreach sort keys %plugins;
  181. if ($form->submitted eq "Cancel") {
  182. IkiWiki::redirect($cgi, $config{url});
  183. return;
  184. }
  185. elsif ($form->submitted eq 'Save Setup' && $form->validate) {
  186. # TODO
  187. $form->text(gettext("Setup saved."));
  188. }
  189. IkiWiki::showform($form, $buttons, $session, $cgi);
  190. } #}}}
  191. sub sessioncgi ($$) { #{{{
  192. my $cgi=shift;
  193. my $session=shift;
  194. if ($cgi->param("do") eq "setup") {
  195. showform($cgi, $session);
  196. exit;
  197. }
  198. } #}}}
  199. sub formbuilder_setup (@) { #{{{
  200. my %params=@_;
  201. my $form=$params{form};
  202. if ($form->title eq "preferences") {
  203. push @{$params{buttons}}, "Wiki Setup";
  204. if ($form->submitted && $form->submitted eq "Wiki Setup") {
  205. showform($params{cgi}, $params{session});
  206. exit;
  207. }
  208. }
  209. } #}}}
  210. 1