if (! defined $session->param("name") ||
! userinfo_get($session->param("name"), "regdate")) {
- $session->param(postsignin => $ENV{QUERY_STRING});
+ $session->param(postsignin => $q->query_string);
cgi_signin($q, $session);
cgi_savesession($session);
exit;
if (-e $oldoutput) {
require IkiWiki::Render;
debug("removing output file $oldoutput");
- IkiWiki::prune($oldoutput);
+ IkiWiki::prune($oldoutput, $config{destdir});
}
}
}
# This is a wrapper around the real prune.
-sub prune ($) {
+sub prune ($;$) {
my $file=shift;
+ my $up_to=shift;
my @keys=IkiWiki::Plugin::amazon_s3::file2keys($file);
}
}
- return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file);
+ return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file, $up_to);
}
1
}
return unless @attachments;
require IkiWiki::Render;
- IkiWiki::prune($dir);
+ IkiWiki::prune($dir, $config{wikistatedir}."/attachments");
# Check the attachments in and trigger a wiki refresh.
if ($config{rcs}) {
my $page=IkiWiki::dirname($f);
my $file="$config{srcdir}/$f";
+ my $filedir=$config{srcdir};
if (! -e $file) {
# old location
$file="$config{wikistatedir}/comments_pending/".$f;
+ $filedir="$config{wikistatedir}/comments_pending";
}
if ($action eq 'Accept') {
}
require IkiWiki::Render;
- IkiWiki::prune($file);
+ IkiWiki::prune($file, $filedir);
}
}
}
if ($delete) {
debug(sprintf(gettext("removing old preview %s"), $file));
- IkiWiki::prune("$config{destdir}/$file");
+ IkiWiki::prune("$config{destdir}/$file", $config{destdir});
}
}
elsif (defined $mtime) {
IkiWiki::rcs_remove($_);
}
else {
- IkiWiki::prune("$config{srcdir}/$_");
+ IkiWiki::prune("$config{srcdir}/$_", $config{srcdir});
}
} @todelete;
},
}
+sub allowed_dirs {
+ return grep { defined $_ } (
+ $config{srcdir},
+ $IkiWiki::Plugin::transient::transientdir,
+ );
+}
+
sub check_canremove ($$$) {
my $page=shift;
my $q=shift;
htmllink("", "", $page, noimageinline => 1)));
}
- # Must exist on disk, and be a regular file.
+ # Must exist in either the srcdir or a suitable underlay (e.g.
+ # transient underlay), and be a regular file.
my $file=$pagesources{$page};
- if (! -e "$config{srcdir}/$file") {
+ my $dir;
+
+ foreach my $srcdir (allowed_dirs()) {
+ if (-e "$srcdir/$file") {
+ $dir = $srcdir;
+ last;
+ }
+ }
+
+ if (! defined $dir) {
error(sprintf(gettext("%s is not in the srcdir, so it cannot be deleted"), $file));
}
- elsif (-l "$config{srcdir}/$file" && ! -f _) {
+ elsif (-l "$dir/$file" && ! -f _) {
error(sprintf(gettext("%s is not a file"), $file));
}
# This is sorta overkill, but better safe than sorry.
if (! defined pagetype($pagesources{$page})) {
if (IkiWiki::Plugin::attachment->can("check_canattach")) {
- IkiWiki::Plugin::attachment::check_canattach($session, $page, "$config{srcdir}/$file");
+ IkiWiki::Plugin::attachment::check_canattach($session, $page, "$dir/$file");
}
else {
error("removal of attachments is not allowed");
my $f=IkiWiki::Plugin::attachment::is_held_attachment($page);
if (defined $f) {
require IkiWiki::Render;
- IkiWiki::prune($f);
+ IkiWiki::prune($f, "$config{wikistatedir}/attachments");
}
}
}
require IkiWiki::Render;
if ($config{rcs}) {
IkiWiki::disable_commit_hook();
- foreach my $file (@files) {
- IkiWiki::rcs_remove($file);
+ }
+ my $rcs_removed = 1;
+
+ foreach my $file (@files) {
+ foreach my $srcdir (allowed_dirs()) {
+ if (-e "$srcdir/$file") {
+ if ($srcdir eq $config{srcdir} && $config{rcs}) {
+ IkiWiki::rcs_remove($file);
+ $rcs_removed = 1;
+ }
+ else {
+ IkiWiki::prune("$srcdir/$file", $srcdir);
+ }
+ }
}
- IkiWiki::rcs_commit_staged(
- message => gettext("removed"),
- session => $session,
- );
- IkiWiki::enable_commit_hook();
- IkiWiki::rcs_update();
}
- else {
- foreach my $file (@files) {
- IkiWiki::prune("$config{srcdir}/$file");
+
+ if ($config{rcs}) {
+ if ($rcs_removed) {
+ IkiWiki::rcs_commit_staged(
+ message => gettext("removed"),
+ session => $session,
+ );
}
+ IkiWiki::enable_commit_hook();
+ IkiWiki::rcs_update();
}
+
IkiWiki::refresh();
IkiWiki::saveindex();
exit 0;
}
-sub postrename ($;$$$) {
+sub postrename ($$$;$$) {
+ my $cgi=shift;
my $session=shift;
my $src=shift;
my $dest=shift;
my $attachment=shift;
- # Load saved form state and return to edit page.
- my $postrename=CGI->new($session->param("postrename"));
+ # Load saved form state and return to edit page, using stored old
+ # cgi state. Or, if the rename was not started on the edit page,
+ # return to the renamed page.
+ my $postrename=$session->param("postrename");
+ if (! defined $postrename) {
+ IkiWiki::redirect($cgi, urlto(defined $dest ? $dest : $src));
+ exit;
+ }
+ my $oldcgi=CGI->new($postrename);
$session->clear("postrename");
IkiWiki::cgi_savesession($session);
# They renamed the page they were editing. This requires
# fixups to the edit form state.
# Tweak the edit form to be editing the new page.
- $postrename->param("page", $dest);
+ $oldcgi->param("page", $dest);
}
# Update edit form content to fix any links present
# on it.
- $postrename->param("editcontent",
+ $oldcgi->param("editcontent",
renamepage_hook($dest, $src, $dest,
- $postrename->param("editcontent")));
+ $oldcgi->param("editcontent")));
# Get a new edit token; old was likely invalidated.
- $postrename->param("rcsinfo",
+ $oldcgi->param("rcsinfo",
IkiWiki::rcs_prepedit($pagesources{$dest}));
}
- IkiWiki::cgi_editpage($postrename, $session);
+ IkiWiki::cgi_editpage($oldcgi, $session);
}
sub formbuilder (@) {
my $session=shift;
my ($form, $buttons)=rename_form($q, $session, Encode::decode_utf8($q->param("page")));
IkiWiki::decode_form_utf8($form);
+ my $src=$form->field("page");
if ($form->submitted eq 'Cancel') {
- postrename($session);
+ postrename($q, $session, $src);
}
elsif ($form->submitted eq 'Rename' && $form->validate) {
IkiWiki::checksessionexpiry($q, $session, $q->param('sid'));
# These untaints are safe because of the checks
# performed in check_canrename later.
- my $src=$form->field("page");
my $srcfile=IkiWiki::possibly_foolish_untaint($pagesources{$src})
if exists $pagesources{$src};
my $dest=IkiWiki::possibly_foolish_untaint(titlepage($form->field("new_name")));
IkiWiki::Plugin::attachment::is_held_attachment($src);
if ($held) {
rename($held, IkiWiki::Plugin::attachment::attachment_holding_location($dest));
- postrename($session, $src, $dest, $q->param("attachment"))
+ postrename($q, $session, $src, $dest, $q->param("attachment"))
unless defined $srcfile;
}
$renamesummary.=$template->output;
}
- postrename($session, $src, $dest, $q->param("attachment"));
+ postrename($q, $session, $src, $dest, $q->param("attachment"));
}
else {
IkiWiki::showform($form, $buttons, $session, $q);
my $casualty = "$transientdir/$file";
if (srcfile($file) ne $casualty && -e $casualty) {
debug(sprintf(gettext("removing transient version of %s"), $file));
- IkiWiki::prune($casualty);
+ IkiWiki::prune($casualty, $transientdir);
}
}
}
}
}
-sub prune ($) {
+sub prune ($;$) {
my $file=shift;
+ my $up_to=shift;
unlink($file);
my $dir=dirname($file);
- while (rmdir($dir)) {
+ while ((! defined $up_to || $dir =~ m{^\Q$up_to\E\/}) && rmdir($dir)) {
$dir=dirname($dir);
}
}
}
foreach my $old (@{$oldrenderedfiles{$page}}) {
- prune($config{destdir}."/".$old);
+ prune($config{destdir}."/".$old, $config{destdir});
}
foreach my $source (keys %destsources) {
foreach my $file (@{$oldrenderedfiles{$page}}) {
if (! grep { $_ eq $file } @{$renderedfiles{$page}}) {
debug(sprintf(gettext("removing %s, no longer built by %s"), $file, $page));
- prune($config{destdir}."/".$file);
+ prune($config{destdir}."/".$file, $config{destdir});
}
}
}
remove_unrendered();
foreach my $page (keys %oldrenderedfiles) {
foreach my $file (@{$oldrenderedfiles{$page}}) {
- prune($config{destdir}."/".$file);
+ prune($config{destdir}."/".$file, $config{destdir});
}
}
}
* passwordauth: Fix url in password recovery email to be absolute.
* httpauth: When it's the only auth method, avoid a pointless and
confusing signin form, and go right to the httpauthurl.
+ * rename: Allow rename to be started not from the edit page; return to
+ the renamed page in this case.
+ * remove: Support removing of pages in the transient underlay. (smcv)
-- Joey Hess <joeyh@debian.org> Wed, 21 Mar 2012 14:33:14 -0400
--- /dev/null
+Definition lists do not look great here...
+
+Here is an example.
+
+<dl>
+<dt>this is a term</dt>
+<dd>and this is its definition.</dd>
+</dl>
+
+(This wiki doesn't support Markdown's extended definition lists, but still, this is valid markup.)
+
+I believe `<dt>` should be made bold. I have added this to my `local.css`, and I would hate to add this all the time forever:
+
+ /* definition lists look better with the term in bold */
+ dt
+ {
+ font-weight: bold;
+ }
+
+:) How does that look? I can provide a patch for the base wiki if you guys really want... ;) -- [[anarcat]]
+
+> What you dislike seems to be the default rendering of definition lists by
+> browsers. I don't think it's ikiwiki's place to override browser defaults
+> for standard markup in the document body, at least not in the default
+> antitheme. --[[Joey]]
>>> The right fix would probably be for `do=create` to allow replacing a page
>>> in the transient underlay without complaining (like the behaviour that
->>> `do=edit` normally has). That wouldn't help you unless [[plugins/autoindex]]
+>>> `do=edit` normally has).
+
+>>>> ... which it turns out it already does. --[[smcv]]
+
+>>> That wouldn't help you unless [[plugins/autoindex]]
>>> defaulted to making transient pages (`autoindex_commit => 0`), but if we
>>> can fix [[removal_of_transient_pages]] then maybe that default can change?
>>> --[[smcv]]
+
+>>>> It turns out that with `autoindex_commit => 0`, the failure mode is
+>>>> different. The transient map is created when you attach the
+>>>> attachment. When you save the page, it's written into the srcdir,
+>>>> the map is deleted from the transientdir, and the ctime/mtime
+>>>> in the indexdb are those of the file in the srcdir, but for some
+>>>> reason the HTML output isn't re-generated (despite a refresh
+>>>> happening). --[[smcv]]
> I think it was possibly a mistake to use wikilink style lookup for
> `pagenames`. --[[Joey]]
+
+[[!tag patch]] [[!template id=gitbranch branch=smcv/literal-pagenames author="[[smcv]]"]]
+>> I used the linking rules to make references to
+>> "nearby" pages convenient, but if you'd prefer "absolute"
+>> semantics, my `ready/literal-pagenames` branch does that. For
+>> my main use-case for `pagenames` ([[plugins/contrib/album]])
+>> it's fine either way. --[[smcv]]
>>>> to affect by web edits. The `-f` check seems rather redundant,
>>>> surely if it's in `%pagesources` ikiwiki has already verified it's
>>>> safe. --[[Joey]]
+
+----
+
+[[!template id=gitbranch branch=smcv/ready/transient-rm author="[[Simon McVittie|smcv]]"]]
+
+Here's a branch. It special-cases the `$transientdir`, but in such a way
+that the special case could easily be extended to other locations where
+deletion should be allowed.
+
+It also changes `IkiWiki::prune()` to optionally stop pruning empty
+parent directories at the point where you'd expect it to (for instance,
+previously it would remove the `$transientdir` itself, if it turns out
+to be empty), and updates callers.
+
+The new `prune` API looks like this:
+
+ IkiWiki::prune("$config{srcdir}/$file", $config{srcdir});
+
+with the second argument optional. I wonder whether it ought to look
+more like `writefile`:
+
+ IkiWiki::prune($config{srcdir}, $file);
+
+although that would be either an incompatible change to internal API
+(forcing all callers to update to 2-argument), or being a bit
+inconsistent between the one-and two-argument forms. Thoughts?
+
+--[[smcv]]
+
+> I've applied the branch as-is, so this bug is [[done]].
+> `prune` is not an exported API so changing it would be ok..
+> I think required 2-argument would be better, but have not checked
+> all the call sites to see if the `$file` is available split out
+> as that would need. --[[Joey]]
the expected behavior is to compensate for the modified root directory (i.e., show index instead of doc/index).
> This seems to work OK now - commit 84c4ca33 and its reversion both
-> appear correctly in [[recentchanges]]. --[[smcv]]
+> appear correctly in [[recentchanges]]. Looking at git history,
+> Joey [[fixed this|done]] in commit 1b6c1895 before 3.20120203.
+> --[[smcv]]
----
-[[!template id=gitbranch branch=smcv/album3 author="[[Simon_McVittie|smcv]]"]]
+[[!template id=gitbranch branch=smcv/album4 author="[[Simon_McVittie|smcv]]"]]
-Available from [[smcv]]'s git repository, in the `album3` branch.
+Available from [[smcv]]'s git repository, in the `album4` branch.
I've called it `album` to distinguish it from
[[contrib/gallery|plugins/contrib/gallery]], although `gallery` might well be
a better name for this functionality.
the best it can do as a fallback for non-Javascript browsers
is to provide a direct link to the image.)
-Updated, November 2011: rebased onto [[trail]] v3, CSS adjusted.
+Updated, April 2012: rebased onto the version of [[trail]] that got merged
## Manual installation
-If you don't want to use a branch of ikiwiki, manual installation requires
-these files (use the "raw" link in gitweb to download), in addition to the
-ones needed by [[trail]]:
+First, you need a version of ikiwiki with the [[trail]] plugin merged in
+(version 3.20120203 or later).
-* [album.pm](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/IkiWiki/Plugin/album.pm)
+Manual installation requires these files (use the "raw" link in gitweb
+to download):
+
+* [album.pm](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/IkiWiki/Plugin/album.pm)
in an `IkiWiki/Plugin` subdirectory of your configured `plugindir`
-* [albumviewer.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/templates/albumviewer.tmpl),
- [albumitem.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/templates/albumitem.tmpl),
- [albumnext.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/templates/albumnext.tmpl) and
- [albumprev.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/templates/albumprev.tmpl),
+* [albumviewer.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/templates/albumviewer.tmpl),
+ [albumitem.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/templates/albumitem.tmpl),
+ [albumnext.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/templates/albumnext.tmpl) and
+ [albumprev.tmpl](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/templates/albumprev.tmpl),
in your configured `templatedir`, or a `templates` subdirectory of your wiki repository
* the album-related bits from the end of the
- [stylesheet](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album3:/doc/style.css)
+ [stylesheet](http://git.pseudorandom.co.uk/smcv/ikiwiki.git/blob/album4:/doc/style.css)
(put them in your local.css)
## Demo
* Remove compatability code in `loadindex` to handle old index data layouts.
* Make pagespecs match relative by default? (see [[discussion]])
* Flip wikilinks? (see [[todo/link_plugin_perhaps_too_general?]] and [[todo/do_not_make_links_backwards]])
-* YADA format setup files per default?
* Enable tagbase by default (so that tag autocreation will work by default).
Note that this is already done for wikis created by `auto-blog.setup`.
* [[tips/html5]] on by default (some day..)
* Remove support for old `.ikiwiki/comments_pending` from comment plugin.
-* Use yaml formatted setup files by default. (Not too compatability breaking
- really.)
In general, we try to use [[ikiwiki-transition]] or forced rebuilds on
upgrade to deal with changes that break compatability. Some things that
# future goals
-* Conversion support for existing other wikis.
- (Being worked on for MoinMoin and TWiki by [[Josh_Triplett|JoshTriplett]]
- and Jamey Sharp; support for other wikis should fit into the same
- framework.)
+* Conversion support for existing other wikis. See [[convert]].
* [[TODO]], [[bugs]], ...
>>> That style of link would work whether the link style was "backwards" or "forwards". Unfortunately it could make some links less readable; after all, there is a reason why one wants to be able to change the link text! But I don't know what proportion of the links are like that. It's a thought, anyway.
>>> --[[KathrynAndersen]]
+>>>> I dislike placing such requirements on the underlay, which is after
+>>>> all, just a subset of pages in this wiki, which many of the people
+>>>> editing may not even realize are part of the underlay. --[[Joey]]
+
>>> Another option for internal links is to just use the regular markdown links instead of `\[[text|link]]` markup, that way it works regardless. Then the documentation for the link plugin just has to state both syntaxes in a safe manner.
>>> I also agree that we should just switch in one shot, although I am worried this means this could be postponed indefinitely.--[[anarcat]]
>>>> I have done just that in my branch: now the underlay only uses wikilinks in the wikilink page, elsewhere regular markdown links are used. I haven't converted the whole of the doc/ directory however, that would be left to the migration. I have written a ikiwik-transition tool to migrate from wikilink to markdown while i was there. --[[anarcat]]
+>>>>> No, that is *not* an option. Relative markdown links **break** when
+>>>>> page A, containing a link, is inlined into page B. --[[Joey]]
+
----
FWIW, I think this change may well be painful, but is a good idea. I can never remember which way around it should be.
--- /dev/null
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 6;
+use File::Path qw(make_path remove_tree);
+
+BEGIN { use_ok("IkiWiki"); }
+BEGIN { use_ok("IkiWiki::Render"); }
+
+%config=IkiWiki::defaultconfig();
+
+remove_tree("t/tmp");
+
+make_path("t/tmp/srcdir/a/b/c");
+make_path("t/tmp/srcdir/d/e/f");
+writefile("a/b/c/d.mdwn", "t/tmp/srcdir", "foo");
+writefile("d/e/f/g.mdwn", "t/tmp/srcdir", "foo");
+IkiWiki::prune("t/tmp/srcdir/d/e/f/g.mdwn");
+ok(-d "t/tmp/srcdir");
+ok(! -e "t/tmp/srcdir/d");
+IkiWiki::prune("t/tmp/srcdir/a/b/c/d.mdwn", "t/tmp/srcdir");
+ok(-d "t/tmp/srcdir");
+ok(! -e "t/tmp/srcdir/a");