Merge branch 'master' of ssh://git.ikiwiki.info
authorJoey Hess <joey@kitenet.net>
Thu, 30 Aug 2012 16:03:32 +0000 (12:03 -0400)
committerJoey Hess <joey@kitenet.net>
Thu, 30 Aug 2012 16:03:32 +0000 (12:03 -0400)
doc/todo/publishing_in_the_future.mdwn [new file with mode: 0644]

diff --git a/doc/todo/publishing_in_the_future.mdwn b/doc/todo/publishing_in_the_future.mdwn
new file mode 100644 (file)
index 0000000..a3cdace
--- /dev/null
@@ -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]]