use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
%pagestate %renderedfiles %oldrenderedfiles %pagesources
- %destsources %depends %hooks %forcerebuild $gettext_obj};
+ %destsources %depends %hooks %forcerebuild $gettext_obj
+ %loaded_plugins};
use Exporter q{import};
our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
cgiurl => {
type => "string",
default => '',
- examples => "http://example.com/wiki/ikiwiki.cgi",
+ example => "http://example.com/wiki/ikiwiki.cgi",
description => "url to the ikiwiki.cgi",
safe => 1,
rebuild => 1,
},
+ cgi_wrapper => {
+ type => "string",
+ default => '',
+ example => "/var/www/wiki/ikiwiki.cgi",
+ description => "cgi wrapper to generate",
+ safe => 0, # file
+ rebuild => 0,
+ },
+ cgi_wrappermode => {
+ type => "string",
+ default => '06755',
+ description => "mode for cgi_wrapper (can safely be made suid)",
+ safe => 0,
+ rebuild => 0,
+ },
rcs => {
type => "string",
default => '',
safe => 0, # don't allow overriding
rebuild => 0,
},
- historyurl => {
- type => "string",
- # TODO should be set per-rcs to allow different
- # examples and descriptions
- default => '',
- example => "XXX",
- description => "XXX",
- safe => 1,
+ default_plugins => {
+ type => "internal",
+ default => [qw{mdwn link inline htmlscrubber passwordauth
+ openid signinedit lockedit conditional
+ recentchanges parentlinks}],
+ description => "plugins to enable by default",
+ safe => 0,
rebuild => 1,
},
- diffurl => {
+ add_plugins => {
type => "string",
- # TODO ditto above
- default => '',
- example => "XXX",
- description => "XXX",
+ default => [],
+ description => "plugins to add to the default configuration",
safe => 1,
rebuild => 1,
},
- discussion => {
- type => "boolean",
- default => 1,
- description => "enable Discussion pages",
+ disable_plugins => {
+ type => "string",
+ default => [],
+ description => "plugins to disable",
safe => 1,
rebuild => 1,
},
- svnpath => {
- # TODO move
- type => "string",
- default => "trunk",
- description => "path inside svn repo where wiki is located",
- safe => 0, # could expose/overwrite data
- rebuild => 0,
- },
- gitorigin_branch => {
- type => "string",
- default => "origin",
- description => "the git origin to pull from",
- safe => 0, # paranoia
- rebuild => 0,
- },
- gitmaster_branch => {
- type => "string",
- default => "master",
- description => "the git master branch",
- safe => 0, # paranoia
- rebuild => 0,
- },
templatedir => {
type => "string",
default => "$installdir/share/ikiwiki/templates",
description => "location of template files",
+ advanced => 1,
safe => 0, # path
rebuild => 1,
},
type => "string",
default => "$installdir/share/ikiwiki/basewiki",
description => "base wiki source location",
+ advanced => 1,
safe => 0, # path
rebuild => 0,
},
+ wrappers => {
+ type => "internal",
+ default => [],
+ description => "wrappers to generate",
+ safe => 0,
+ rebuild => 0,
+ },
underlaydirs => {
type => "internal",
default => [],
verbose => {
type => "boolean",
default => 0,
- description => "display verbose messages when building",
+ description => "display verbose messages when building?",
safe => 1,
rebuild => 0,
},
syslog => {
type => "boolean",
default => 0,
- description => "log to syslog",
+ description => "log to syslog?",
safe => 1,
rebuild => 0,
},
safe => 0, # changing requires manual transition
rebuild => 1,
},
+ discussion => {
+ type => "boolean",
+ default => 1,
+ description => "enable Discussion pages?",
+ safe => 1,
+ rebuild => 1,
+ },
default_pageext => {
type => "string",
default => "mdwn",
type => "string",
default => '%c',
description => "strftime format string to display date",
+ advanced => 1,
safe => 1,
rebuild => 1,
},
default => undef,
example => "en_US.UTF-8",
description => "UTF-8 locale to use",
+ advanced => 1,
safe => 0,
rebuild => 1,
},
type => "boolean",
default => 0,
description => "only send cookies over SSL connections?",
+ advanced => 1,
safe => 1,
rebuild => 0,
},
hardlink => {
type => "boolean",
default => 0,
- description => "attempt to hardlink source files (optimisation for large files)",
+ description => "attempt to hardlink source files? (optimisation for large files)",
+ advanced => 1,
safe => 0, # paranoia
rebuild => 0,
},
-
+ umask => {
+ type => "integer",
+ description => "",
+ example => "022",
+ description => "force ikiwiki to use a particular umask",
+ advanced => 1,
+ safe => 0, # paranoia
+ rebuild => 0,
+ },
+ libdir => {
+ type => "string",
+ default => "",
+ example => "$ENV{HOME}/.ikiwiki/",
+ description => "extra library and plugin directory",
+ advanced => 1,
+ safe => 0, # directory
+ rebuild => 0,
+ },
+ ENV => {
+ type => "string",
+ default => {},
+ description => "environment variables",
+ safe => 0, # paranoia
+ rebuild => 0,
+ },
+ exclude => {
+ type => "string",
+ default => undef,
+ example => '\.wav$',
+ description => "regexp of source files to ignore",
+ advanced => 1,
+ safe => 0, # regexp
+ rebuild => 1,
+ },
+ banned_users => {
+ type => "string",
+ default => [],
+ description => "users who are banned from the wiki",
+ safe => 1,
+ rebuild => 0,
+ },
wiki_file_prune_regexps => {
type => "internal",
default => [qr/(^|\/)\.\.(\/|$)/, qr/^\./, qr/\/\./,
safe => 0,
rebuild => 0,
},
- wrapper => {
- type => "internal",
- default => undef,
- description => "wrapper file to generate",
- safe => 0,
- rebuild => 0,
- },
- wrappermode => {
- type => "internal",
- default => undef,
- description => "mode of wrapper file",
- safe => 0,
- rebuild => 0,
- },
setup => {
type => "internal",
default => undef,
safe => 0,
rebuild => 0,
},
- plugin => {
- type => "internal",
- default => [qw{mdwn link inline htmlscrubber passwordauth
- openid signinedit lockedit conditional
- recentchanges parentlinks}],
- description => "enabled plugins",
- safe => 0,
- rebuild => 1,
- },
- libdir => {
- type => "internal",
- default => undef,
- example => "$ENV{HOME}/.ikiwiki/",
- description => "extra library and plugin directory",
- safe => 0,
- rebuild => 0,
- },
} #}}}
sub defaultconfig () { #{{{
$config{wikistatedir}="$config{srcdir}/.ikiwiki"
unless exists $config{wikistatedir};
-
- if ($config{rcs}) {
- eval qq{use IkiWiki::Rcs::$config{rcs}};
- if ($@) {
- error("Failed to load RCS module IkiWiki::Rcs::$config{rcs}: $@");
- }
- }
- else {
- require IkiWiki::Rcs::Stub;
- }
- if (exists $config{umask}) {
+ if (defined $config{umask}) {
umask(possibly_foolish_untaint($config{umask}));
}
return 1;
} #}}}
+sub listplugins () { #{{{
+ my %ret;
+
+ foreach my $dir (@INC, $config{libdir}) {
+ next unless defined $dir && length $dir;
+ foreach my $file (glob("$dir/IkiWiki/Plugin/*.pm")) {
+ my ($plugin)=$file=~/.*\/(.*)\.pm$/;
+ $ret{$plugin}=1;
+ }
+ }
+ foreach my $dir ($config{libdir}, "$installdir/lib/ikiwiki") {
+ next unless defined $dir && length $dir;
+ foreach my $file (glob("$dir/plugins/*")) {
+ $ret{basename($file)}=1 if -x $file;
+ }
+ }
+
+ return keys %ret;
+} #}}}
+
sub loadplugins () { #{{{
- if (defined $config{libdir}) {
+ if (defined $config{libdir} && length $config{libdir}) {
unshift @INC, possibly_foolish_untaint($config{libdir});
}
- loadplugin($_) foreach @{$config{plugin}};
+ loadplugin($_) foreach @{$config{default_plugins}}, @{$config{add_plugins}};
+
+ if ($config{rcs}) {
+ if (exists $IkiWiki::hooks{rcs}) {
+ error(gettext("cannot use multiple rcs plugins"));
+ }
+ loadplugin($config{rcs});
+ }
+ if (! exists $IkiWiki::hooks{rcs}) {
+ loadplugin("norcs");
+ }
run_hooks(getopt => sub { shift->() });
if (grep /^-/, @ARGV) {
if (defined $dir && -x "$dir/plugins/$plugin") {
require IkiWiki::Plugin::external;
import IkiWiki::Plugin::external "$dir/plugins/$plugin";
+ $loaded_plugins{$plugin}=1;
return 1;
}
}
if ($@) {
error("Failed to load plugin $mod: $@");
}
+ $loaded_plugins{$plugin}=1;
return 1;
} #}}}
if ($preprocessing{$page}++ > 3) {
# Avoid loops of preprocessed pages preprocessing
# other pages that preprocess them, etc.
- #translators: The first parameter is a
- #translators: preprocessor directive name,
- #translators: the second a page name, the
- #translators: third a number.
- return "[[".sprintf(gettext("%s preprocessing loop detected on %s at depth %i"),
- $command, $page, $preprocessing{$page}).
- "]]";
+ return "[[!$command <span class=\"error\">".
+ sprintf(gettext("preprocessing loop detected on %s at depth %i"),
+ $page, $preprocessing{$page}).
+ "</span>]]";
}
my $ret;
if (! $scan) {
return 1;
} #}}}
+sub rcs_update () { #{{{
+ $hooks{rcs}{rcs_update}{call}->(@_);
+} #}}}
+
+sub rcs_prepedit ($) { #{{{
+ $hooks{rcs}{rcs_prepedit}{call}->(@_);
+} #}}}
+
+sub rcs_commit ($$$;$$) { #{{{
+ $hooks{rcs}{rcs_commit}{call}->(@_);
+} #}}}
+
+sub rcs_commit_staged ($$$) { #{{{
+ $hooks{rcs}{rcs_commit_staged}{call}->(@_);
+} #}}}
+
+sub rcs_add ($) { #{{{
+ $hooks{rcs}{rcs_add}{call}->(@_);
+} #}}}
+
+sub rcs_remove ($) { #{{{
+ $hooks{rcs}{rcs_remove}{call}->(@_);
+} #}}}
+
+sub rcs_rename ($$) { #{{{
+ $hooks{rcs}{rcs_rename}{call}->(@_);
+} #}}}
+
+sub rcs_recentchanges ($) { #{{{
+ $hooks{rcs}{rcs_recentchanges}{call}->(@_);
+} #}}}
+
+sub rcs_diff ($) { #{{{
+ $hooks{rcs}{rcs_diff}{call}->(@_);
+} #}}}
+
+sub rcs_getctime ($) { #{{{
+ $hooks{rcs}{rcs_getctime}{call}->(@_);
+} #}}}
+
sub globlist_to_pagespec ($) { #{{{
my @globlist=split(' ', shift);