From: http://www.cse.unsw.edu.au/~willu/ Date: Sun, 14 Sep 2008 11:04:55 +0000 (-0400) Subject: Add another trial approach for structured data X-Git-Tag: 2.64~11 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8ad716d92c615864a5293b030afc6535e9d92b6f;p=ikiwiki.git Add another trial approach for structured data --- diff --git a/doc/todo/structured_page_data.mdwn b/doc/todo/structured_page_data.mdwn index a8f8d2108..a0a3a9b84 100644 --- a/doc/todo/structured_page_data.mdwn +++ b/doc/todo/structured_page_data.mdwn @@ -104,7 +104,7 @@ See also: >Anyway, I just wanted to list the thoughts. In none of these use cases is straight yaml or json the >obvious answer. -- [[Will]] ->> Okie. I've had a play with this. A plugin is included inline below, but it is only a rough first pass to +>> Okie. I've had a play with this. A 'form' plugin is included inline below, but it is only a rough first pass to >> get a feel for the design space. >> >> The current design defines a new type of page - a 'form'. The type of page holds YAML data @@ -144,8 +144,23 @@ See also: \[[!inline pages="form_eq(age,15)" archive="yes"]] >> will include a link to the page generated above. ->> ->> Anyway, here is the plugin. As noted above this is only a preliminary, exploratory, attempt. -- [[Will]] + +>>> Okie, I've just made another plugin to try and do things in a different way. +>>> This approach adds a 'data' directive. There are two arguments, `key` and `value`. +>>> The directive is replaced by the value. There is also a match function, which is similar +>>> to the one above. It also takes two arguments, a key and a value. It returns true if the +>>> page has that key/value pair in a data directive. e.g.: + + \[[!data key="age" value="15"]] + +>>> then, in another page: + + \[[!inline pages="data_eq(age,15)" archive="yes"]] + +>>> I expect that we could have more match functions for each type of structured data, +>>> I just wanted to implement a rough prototype to get a feel for how it behaves. -- [[Will]] + +>> Anyway, here are the plugins. As noted above these are only preliminary, exploratory, attempts. -- [[Will]] #!/usr/bin/perl # Interpret YAML data to make a web form @@ -362,3 +377,82 @@ See also: } #}}} 1 + +---- + + #!/usr/bin/perl + # Allow data embedded in a page to be checked for + package IkiWiki::Plugin::data; + + use warnings; + use strict; + use IkiWiki 2.00; + + sub import { #{{{ + hook(type => "getsetup", id => "data", call => \&getsetup); + hook(type => "needsbuild", id => "data", call => \&needsbuild); + hook(type => "preprocess", id => "data", call => \&preprocess, scan => 1); + } # }}} + + sub getsetup () { #{{{ + return + plugin => { + safe => 1, + rebuild => 1, # format plugin + }, + } #}}} + + sub needsbuild (@) { #{{{ + my $needsbuild=shift; + foreach my $page (keys %pagestate) { + if (exists $pagestate{$page}{data}) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { + # remove state, it will be re-added + # if the preprocessor directive is still + # there during the rebuild + delete $pagestate{$page}{data}; + } + } + } + } + + sub preprocess (@) { #{{{ + my %params=@_; + + $pagestate{$params{page}}{data}{$params{key}} = $params{value}; + + return IkiWiki::preprocess($params{page}, $params{destpage}, + IkiWiki::filter($params{page}, $params{destpage}, $params{value})) if defined wantarray; + } # }}} + + + package IkiWiki::PageSpec; + + sub match_data_eq ($$;@) { #{{{ + my $page=shift; + my $argSet=shift; + my @args=split(/,/, $argSet); + my $key=shift @args; + my $value=shift @args; + + my $file = $IkiWiki::pagesources{$page}; + + if (! exists $IkiWiki::pagestate{$page}{data}) { + return IkiWiki::FailReason->new("page does not contain any data directives"); + } + + if (! exists $IkiWiki::pagestate{$page}{data}{$key}) { + return IkiWiki::FailReason->new("page does not contain data key '$key'"); + } + + my $formVal = $IkiWiki::pagestate{$page}{data}{$key}; + + if ($formVal eq $value) { + return IkiWiki::SuccessReason->new("value matches"); + } else { + return IkiWiki::FailReason->new("value does not match"); + } + } #}}} + + 1