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