wishlist feature: marking things to be published in the future

master
Jon Dowland 2012-08-30 16:44:12 +01:00
parent aee3811150
commit 4eb97eea7a
1 changed files with 91 additions and 0 deletions

View File

@ -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(<TMPL_VAR date>)"
then="""[[!tag draft]]"""
else="""[[!meta date="<TMPL_VAR 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(<TMPL_VAR date>)"
then="""[[!tag draft]][[!dirty]]"""
else="""[[!meta date="<TMPL_VAR 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]]