diff --git a/doc/todo/publishing_in_the_future.mdwn b/doc/todo/publishing_in_the_future.mdwn new file mode 100644 index 000000000..a3cdacedb --- /dev/null +++ b/doc/todo/publishing_in_the_future.mdwn @@ -0,0 +1,91 @@ +[[!tag wishlist]]I would quite like the ability to write a page (blog post in +practice) but for the page to not be displayed until a date and time after it +is added to the wiki. I've thought this through a bit, but would appreciate +feedback from people before I go any further. Would anyone else find this +useful? + +Thinking about how to implement this in ikiwiki, perhaps a conditional +pagespec would be best (which could be tidied up into a template) + + [[!if test="current_date_before()" + then="""[[!tag draft]]""" + else="""[[!meta date=""]]""" + ]] + +…pre-supposing a scheme whereby tagging 'draft' hides the page from an +aggregation somewhere. With a template, this could collapse to + + [[!template id=publishafter date="Thu Aug 30 14:13:06 BST 2012"]] + +This would require implementing the `current_date_before` pagespec. + +You would also need a regularly scheduled wiki refresh and a way of marking the +unpublished pages as 'dirty' so they were always scanned on refresh until their +publish date has occurred. That could perhaps be implemented via a small plugin +which defined a pagespec which ensured the page was 'dirty': + + [[!if test="current_date_before()" + then="""[[!tag draft]][[!dirty]]""" + else="""[[!meta date=""]]""" + ]] + +The following is an attempt at the dirty part: + + #!/usr/bin/perl + package IkiWiki::Plugin::dirty; + # provides a pagespec 'dirty' which ensures the page will always be + # re-scanned for content on wiki refresh. + + use warnings; + use strict; + use IkiWiki 3.00; + + hook(type => "preprocess", id => "dirty", call => \&preprocess); + hook(type => "needsbuild", id => "dirty", call => \&needsbuild); + + sub preprocess (@) { + my %params = @_; + $pagestate{$params{page}}{dirty}{dirty} = 1; + return ''; + } + + sub needsbuild (@) { + my $pages= shift; + my %p2 = map { $_ => 1 } @$pages; + my %d2 = map { $_ => 1 } @$deleted; + + foreach my $page (keys %pagestate) { + if(exists $pagestate{$page}{dirty}{dirty}) { + push @$pages, $pagesources{$page} unless + (exists $p2{$pagesources{$page}} or exists $d2{$pagesources{$page}}); + delete $pagestate{$page}{dirty}{dirty}; + } + } + + return $pages; + } + + 1 + +Although it doesn't fit, the `current_date_before` pagespec could be implemented +in the same plugin. I tried the following (before the trailing `1`): + + package IkiWiki::PageSpec; + use Date::Parse; + + sub match_current_date_before ($$;@) { + shift; + my $date = shift; + my $out = str2time($date); + if(defined $out) { + return IkiWiki::SuccessReason->new("time before now") if $out < time(); + return IkiWiki::FailReason->new("time not before now"); + } else { return IkiWiki::ErrorReason->new("couldn't parse time $date")}; + } + +I always hit the `ErrorReason` branch when I try to use it, even with strings +which work fine in test scripts. If anyone can help me debug that I'd be very +grateful. +If anyone has any clues as to why this doesn't work + +Thoughts on the whole idea? — [[Jon]]