refactor
[ikiwiki.git] / IkiWiki / Setup.pm
1 #!/usr/bin/perl
2 # Ikiwiki setup files are perl files that 'use IkiWiki::Setup::foo',
3 # passing it some sort of configuration data.
4
5 package IkiWiki::Setup;
6
7 use warnings;
8 use strict;
9 use IkiWiki;
10 use open qw{:utf8 :std};
11
12 sub load ($) { # {{{
13         my $setup=IkiWiki::possibly_foolish_untaint(shift);
14         delete $config{setup};
15         #translators: The first parameter is a filename, and the second
16         #translators: is a (probably not translated) error message.
17         open (IN, $setup) || error(sprintf(gettext("cannot read %s: %s"), $setup, $!));
18         my $code;
19         {
20                 local $/=undef;
21                 $code=<IN>;
22         }
23         ($code)=$code=~/(.*)/s;
24         close IN;
25
26         eval $code;
27         error("$setup: ".$@) if $@;
28 } #}}}
29
30 sub merge ($) {
31         # Merge setup into existing config and untaint.
32         my %setup=%{shift()};
33
34         if (exists $setup{add_plugins}) {
35                 push @{$setup{add_plugins}}, @{$config{add_plugins}};
36         }
37         if (exists $setup{exclude}) {
38                 push @{$config{wiki_file_prune_regexps}}, $setup{exclude};
39         }
40         foreach my $c (keys %setup) {
41                 if (defined $setup{$c}) {
42                         if (! ref $setup{$c} || ref $setup{$c} eq 'Regexp') {
43                                 $config{$c}=IkiWiki::possibly_foolish_untaint($setup{$c});
44                         }
45                         elsif (ref $setup{$c} eq 'ARRAY') {
46                                 if ($c eq 'wrappers') {
47                                         # backwards compatability code
48                                         $config{$c}=$setup{$c};
49                                 }
50                                 else {
51                                         $config{$c}=[map { IkiWiki::possibly_foolish_untaint($_) } @{$setup{$c}}]
52                                 }
53                         }
54                         elsif (ref $setup{$c} eq 'HASH') {
55                                 foreach my $key (keys %{$setup{$c}}) {
56                                         $config{$c}{$key}=IkiWiki::possibly_foolish_untaint($setup{$c}{$key});
57                                 }
58                         }
59                 }
60                 else {
61                         $config{$c}=undef;
62                 }
63         }
64         
65         if (length $config{cgi_wrapper}) {
66                 push @{$config{wrappers}}, {
67                         cgi => 1,
68                         wrapper => $config{cgi_wrapper},
69                         wrappermode => (defined $config{cgi_wrappermode} ? $config{cgi_wrappermode} : "06755"),
70                 };
71         }
72 } #}}}
73
74 sub getsetup () { #{{{
75         # Gets all available setup data from all plugins. Returns an ordered list of
76         # [plugin, setup] pairs.
77         my @ret;
78
79         # Load all plugins, so that all setup options are available.
80         # (But skip a few problematic external demo plugins.)
81         my @plugins=grep { ! /^(externaldemo|pythondemo|\Q$config{rcs}\E)$/ }
82                 sort(IkiWiki::listplugins());
83         unshift @plugins, $config{rcs} if $config{rcs}; # rcs plugin 1st
84         foreach my $plugin (@plugins) {
85                 eval { IkiWiki::loadplugin($plugin) };
86                 if (exists $IkiWiki::hooks{checkconfig}{$plugin}{call}) {
87                         my @s=eval { $IkiWiki::hooks{checkconfig}{$plugin}{call}->() };
88                 }
89         }
90
91         foreach my $plugin (@plugins) {
92                 if (exists $IkiWiki::hooks{getsetup}{$plugin}{call}) {
93                         # use an array rather than a hash, to preserve order
94                         my @s=eval { $IkiWiki::hooks{getsetup}{$plugin}{call}->() };
95                         next unless @s;
96                         push @ret, [ $plugin, \@s ],
97                 }
98         }
99
100         return @ret;
101 } #}}}
102
103 sub dump ($) { #{{{
104         my $file=IkiWiki::possibly_foolish_untaint(shift);
105         
106         require IkiWiki::Setup::Standard;
107         my @dump=IkiWiki::Setup::Standard::gendump("Setup file for ikiwiki.");
108
109         open (OUT, ">", $file) || die "$file: $!";
110         print OUT "$_\n" foreach @dump;
111         close OUT;
112 }
113
114 1