use open qw{:utf8 :std};
use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
- %pagestate %renderedfiles %oldrenderedfiles %pagesources
- %destsources %depends %hooks %forcerebuild $gettext_obj
- %loaded_plugins};
+ %pagestate %wikistate %renderedfiles %oldrenderedfiles
+ %pagesources %destsources %depends %hooks %forcerebuild
+ $gettext_obj %loaded_plugins};
use Exporter q{import};
our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
bestlink htmllink readfile writefile pagetype srcfile pagename
displaytime will_render gettext urlto targetpage
- add_underlay
- %config %links %pagestate %renderedfiles
+ add_underlay pagetitle titlepage linkpage newpagefile
+ %config %links %pagestate %wikistate %renderedfiles
%pagesources %destsources);
our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE
safe => 0, # changing requires manual transition
rebuild => 1,
},
+ indexpages => {
+ type => "boolean",
+ default => 0,
+ description => "use page/index.mdwn source files",
+ safe => 1,
+ rebuild => 1,
+ },
discussion => {
type => "boolean",
default => 1,
my $type=pagetype($file);
my $page=$file;
$page=~s/\Q.$type\E*$// if defined $type && !$hooks{htmlize}{$type}{keepextension};
+ if ($config{indexpages} && $page=~/(.*)\/index$/) {
+ $page=$1;
+ }
return $page;
} #}}}
+sub newpagefile ($$) { #{{{
+ my $page=shift;
+ my $type=shift;
+
+ if (! $config{indexpages} || $page eq 'index') {
+ return $page.".".$type;
+ }
+ else {
+ return $page."/index.".$type;
+ }
+} #}}}
+
sub targetpage ($$) { #{{{
my $page=shift;
my $ext=shift;
- if (! $config{usedirs} || $page =~ /^index$/ ) {
+ if (! $config{usedirs} || $page eq 'index') {
return $page.".".$ext;
- } else {
+ }
+ else {
return $page."/index.".$ext;
}
} #}}}
sub add_underlay ($) { #{{{
my $dir=shift;
- if ($dir=~/^\//) {
- unshift @{$config{underlaydirs}}, $dir;
+ if ($dir !~ /^\//) {
+ $dir="$config{underlaydir}/../$dir";
}
- else {
- unshift @{$config{underlaydirs}}, "$config{underlaydir}/../$dir";
+
+ if (! grep { $_ eq $dir } @{$config{underlaydirs}}) {
+ unshift @{$config{underlaydirs}}, $dir;
}
return 1;
# Important security check.
if (-e "$config{destdir}/$dest" && ! $config{rebuild} &&
- ! grep { $_ eq $dest } (@{$renderedfiles{$page}}, @{$oldrenderedfiles{$page}})) {
+ ! grep { $_ eq $dest } (@{$renderedfiles{$page}}, @{$oldrenderedfiles{$page}}, @{$wikistate{editpage}{previews}})) {
error("$config{destdir}/$dest independently created, not overwriting with version from $page");
}
} #}}}
sub displaytime ($;$) { #{{{
+ my $time=shift;
+ my $format=shift;
+ if (exists $hooks{displaytime}) {
+ my $ret;
+ run_hooks(displaytime => sub {
+ $ret=shift->($time, $format)
+ });
+ return $ret;
+ }
+ else {
+ return formattime($time, $format);
+ }
+} #}}}
+
+sub formattime ($;$) { #{{{
+ # Plugins can override this function to mark up the time for
+ # display.
my $time=shift;
my $format=shift;
if (! defined $format) {
return;
}
}
- my $ret=Storable::fd_retrieve($in);
- if (! defined $ret) {
+
+ my $index=Storable::fd_retrieve($in);
+ if (! defined $index) {
return 0;
}
- my %index=%$ret;
- foreach my $src (keys %index) {
- my %d=%{$index{$src}};
+
+ my $pages;
+ if (exists $index->{version} && ! ref $index->{version}) {
+ $pages=$index->{page};
+ %wikistate=%{$index->{state}};
+ }
+ else {
+ $pages=$index;
+ %wikistate=();
+ }
+
+ foreach my $src (keys %$pages) {
+ my $d=$pages->{$src};
my $page=pagename($src);
- $pagectime{$page}=$d{ctime};
+ $pagectime{$page}=$d->{ctime};
if (! $config{rebuild}) {
$pagesources{$page}=$src;
- $pagemtime{$page}=$d{mtime};
- $renderedfiles{$page}=$d{dest};
- if (exists $d{links} && ref $d{links}) {
- $links{$page}=$d{links};
- $oldlinks{$page}=[@{$d{links}}];
+ $pagemtime{$page}=$d->{mtime};
+ $renderedfiles{$page}=$d->{dest};
+ if (exists $d->{links} && ref $d->{links}) {
+ $links{$page}=$d->{links};
+ $oldlinks{$page}=[@{$d->{links}}];
}
- if (exists $d{depends}) {
- $depends{$page}=$d{depends};
+ if (exists $d->{depends}) {
+ $depends{$page}=$d->{depends};
}
- if (exists $d{state}) {
- $pagestate{$page}=$d{state};
+ if (exists $d->{state}) {
+ $pagestate{$page}=$d->{state};
}
}
- $oldrenderedfiles{$page}=[@{$d{dest}}];
+ $oldrenderedfiles{$page}=[@{$d->{dest}}];
}
foreach my $page (keys %pagesources) {
$pagecase{lc $page}=$page;
my $newfile="$config{wikistatedir}/indexdb.new";
my $cleanup = sub { unlink($newfile) };
open (my $out, '>', $newfile) || error("cannot write to $newfile: $!", $cleanup);
+
my %index;
foreach my $page (keys %pagemtime) {
next unless $pagemtime{$page};
my $src=$pagesources{$page};
- $index{$src}={
+ $index{page}{$src}={
ctime => $pagectime{$page},
mtime => $pagemtime{$page},
dest => $renderedfiles{$page},
};
if (exists $depends{$page}) {
- $index{$src}{depends} = $depends{$page};
+ $index{page}{$src}{depends} = $depends{$page};
}
if (exists $pagestate{$page}) {
foreach my $id (@hookids) {
foreach my $key (keys %{$pagestate{$page}{$id}}) {
- $index{$src}{state}{$id}{$key}=$pagestate{$page}{$id}{$key};
+ $index{page}{$src}{state}{$id}{$key}=$pagestate{$page}{$id}{$key};
}
}
}
}
+
+ $index{state}={};
+ foreach my $id (@hookids) {
+ foreach my $key (keys %{$wikistate{$id}}) {
+ $index{state}{$id}{$key}=$wikistate{$id}{$key};
+ }
+ }
+
+ $index{version}="3";
my $ret=Storable::nstore_fd(\%index, $out);
return if ! defined $ret || ! $ret;
close $out || error("failed saving to $newfile: $!", $cleanup);
}
} #}}}
+sub match_user ($$;@) { #{{{
+ shift;
+ my $user=shift;
+ my %params=@_;
+
+ if (! exists $params{user}) {
+ return IkiWiki::FailReason->new("no user specified");
+ }
+
+ if (defined $params{user} && lc $params{user} eq lc $user) {
+ return IkiWiki::SuccessReason->new("user is $user");
+ }
+ elsif (! defined $params{user}) {
+ return IkiWiki::FailReason->new("not logged in");
+ }
+ else {
+ return IkiWiki::FailReason->new("user is $params{user}, not $user");
+ }
+} #}}}
+
+sub match_admin ($$;@) { #{{{
+ shift;
+ shift;
+ my %params=@_;
+
+ if (! exists $params{user}) {
+ return IkiWiki::FailReason->new("no user specified");
+ }
+
+ if (defined $params{user} && IkiWiki::is_admin($params{user})) {
+ return IkiWiki::SuccessReason->new("user is an admin");
+ }
+ elsif (! defined $params{user}) {
+ return IkiWiki::FailReason->new("not logged in");
+ }
+ else {
+ return IkiWiki::FailReason->new("user is not an admin");
+ }
+} #}}}
+
+sub match_ip ($$;@) { #{{{
+ shift;
+ my $ip=shift;
+ my %params=@_;
+
+ if (! exists $params{ip}) {
+ return IkiWiki::FailReason->new("no IP specified");
+ }
+
+ if (defined $params{ip} && lc $params{ip} eq lc $ip) {
+ return IkiWiki::SuccessReason->new("IP is $ip");
+ }
+ else {
+ return IkiWiki::FailReason->new("IP is $params{ip}, not $ip");
+ }
+} #}}}
+
1