Merge branch 'master' into autotag
commit
34e8c78c1c
11
IkiWiki.pm
11
IkiWiki.pm
|
@ -356,7 +356,7 @@ sub getsetup () {
|
||||||
},
|
},
|
||||||
wiki_file_prune_regexps => {
|
wiki_file_prune_regexps => {
|
||||||
type => "internal",
|
type => "internal",
|
||||||
default => [qr/(^|\/)\.\.(\/|$)/, qr/^\./, qr/\/\./,
|
default => [qr/(^|\/)\.\.(\/|$)/, qr/^\//, qr/^\./, qr/\/\./,
|
||||||
qr/\.x?html?$/, qr/\.ikiwiki-new$/,
|
qr/\.x?html?$/, qr/\.ikiwiki-new$/,
|
||||||
qr/(^|\/).svn\//, qr/.arch-ids\//, qr/{arch}\//,
|
qr/(^|\/).svn\//, qr/.arch-ids\//, qr/{arch}\//,
|
||||||
qr/(^|\/)_MTN\//, qr/(^|\/)_darcs\//,
|
qr/(^|\/)_MTN\//, qr/(^|\/)_darcs\//,
|
||||||
|
@ -1844,15 +1844,8 @@ sub deptype (@) {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $file_prune_regexp;
|
my $file_prune_regexp;
|
||||||
sub file_pruned ($;$) {
|
sub file_pruned ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
if (@_) {
|
|
||||||
require File::Spec;
|
|
||||||
$file=File::Spec->canonpath($file);
|
|
||||||
my $base=File::Spec->canonpath(shift);
|
|
||||||
return if $file eq $base;
|
|
||||||
$file =~ s#^\Q$base\E/+##;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined $config{include} && length $config{include}) {
|
if (defined $config{include} && length $config{include}) {
|
||||||
return 0 if $file =~ m/$config{include}/;
|
return 0 if $file =~ m/$config{include}/;
|
||||||
|
|
|
@ -137,7 +137,7 @@ sub formbuilder (@) {
|
||||||
$filename=linkpage(IkiWiki::possibly_foolish_untaint(
|
$filename=linkpage(IkiWiki::possibly_foolish_untaint(
|
||||||
attachment_location($form->field('page')).
|
attachment_location($form->field('page')).
|
||||||
IkiWiki::basename($filename)));
|
IkiWiki::basename($filename)));
|
||||||
if (IkiWiki::file_pruned($filename, $config{srcdir})) {
|
if (IkiWiki::file_pruned($filename)) {
|
||||||
error(gettext("bad attachment filename"));
|
error(gettext("bad attachment filename"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,18 +36,22 @@ sub refresh () {
|
||||||
|
|
||||||
my (%pages, %dirs);
|
my (%pages, %dirs);
|
||||||
foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
|
foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
|
||||||
|
require File::Spec;
|
||||||
|
$dir=File::Spec->canonpath($dir);
|
||||||
|
|
||||||
find({
|
find({
|
||||||
no_chdir => 1,
|
no_chdir => 1,
|
||||||
wanted => sub {
|
wanted => sub {
|
||||||
$_=decode_utf8($_);
|
my $file=File::Spec->canonpath(decode_utf8($_));
|
||||||
if (IkiWiki::file_pruned($_, $dir)) {
|
return if $file eq $dir;
|
||||||
|
$file=~s/^\Q$dir\E\/?//;
|
||||||
|
return unless length $file;
|
||||||
|
if (IkiWiki::file_pruned($file)) {
|
||||||
$File::Find::prune=1;
|
$File::Find::prune=1;
|
||||||
}
|
}
|
||||||
elsif (! -l $_) {
|
elsif (! -l $_) {
|
||||||
my ($f)=/$config{wiki_file_regexp}/; # untaint
|
my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint
|
||||||
return unless defined $f;
|
return unless defined $f;
|
||||||
$f=~s/^\Q$dir\E\/?//;
|
|
||||||
return unless length $f;
|
|
||||||
return if $f =~ /\._([^.]+)$/; # skip internal page
|
return if $f =~ /\._([^.]+)$/; # skip internal page
|
||||||
if (! -d _) {
|
if (! -d _) {
|
||||||
$pages{pagename($f)}=1;
|
$pages{pagename($f)}=1;
|
||||||
|
|
|
@ -286,14 +286,10 @@ sub rcs_diff ($) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) {
|
sub extract_timestamp (@) {
|
||||||
my ($file) = @_;
|
|
||||||
|
|
||||||
# XXX filename passes through the shell here, should try to avoid
|
# XXX filename passes through the shell here, should try to avoid
|
||||||
# that just in case
|
# that just in case
|
||||||
my @cmdline = ("bzr", "log", "--limit", '1', "$config{srcdir}/$file");
|
open (my $out, "@_ |");
|
||||||
open (my $out, "@cmdline |");
|
|
||||||
|
|
||||||
my @log = bzr_log($out);
|
my @log = bzr_log($out);
|
||||||
|
|
||||||
if (length @log < 1) {
|
if (length @log < 1) {
|
||||||
|
@ -303,12 +299,22 @@ sub rcs_getctime ($) {
|
||||||
eval q{use Date::Parse};
|
eval q{use Date::Parse};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
my $ctime = str2time($log[0]->{"timestamp"});
|
my $time = str2time($log[0]->{"timestamp"});
|
||||||
return $ctime;
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rcs_getctime ($) {
|
||||||
|
my ($file) = @_;
|
||||||
|
|
||||||
|
my @cmdline = ("bzr", "log", "--forward", "--limit", '1', "$config{srcdir}/$file");
|
||||||
|
return extract_timestamp(@cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_getmtime ($) {
|
sub rcs_getmtime ($) {
|
||||||
error "rcs_getmtime is not implemented for bzr\n"; # TODO
|
my ($file) = @_;
|
||||||
|
|
||||||
|
my @cmdline = ("bzr", "log", "--limit", '1', "$config{srcdir}/$file");
|
||||||
|
return extract_timestamp(@cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -338,7 +338,7 @@ sub editcomment ($$) {
|
||||||
my $page = $form->field('page');
|
my $page = $form->field('page');
|
||||||
$page = IkiWiki::possibly_foolish_untaint($page);
|
$page = IkiWiki::possibly_foolish_untaint($page);
|
||||||
if (! defined $page || ! length $page ||
|
if (! defined $page || ! length $page ||
|
||||||
IkiWiki::file_pruned($page, $config{srcdir})) {
|
IkiWiki::file_pruned($page)) {
|
||||||
error(gettext("bad page name"));
|
error(gettext("bad page name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +548,7 @@ sub commentmoderation ($$) {
|
||||||
# pending comment before untainting.
|
# pending comment before untainting.
|
||||||
my ($f)= $id =~ /$config{wiki_file_regexp}/;
|
my ($f)= $id =~ /$config{wiki_file_regexp}/;
|
||||||
if (! defined $f || ! length $f ||
|
if (! defined $f || ! length $f ||
|
||||||
IkiWiki::file_pruned($f, $config{srcdir})) {
|
IkiWiki::file_pruned($f)) {
|
||||||
error("illegal file");
|
error("illegal file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,18 +644,14 @@ sub comments_pending () {
|
||||||
find({
|
find({
|
||||||
no_chdir => 1,
|
no_chdir => 1,
|
||||||
wanted => sub {
|
wanted => sub {
|
||||||
$_=decode_utf8($_);
|
my $file=decode_utf8($_);
|
||||||
if (IkiWiki::file_pruned($_, $dir)) {
|
$file=~s/^\Q$dir\E\/?//;
|
||||||
$File::Find::prune=1;
|
return if ! length $file || IkiWiki::file_pruned($file)
|
||||||
}
|
|| -l $_ || -d _ || $file !~ /\Q._comment\E$/;
|
||||||
elsif (! -l $_ && ! -d _) {
|
my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint
|
||||||
$File::Find::prune=0;
|
if (defined $f) {
|
||||||
my ($f)=/$config{wiki_file_regexp}/; # untaint
|
my $ctime=(stat($_))[10];
|
||||||
if (defined $f && $f =~ /\Q._comment\E$/) {
|
push @ret, [$f, $ctime];
|
||||||
my $ctime=(stat($f))[10];
|
|
||||||
$f=~s/^\Q$dir\E\/?//;
|
|
||||||
push @ret, [$f, $ctime];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, $dir);
|
}, $dir);
|
||||||
|
|
|
@ -63,7 +63,7 @@ sub file_in_vc ($$) {
|
||||||
}
|
}
|
||||||
my $found=0;
|
my $found=0;
|
||||||
while (<DARCS_MANIFEST>) {
|
while (<DARCS_MANIFEST>) {
|
||||||
$found = 1, last if /^(\.\/)?$file$/;
|
$found = 1 if /^(\.\/)?$file$/;
|
||||||
}
|
}
|
||||||
close(DARCS_MANIFEST) or error("'darcs query manifest' exited " . $?);
|
close(DARCS_MANIFEST) or error("'darcs query manifest' exited " . $?);
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,9 @@ sub cgi_editpage ($$) {
|
||||||
# wiki_file_regexp.
|
# wiki_file_regexp.
|
||||||
my ($page)=$form->field('page')=~/$config{wiki_file_regexp}/;
|
my ($page)=$form->field('page')=~/$config{wiki_file_regexp}/;
|
||||||
$page=possibly_foolish_untaint($page);
|
$page=possibly_foolish_untaint($page);
|
||||||
my $absolute=($page =~ s#^/+##);
|
my $absolute=($page =~ s#^/+##); # absolute name used to force location
|
||||||
if (! defined $page || ! length $page ||
|
if (! defined $page || ! length $page ||
|
||||||
file_pruned($page, $config{srcdir})) {
|
file_pruned($page)) {
|
||||||
error(gettext("bad page name"));
|
error(gettext("bad page name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,8 +220,7 @@ sub cgi_editpage ($$) {
|
||||||
my $best_loc;
|
my $best_loc;
|
||||||
if (! defined $from || ! length $from ||
|
if (! defined $from || ! length $from ||
|
||||||
$from ne $form->field('from') ||
|
$from ne $form->field('from') ||
|
||||||
file_pruned($from, $config{srcdir}) ||
|
file_pruned($from) ||
|
||||||
$from=~/^\// ||
|
|
||||||
$absolute ||
|
$absolute ||
|
||||||
$form->submitted) {
|
$form->submitted) {
|
||||||
@page_locs=$best_loc=$page;
|
@page_locs=$best_loc=$page;
|
||||||
|
|
|
@ -105,11 +105,13 @@ sub formbuilder_setup (@) {
|
||||||
my $session=$params{session};
|
my $session=$params{session};
|
||||||
my $cgi=$params{cgi};
|
my $cgi=$params{cgi};
|
||||||
|
|
||||||
if ($form->title eq "signin" || $form->title eq "register" || $cgi->param("do") eq "register") {
|
my $do_register=defined $cgi->param("do") && $cgi->param("do") eq "register";
|
||||||
|
|
||||||
|
if ($form->title eq "signin" || $form->title eq "register" || $do_register) {
|
||||||
$form->field(name => "name", required => 0);
|
$form->field(name => "name", required => 0);
|
||||||
$form->field(name => "password", type => "password", required => 0);
|
$form->field(name => "password", type => "password", required => 0);
|
||||||
|
|
||||||
if ($form->submitted eq "Register" || $form->submitted eq "Create Account" || $cgi->param("do") eq "register") {
|
if ($form->submitted eq "Register" || $form->submitted eq "Create Account" || $do_register) {
|
||||||
$form->field(name => "confirm_password", type => "password");
|
$form->field(name => "confirm_password", type => "password");
|
||||||
$form->field(name => "account_creation_password", type => "password")
|
$form->field(name => "account_creation_password", type => "password")
|
||||||
if (defined $config{account_creation_password} &&
|
if (defined $config{account_creation_password} &&
|
||||||
|
@ -247,8 +249,10 @@ sub formbuilder (@) {
|
||||||
my $cgi=$params{cgi};
|
my $cgi=$params{cgi};
|
||||||
my $buttons=$params{buttons};
|
my $buttons=$params{buttons};
|
||||||
|
|
||||||
|
my $do_register=defined $cgi->param("do") && $cgi->param("do") eq "register";
|
||||||
|
|
||||||
if ($form->title eq "signin" || $form->title eq "register") {
|
if ($form->title eq "signin" || $form->title eq "register") {
|
||||||
if (($form->submitted && $form->validate) || $cgi->param("do") eq "register") {
|
if (($form->submitted && $form->validate) || $do_register) {
|
||||||
if ($form->submitted eq 'Login') {
|
if ($form->submitted eq 'Login') {
|
||||||
$session->param("name", $form->field("name"));
|
$session->param("name", $form->field("name"));
|
||||||
IkiWiki::cgi_postsignin($cgi, $session);
|
IkiWiki::cgi_postsignin($cgi, $session);
|
||||||
|
@ -311,7 +315,7 @@ sub formbuilder (@) {
|
||||||
$form->field(name => "name", required => 0);
|
$form->field(name => "name", required => 0);
|
||||||
push @$buttons, "Reset Password";
|
push @$buttons, "Reset Password";
|
||||||
}
|
}
|
||||||
elsif ($form->submitted eq "Register" || $cgi->param("do") eq "register") {
|
elsif ($form->submitted eq "Register" || $do_register) {
|
||||||
@$buttons="Create Account";
|
@$buttons="Create Account";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,8 @@ sub check_canrename ($$$$$$) {
|
||||||
error(gettext("no change to the file name was specified"));
|
error(gettext("no change to the file name was specified"));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Must be a legal filename, and not absolute.
|
# Must be a legal filename.
|
||||||
if (IkiWiki::file_pruned($destfile, $config{srcdir}) ||
|
if (IkiWiki::file_pruned($destfile)) {
|
||||||
$destfile=~/^\//) {
|
|
||||||
error(sprintf(gettext("illegal name")));
|
error(sprintf(gettext("illegal name")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ sub index (@) {
|
||||||
|
|
||||||
# A unique pageterm is used to identify the document for a page.
|
# A unique pageterm is used to identify the document for a page.
|
||||||
my $pageterm=pageterm($params{page});
|
my $pageterm=pageterm($params{page});
|
||||||
return $params{content} unless defined $pageterm;
|
return unless defined $pageterm;
|
||||||
|
|
||||||
my $db=xapiandb();
|
my $db=xapiandb();
|
||||||
my $doc=Search::Xapian::Document->new();
|
my $doc=Search::Xapian::Document->new();
|
||||||
|
|
|
@ -82,7 +82,7 @@ sub test () {
|
||||||
my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
|
my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
|
||||||
$file=IkiWiki::possibly_foolish_untaint($file);
|
$file=IkiWiki::possibly_foolish_untaint($file);
|
||||||
if (! defined $file || ! length $file ||
|
if (! defined $file || ! length $file ||
|
||||||
IkiWiki::file_pruned($file, $config{srcdir})) {
|
IkiWiki::file_pruned($file)) {
|
||||||
error(gettext("bad file name %s"), $file);
|
error(gettext("bad file name %s"), $file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,13 +366,13 @@ sub find_new_files ($) {
|
||||||
push @internal_new, $file;
|
push @internal_new, $file;
|
||||||
}
|
}
|
||||||
elsif ($config{rcs}) {
|
elsif ($config{rcs}) {
|
||||||
if (! $times_noted) {
|
|
||||||
debug(sprintf(gettext("querying %s for file creation and modification times.."), $config{rcs}));
|
|
||||||
$times_noted=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
push @new, $file;
|
push @new, $file;
|
||||||
if ($config{gettime} && -e "$config{srcdir}/$file") {
|
if ($config{gettime} && -e "$config{srcdir}/$file") {
|
||||||
|
if (! $times_noted) {
|
||||||
|
debug(sprintf(gettext("querying %s for file creation and modification times.."), $config{rcs}));
|
||||||
|
$times_noted=1;
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
my $ctime=rcs_getctime("$config{srcdir}/$file");
|
my $ctime=rcs_getctime("$config{srcdir}/$file");
|
||||||
if ($ctime > 0) {
|
if ($ctime > 0) {
|
||||||
|
@ -431,7 +431,7 @@ sub remove_del (@) {
|
||||||
foreach my $file (@_) {
|
foreach my $file (@_) {
|
||||||
my $page=pagename($file);
|
my $page=pagename($file);
|
||||||
if (! isinternal($page)) {
|
if (! isinternal($page)) {
|
||||||
debug(sprintf(gettext("removing old page %s"), $page));
|
debug(sprintf(gettext("removing obsolete %s"), $page));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $old (@{$oldrenderedfiles{$page}}) {
|
foreach my $old (@{$oldrenderedfiles{$page}}) {
|
||||||
|
@ -634,34 +634,35 @@ sub render_dependent ($$$$$$$) {
|
||||||
if ($type == $IkiWiki::DEPEND_LINKS) {
|
if ($type == $IkiWiki::DEPEND_LINKS) {
|
||||||
next unless $linkchangers->{lc($page)};
|
next unless $linkchangers->{lc($page)};
|
||||||
}
|
}
|
||||||
return $page;
|
$reason=$page;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_CONTENT) {
|
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_CONTENT) {
|
||||||
last if $reason =
|
last if $in->(\@changed, $IkiWiki::DEPEND_CONTENT);
|
||||||
$in->(\@changed, $IkiWiki::DEPEND_CONTENT);
|
last if $internal_dep && (
|
||||||
last if $internal_dep && ($reason =
|
|
||||||
$in->($internal_new, $IkiWiki::DEPEND_CONTENT) ||
|
$in->($internal_new, $IkiWiki::DEPEND_CONTENT) ||
|
||||||
$in->($internal_del, $IkiWiki::DEPEND_CONTENT) ||
|
$in->($internal_del, $IkiWiki::DEPEND_CONTENT) ||
|
||||||
$in->($internal_changed, $IkiWiki::DEPEND_CONTENT));
|
$in->($internal_changed, $IkiWiki::DEPEND_CONTENT)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_PRESENCE) {
|
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_PRESENCE) {
|
||||||
last if $reason =
|
last if $in->(\@exists_changed, $IkiWiki::DEPEND_PRESENCE);
|
||||||
$in->(\@exists_changed, $IkiWiki::DEPEND_PRESENCE);
|
last if $internal_dep && (
|
||||||
last if $internal_dep && ($reason =
|
|
||||||
$in->($internal_new, $IkiWiki::DEPEND_PRESENCE) ||
|
$in->($internal_new, $IkiWiki::DEPEND_PRESENCE) ||
|
||||||
$in->($internal_del, $IkiWiki::DEPEND_PRESENCE));
|
$in->($internal_del, $IkiWiki::DEPEND_PRESENCE)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_LINKS) {
|
if ($depends{$p}{$dep} & $IkiWiki::DEPEND_LINKS) {
|
||||||
last if $reason =
|
last if $in->(\@changed, $IkiWiki::DEPEND_LINKS);
|
||||||
$in->(\@changed, $IkiWiki::DEPEND_LINKS);
|
last if $internal_dep && (
|
||||||
last if $internal_dep && ($reason =
|
|
||||||
$in->($internal_new, $IkiWiki::DEPEND_LINKS) ||
|
$in->($internal_new, $IkiWiki::DEPEND_LINKS) ||
|
||||||
$in->($internal_del, $IkiWiki::DEPEND_LINKS) ||
|
$in->($internal_del, $IkiWiki::DEPEND_LINKS) ||
|
||||||
$in->($internal_changed, $IkiWiki::DEPEND_LINKS));
|
$in->($internal_changed, $IkiWiki::DEPEND_LINKS)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ ikiwiki (3.20100415) UNRELEASED; urgency=low
|
||||||
timestamps on basewiki files shipped in the deb are sane.
|
timestamps on basewiki files shipped in the deb are sane.
|
||||||
* autoindex: Switch to using %wikistate instead of abusing
|
* autoindex: Switch to using %wikistate instead of abusing
|
||||||
$pagestate{index}.
|
$pagestate{index}.
|
||||||
|
* bzr: Support rcs_getmtime, and fix rcs_getctime implementation
|
||||||
|
(Jelmer Vernooij)
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Sun, 04 Apr 2010 12:17:11 -0400
|
-- Joey Hess <joeyh@debian.org> Sun, 04 Apr 2010 12:17:11 -0400
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,10 @@ think about merging them. This is recommended. :-)
|
||||||
|
|
||||||
## branches
|
## branches
|
||||||
|
|
||||||
|
In order to refer to a branch in one of the above git repositories, for
|
||||||
|
example when submitting a [[patch]], you can use the
|
||||||
|
[[templates/gitbranch]] template.
|
||||||
|
|
||||||
Some of the branches included in the main repository include:
|
Some of the branches included in the main repository include:
|
||||||
|
|
||||||
* `gallery` contains the [[todo/Gallery]] plugin. It's not yet merged
|
* `gallery` contains the [[todo/Gallery]] plugin. It's not yet merged
|
||||||
|
|
|
@ -120,7 +120,7 @@ Personal sites and blogs
|
||||||
* [[Adam_Trickett|ajt]]'s home intranet/sanbox system ([Internet site & blog](http://www.iredale.net/) -- not ikiwiki yet)
|
* [[Adam_Trickett|ajt]]'s home intranet/sanbox system ([Internet site & blog](http://www.iredale.net/) -- not ikiwiki yet)
|
||||||
* [[Simon_McVittie|smcv]]'s [website](http://www.pseudorandom.co.uk/) and
|
* [[Simon_McVittie|smcv]]'s [website](http://www.pseudorandom.co.uk/) and
|
||||||
[blog](http://smcv.pseudorandom.co.uk/)
|
[blog](http://smcv.pseudorandom.co.uk/)
|
||||||
* Svend's [website](http://www.ciffer.net/~svend/) and [blog](http://www.ciffer.net/~svend/blog/)
|
* Svend's [website](http://ciffer.net/~svend/) and [blog](http://ciffer.net/~svend/blog/)
|
||||||
* [muammar's site](http://muammar.me)
|
* [muammar's site](http://muammar.me)
|
||||||
* [Per Bothner's blog](http://per.bothner.com/blog/)
|
* [Per Bothner's blog](http://per.bothner.com/blog/)
|
||||||
* [Bernd Zeimetz (bzed)](http://bzed.de/)
|
* [Bernd Zeimetz (bzed)](http://bzed.de/)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
I'm adding some plugins to Ikiwiki to support a bioacoustic wiki. See here:
|
||||||
|
|
||||||
|
<http://bioacoustics.cse.unsw.edu.au/wiki/>
|
||||||
|
|
||||||
|
Personal home page:
|
||||||
|
|
||||||
|
<http://peteg.org/>
|
|
@ -6,8 +6,7 @@ histories.
|
||||||
Ikiwiki started out supporting only [[Subversion|svn]], but the interface
|
Ikiwiki started out supporting only [[Subversion|svn]], but the interface
|
||||||
ikiwiki uses to a revision control system is sufficiently simple and
|
ikiwiki uses to a revision control system is sufficiently simple and
|
||||||
generic that it can be adapted to work with many systems by writing a
|
generic that it can be adapted to work with many systems by writing a
|
||||||
[[plugin|plugins/write]]. [[Subversion|svn]] is still a recommended choice;
|
[[plugin|plugins/write]]. These days, most people use [[git]].
|
||||||
[[git]] is another well-tested option.
|
|
||||||
|
|
||||||
While all supported revision control systems work well enough for basic
|
While all supported revision control systems work well enough for basic
|
||||||
use, some advanced or special features are not supported in all of them.
|
use, some advanced or special features are not supported in all of them.
|
||||||
|
@ -28,7 +27,7 @@ auto.setup |yes |yes |incomplete|yes |incomplete |yes
|
||||||
`rcs_remove` |yes |yes |yes |yes |no |yes |no |yes
|
`rcs_remove` |yes |yes |yes |yes |no |yes |no |yes
|
||||||
`rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes
|
`rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes
|
||||||
`rcs_getctime` |fast |slow |slow |slow |slow |slow |slow |slow
|
`rcs_getctime` |fast |slow |slow |slow |slow |slow |slow |slow
|
||||||
`rcs_getmtime` |fast |slow |no |no |no |no |no |no
|
`rcs_getmtime` |fast |slow |slow |no |no |no |no |no
|
||||||
anonymous push |yes |no |no |no |no |no |no |no
|
anonymous push |yes |no |no |no |no |no |no |no
|
||||||
conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes
|
conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes
|
||||||
"""]]
|
"""]]
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
[GNU](http://www.gnu.org/) [Arch](http://www.gnuarch.org/) revision control
|
[GNU](http://www.gnu.org/) [Arch](http://www.gnuarch.org/) revision control
|
||||||
system. Ikiwiki supports storing a wiki in tla.
|
system. Ikiwiki supports storing a wiki in tla.
|
||||||
|
|
||||||
|
Warning: Since tla is not being maintained, neither is this plugin, and
|
||||||
|
using ikiwiki with tla is not recommended.
|
||||||
|
|
||||||
Ikiwiki can run as a [[post-commit]] hook to update a wiki whenever commits
|
Ikiwiki can run as a [[post-commit]] hook to update a wiki whenever commits
|
||||||
come in. When running as a [[cgi]] with tla, ikiwiki automatically
|
come in. When running as a [[cgi]] with tla, ikiwiki automatically
|
||||||
commits edited pages to the Arch repostory, and uses the Arch
|
commits edited pages to the Arch repostory, and uses the Arch
|
||||||
|
|
|
@ -56,17 +56,38 @@ and the tags would appear at the bottom of the post, the Rubrica next to the tit
|
||||||
|
|
||||||
Aside from the name of the plugin (and thus of the main directive), which could be `tag`, `meta`, `field` or whatever (maybe extending `meta` would be the most sensible choice), the features we want are
|
Aside from the name of the plugin (and thus of the main directive), which could be `tag`, `meta`, `field` or whatever (maybe extending `meta` would be the most sensible choice), the features we want are
|
||||||
|
|
||||||
1. allow multiple values per type/attribute/field/whatever (fields currently only allows one)
|
1. allow multiple values per type/attribute/field/whatever (fields currently only allows one)
|
||||||
2. allow both hidden and visible references (à la tag vs taglink)
|
* Agreed about multiple values; I've been considering whether I should add that to `field`. -- K.A.
|
||||||
3. allow each type/attribute/field to be exposed under multiple queries (e.g. tags and categories; this is mostly important for backwards compatibility, not sure if it might have other uses too)
|
2. allow both hidden and visible references (a la tag vs taglink)
|
||||||
4. allow arbitrary types/attributes/fields/whatever (even 'undefined' ones)
|
* Hidden and visible references; that's fair enough too. My approach with `ymlfront` and `getfield` is that the YAML code is hidden, and the display is done with `getfield`, but there's no reason not to use additional approaches. -- K.A.
|
||||||
|
3. allow each type/attribute/field to be exposed under multiple queries (e.g. tags and categories; this is mostly important for backwards compatibility, not sure if it might have other uses too)
|
||||||
|
* I'm not sure what you mean here. -- K.A.
|
||||||
|
* Typical example is tags: they are accessible both as `tags` and as `categories`, although the way they are presented changes a little -- G.B.
|
||||||
|
4. allow arbitrary types/attributes/fields/whatever (even 'undefined' ones)
|
||||||
|
* Are you saying that these must be typed, or are you saying that they can be user-defined? -- K.A.
|
||||||
|
* I am saying that the user should be able to define (e.g. in the config) some set of types/fields/attributes/whatever, following the specification illustrated below, but also be able to use something like `\[[!meta somefield="somevalue"]]` where `somefield` was never defined before. In this case `somefield` will have some default values for the properties described in the spec below. -- G.B.
|
||||||
|
|
||||||
Each type/attribute/field/whatever (predefined, user-defined, arbitrary) would thus have the following parameters:
|
Each type/attribute/field/whatever (predefined, user-defined, arbitrary) would thus have the following parameters:
|
||||||
|
|
||||||
* `directive` : the name of the directive that can be used to set the value as a hidden reference; we can discuss whether, for pre- or user-defined types, it being undef means no directive or a default directive matching the attribute name would be defined.
|
* `directive` : the name of the directive that can be used to set the value as a hidden reference; we can discuss whether, for pre- or user-defined types, it being undef means no directive or a default directive matching the attribute name would be defined.
|
||||||
* `linkdirective` : the name of the directive that can be used for a visible reference; no such directive would be defined by default
|
* I still want there to be able to be enough flexibility in the concept to enable plugins such as `yamlfront`, which sets the data using YAML format, rather than using directives. -- K.A.
|
||||||
* `linktype` : link type for (hidden and visible) references
|
* The possibility to use a directive does not preclude other ways of defining the field values. IOW, even if the directive `somefield` is defined, the user would still be able to use the syntax `\[[!meta somefield="somevalue"]]`, or any other syntax (such as YAML). -- G.B.
|
||||||
* `linkbase` : akin to the tagbase parameter
|
* `linkdirective` : the name of the directive that can be used for a visible reference; no such directive would be defined by default
|
||||||
* `queries` : list of template queries this type/attribute/field/whatever is exposed to
|
* `linktype` : link type for (hidden and visible) references
|
||||||
|
* Is this the equivalent to "field name"? -- K.A.
|
||||||
|
* This would be such by default, but it could be set to something different. [[Typed links|matching_different_kinds_of_links]] is a very recent ikiwiki feature. -- G.B.
|
||||||
|
* `linkbase` : akin to the tagbase parameter
|
||||||
|
* Is this a field-name -> directory mapping? -- K.A.
|
||||||
|
* yes, with each directory having one page per value. It might not make sense for all fields, of course -- G.B.
|
||||||
|
* (nods) I've been working on something similar with my unreleased `tagger` module. In that, by default, the field-name maps to the closest wiki-page of the same name. Thus, if one had the field "genre=poetry" on the page fiction/stories/mary/lamb, then that would map to fiction/genre/poetry if fiction/genre existed. --K.A.
|
||||||
|
* that's the idea. In your case you could have the linkbase of genre be fiction/genre, and it would be created if it was missing. -- G.B.
|
||||||
|
* `queries` : list of template queries this type/attribute/field/whatever is exposed to
|
||||||
|
* I'm not sure what you mean here. -- K.A.
|
||||||
|
* as mentioned before, some fields may be made accessible through different template queries, in different form. This is the case already for tags, that also come up in the `categories` query (used by Atom and RSS feeds). -- G.B.
|
||||||
|
* Ah, do you mean that the input value is the same, but the output format is different? Like the difference between TMPL_VAR NAME="FOO" and TMPL_VAR NAME="raw_FOO"; one is htmlized, and the other is not. -- K.A.
|
||||||
|
* Actually this is about the same information appearing in different queries (e.g. NAME="FOO" and NAME="BAR"). Example: say that I defined a "Rubrica" field. I would want both tags and categories to appear in `categories` template query, but only tags would appear in the `tags` query, and only Rubrica values to appear in `rubrica` queries. The issue of different output formats was presented in the next paragraph instead. -- G.B.
|
||||||
|
|
||||||
|
Where this approach is limiting is on the kind of data that is passed to (template) queries. The value of the metadata fields might need some massaging (e.g. compare how tags are passed to tags queries vs cateogires queries, or also see what is done with the fields in the current `meta` plugin). I have problems on picturing an easy way to make this possible user-side (i.e. via templates and not in Perl modules). Suggestions welcome.
|
||||||
|
|
||||||
|
One possibility could be to have the `queries` configuration allow a hash mapping query names to functions that would transform the data. Lacking that possibility, we might have to leave some predefined fields to have custom Perl-side treatment and leave custom fields to be untransformable.
|
||||||
|
|
||||||
Where this approach is limiting is on the kind of data that is passed to (template) queries. The value of the metadata fields might need some massaging (e.g. compare how tags are passed to tags queries vs cateogires queries). I have problems on picturing an easy way to make this possible user-side (i.e. via templates and not in Perl modules). Suggestions welcome.
|
|
||||||
|
|
|
@ -269,14 +269,13 @@ wrong direction.
|
||||||
|
|
||||||
>> True. I'll do that. --[[David_Riebenbauer]]
|
>> True. I'll do that. --[[David_Riebenbauer]]
|
||||||
|
|
||||||
> Seems that `%autofiles` stores plugin names as keys, but never
|
[[!template id=gitbranch branch=origin/autotag author="[[Joey]]"]]
|
||||||
> really uses them. So it could just as easily be an array.
|
I've pushed an autotag branch of my own, which refactors
|
||||||
>
|
things a bit. It is untested so far though. --[[Joey]]
|
||||||
> I'd be happy if the `%del_hash` global were not needed.
|
|
||||||
> Looks like it could be avoided by moving the checks
|
* `verify_src_file` only called from Render.pm
|
||||||
> that `add_autofile` does into the autofile handling loop in
|
* Gets rid of `%del_files`.
|
||||||
> `Render`. (Also, that loop should probably be in its own
|
* Uses `%wikistate`.
|
||||||
> function anyway.) --[[Joey]]
|
|
||||||
|
|
||||||
[f3abeac919c4736429bd3362af6edf51ede8e7fe]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=f3abeac919c4736429bd3362af6edf51ede8e7fe (commitdiff for f3abeac919c4736429bd3362af6edf51ede8e7fe)
|
[f3abeac919c4736429bd3362af6edf51ede8e7fe]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=f3abeac919c4736429bd3362af6edf51ede8e7fe (commitdiff for f3abeac919c4736429bd3362af6edf51ede8e7fe)
|
||||||
[4af4d26582f0c2b915d7102fb4a604b176385748]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=4af4d26582f0c2b915d7102fb4a604b176385748 (commitdiff for 4af4d26582f0c2b915d7102fb4a604b176385748)
|
[4af4d26582f0c2b915d7102fb4a604b176385748]: http://git.liegesta.at/?p=ikiwiki.git;a=commitdiff;h=4af4d26582f0c2b915d7102fb4a604b176385748 (commitdiff for 4af4d26582f0c2b915d7102fb4a604b176385748)
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
If `page.tmpl` is changed, it would be nice if ikiwiki automatically
|
||||||
|
noticed, and rebuilt all pages. If `inlinepage.tmpl` is changed, a rebuild
|
||||||
|
of all pages using it in an inline would be stellar.
|
||||||
|
|
||||||
|
This would allow setting:
|
||||||
|
|
||||||
|
templatedir => "$srcdir/templates",
|
||||||
|
|
||||||
|
.. and then the [[wikitemplates]] are managed like other wiki files; and
|
||||||
|
like other wiki files, a change to them automatically updates dependent
|
||||||
|
pages.
|
||||||
|
|
||||||
|
Originally, it made good sense not to have the templatedir inside the wiki.
|
||||||
|
Those templates can be used to bypass the htmlscrubber, and you don't want
|
||||||
|
just anyone to edit them. But the same can be said of `style.css` and
|
||||||
|
`ikiwiki.js`, which *are* in the wiki. We rely on `allowed_attachments`
|
||||||
|
being set to secure those to prevent users uploading replacements. And we
|
||||||
|
assume that users who can directly (non-anon) commit *can* edit them, and
|
||||||
|
that's ok.
|
||||||
|
|
||||||
|
So, perhaps the easiest way to solve this [[wishlist]] would be to
|
||||||
|
make templatedir *default* to "$srcdir/templates/, and make ikiwiki
|
||||||
|
register dependencies on `page.tmpl`, `inlinepage.tmpl`, etc, as they're
|
||||||
|
used. Although, having every page declare an explicit dep on `page.tmpl`
|
||||||
|
is perhaps a bit much; might be better to implement a special case for that
|
||||||
|
one. Also, having the templates be copied to `destdir` is not desirable.
|
||||||
|
In a sense, these template would be like internal pages, except not wiki
|
||||||
|
pages, but raw files.
|
||||||
|
|
||||||
|
The risk is that a site might have `allowed_attachments` set to
|
||||||
|
`templates/*` or `*.tmpl` something like that. I think such a configuration
|
||||||
|
is the *only* risk, and it's unlikely enough that a NEWS warning should
|
||||||
|
suffice.
|
||||||
|
|
||||||
|
(This would also help to clear up the tricky disctinction between
|
||||||
|
wikitemplates and in-wiki templates.)
|
||||||
|
|
||||||
|
> But would this require that templates be parseable as wiki pages? Because that would be a nuisance. --[[KathrynAndersen]]
|
||||||
|
|
||||||
|
>> It would be better for them not to be rendered separately at all.
|
||||||
|
>> --[[Joey]]
|
||||||
|
|
||||||
|
>>> I don't follow you. --[[KathrynAndersen]]
|
||||||
|
|
||||||
|
>>>> If they don't render to output files, they clearly don't
|
||||||
|
>>>> need to be treated as wiki pages. (They need to be treated
|
||||||
|
>>>> as raw files anyway, because you don't want random users editing them
|
||||||
|
>>>> in the online editor.) --[[Joey]]
|
||||||
|
|
||||||
|
>>>>> Just to be clear, the raw files would not be copied across to the output
|
||||||
|
>>>>> directory? -- [[Jon]]
|
||||||
|
|
||||||
|
>>>>>> Without modifying ikiwiki, they'd be copied to the output directory as
|
||||||
|
>>>>>> (e.g.) http://ikiwiki.info/templates/inlinepage.tmpl; to not copy them,
|
||||||
|
>>>>>> it'd either be necessary to make them be internal pages
|
||||||
|
>>>>>> (templates/inlinepage._tmpl) or special-case them in some other way.
|
||||||
|
>>>>>> --[[smcv]]
|
|
@ -1,4 +1,4 @@
|
||||||
[[!meta title="Svend Sorensen"]]
|
[[!meta title="Svend Sorensen"]]
|
||||||
|
|
||||||
* [website](http://www.ciffer.net/~svend/)
|
* [website](http://ciffer.net/~svend/)
|
||||||
* [blog](http://www.ciffer.net/~svend/blog/)
|
* [blog](http://ciffer.net/~svend/blog/)
|
||||||
|
|
|
@ -12,7 +12,7 @@ BEGIN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
use Test::More tests => 16;
|
use Test::More tests => 17;
|
||||||
|
|
||||||
BEGIN { use_ok("IkiWiki"); }
|
BEGIN { use_ok("IkiWiki"); }
|
||||||
|
|
||||||
|
@ -60,6 +60,9 @@ is($changes[1]{pages}[0]{"page"}, "test1");
|
||||||
my $ctime = IkiWiki::rcs_getctime("test2.mdwn");
|
my $ctime = IkiWiki::rcs_getctime("test2.mdwn");
|
||||||
ok($ctime >= time() - 20);
|
ok($ctime >= time() - 20);
|
||||||
|
|
||||||
|
my $mtime = IkiWiki::rcs_getmtime("test2.mdwn");
|
||||||
|
ok($mtime >= time() - 20);
|
||||||
|
|
||||||
writefile('test3.mdwn', $config{srcdir}, $test1);
|
writefile('test3.mdwn', $config{srcdir}, $test1);
|
||||||
IkiWiki::rcs_add("test3.mdwn");
|
IkiWiki::rcs_add("test3.mdwn");
|
||||||
IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn");
|
IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn");
|
||||||
|
|
|
@ -7,35 +7,34 @@ BEGIN { use_ok("IkiWiki"); }
|
||||||
|
|
||||||
%config=IkiWiki::defaultconfig();
|
%config=IkiWiki::defaultconfig();
|
||||||
|
|
||||||
ok(IkiWiki::file_pruned("src/.htaccess", "src"));
|
ok(IkiWiki::file_pruned(".htaccess"));
|
||||||
ok(IkiWiki::file_pruned("src/.ikiwiki/", "src"));
|
ok(IkiWiki::file_pruned(".ikiwiki/"));
|
||||||
ok(IkiWiki::file_pruned("src/.ikiwiki/index", "src"));
|
ok(IkiWiki::file_pruned(".ikiwiki/index"));
|
||||||
ok(IkiWiki::file_pruned("src/CVS/foo", "src"));
|
ok(IkiWiki::file_pruned("CVS/foo"));
|
||||||
ok(IkiWiki::file_pruned("src/subdir/CVS/foo", "src"));
|
ok(IkiWiki::file_pruned("subdir/CVS/foo"));
|
||||||
ok(IkiWiki::file_pruned("src/.svn", "src"));
|
ok(IkiWiki::file_pruned(".svn"));
|
||||||
ok(IkiWiki::file_pruned("src/subdir/.svn", "src"));
|
ok(IkiWiki::file_pruned("subdir/.svn"));
|
||||||
ok(IkiWiki::file_pruned("src/subdir/.svn/foo", "src"));
|
ok(IkiWiki::file_pruned("subdir/.svn/foo"));
|
||||||
ok(IkiWiki::file_pruned("src/.git", "src"));
|
ok(IkiWiki::file_pruned(".git"));
|
||||||
ok(IkiWiki::file_pruned("src/subdir/.git", "src"));
|
ok(IkiWiki::file_pruned("subdir/.git"));
|
||||||
ok(IkiWiki::file_pruned("src/subdir/.git/foo", "src"));
|
ok(IkiWiki::file_pruned("subdir/.git/foo"));
|
||||||
ok(! IkiWiki::file_pruned("src/svn/fo", "src"));
|
ok(! IkiWiki::file_pruned("svn/fo"));
|
||||||
ok(! IkiWiki::file_pruned("src/git", "src"));
|
ok(! IkiWiki::file_pruned("git"));
|
||||||
ok(! IkiWiki::file_pruned("src/index.mdwn", "src"));
|
ok(! IkiWiki::file_pruned("index.mdwn"));
|
||||||
ok(! IkiWiki::file_pruned("src/index.", "src"));
|
ok(! IkiWiki::file_pruned("index."));
|
||||||
|
ok(IkiWiki::file_pruned("."));
|
||||||
|
ok(IkiWiki::file_pruned("./"));
|
||||||
|
|
||||||
# these are ok because while the filename starts with ".", the canonpathed
|
# absolute filenames are not allowed.
|
||||||
# version does not
|
ok(IkiWiki::file_pruned("/etc/passwd"));
|
||||||
ok(! IkiWiki::file_pruned("src/.", "src"));
|
ok(IkiWiki::file_pruned("//etc/passwd"));
|
||||||
ok(! IkiWiki::file_pruned("src/./", "src"));
|
ok(IkiWiki::file_pruned("/"));
|
||||||
|
ok(IkiWiki::file_pruned("//"));
|
||||||
|
ok(IkiWiki::file_pruned("///"));
|
||||||
|
|
||||||
ok(IkiWiki::file_pruned("src/..", "src"));
|
|
||||||
ok(IkiWiki::file_pruned("src/../", "src"));
|
|
||||||
ok(IkiWiki::file_pruned("src/../", "src"));
|
|
||||||
|
|
||||||
ok(! IkiWiki::file_pruned("src", "src"));
|
ok(IkiWiki::file_pruned(".."));
|
||||||
ok(! IkiWiki::file_pruned("/.foo/src", "/.foo/src"));
|
ok(IkiWiki::file_pruned("../"));
|
||||||
ok(IkiWiki::file_pruned("/.foo/src/.foo/src", "/.foo/src"));
|
|
||||||
ok(! IkiWiki::file_pruned("/.foo/src/index.mdwn", "/.foo/src/index.mdwn"));
|
|
||||||
|
|
||||||
ok(IkiWiki::file_pruned("x/y/foo.dpkg-tmp", "src"));
|
ok(IkiWiki::file_pruned("y/foo.dpkg-tmp"));
|
||||||
ok(IkiWiki::file_pruned("x/y/foo.ikiwiki-new", "src"));
|
ok(IkiWiki::file_pruned("y/foo.ikiwiki-new"));
|
||||||
|
|
Loading…
Reference in New Issue