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