diff options
author | joey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071> | 2007-07-27 05:09:54 +0000 |
---|---|---|
committer | joey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071> | 2007-07-27 05:09:54 +0000 |
commit | 0c481bce6e828613406838bc68ed0958459f6a8c (patch) | |
tree | afc99f4e3e6a98c15a07d38d251fb9ab34543f85 /doc/todo | |
parent | 26bfed13ac23faf7108f861447f3a1bc774c674f (diff) |
web commit by http://ethan.betacantrips.com/: new patch
Diffstat (limited to 'doc/todo')
-rw-r--r-- | doc/todo/pagespec_relative_to_a_target.mdwn | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/doc/todo/pagespec_relative_to_a_target.mdwn b/doc/todo/pagespec_relative_to_a_target.mdwn new file mode 100644 index 000000000..e92988c3e --- /dev/null +++ b/doc/todo/pagespec_relative_to_a_target.mdwn @@ -0,0 +1,89 @@ +Sometimes you want to match a page only if it has certain properties. The use +case I have in mind is this: show me all the pages that have children. You +can't do that with a pagespec, so I created a plugin that adds some pagespec +functions. + +`match_relative(blah)` will match a page x if a pagespec from x would match +`blah`. This is only actually useful with relative pagespecs. + +`match_has_child(blah)` will match a child if it has a descendant named +`blah`. If blah is empty, any child will match. + +So if I have: + +* foo +* foo/blah +* foo/bar +* foo/bar/blah +* foo/bar/bahoo +* foo/baz +* foo/baz/goo +* foo/baz/goo/blah + +A pagespec `match_relative(./blah)` will match `foo/bar/bahoo`, because +a pagespec of `./blah` from `bahoo` would match `foo/bar/blah`. A +pagespec of `match_has_child(blah)` would match `foo`, `foo/bar`, +`foo/baz`, and `foo/baz/goo`. + +Note that if you try to inline `*/blah` you will match `foo/blah`, +`foo/bar/blah`, and `foo/baz/goo/blah` -- that is, the blah pages +themselves rather than any relatives of theirs. + +This patch is useful for (among other things) constructing blogging +systems where leaf nodes are organized hierarchically; using has_child, +you can inline only leaf nodes and ignore "intermediate" nodes. +match_relative can be used recursively to match properties of arbitrary +complexity: "show me all the pages who have children called foo that +have children called blah". I'm not sure what use it is, though. + +You can see the patch in action at +<http://ikidev.betacantrips.com/conditionaltest/>, +so named because I had hoped that something in conditional.pm could +help me. I know the name "relative" sucks, feel free to come up with a +better one. --Ethan + +<pre> +diff -urNX ignorepats ikiwiki/IkiWiki/Plugin/relative.pm ikidev/IkiWiki/Plugin/relative.pm +--- ikiwiki/IkiWiki/Plugin/relative.pm 1969-12-31 16:00:00.000000000 -0800 ++++ ikidev/IkiWiki/Plugin/relative.pm 2007-07-26 21:48:10.642686000 -0700 +@@ -0,0 +1,39 @@ ++#!/usr/bin/perl ++# relative.pm: support for pagespecs on possible matches ++package IkiWiki::Plugin::relative; ++ ++use warnings; ++use strict; ++use IkiWiki 2.00; ++ ++package IkiWiki::PageSpec; ++ ++sub match_relative($$;@) { #{{{ ++ my $parent = shift; ++ my $spec = shift; ++ my %params = @_; ++ ++ foreach my $page (keys %IkiWiki::pagesources) { ++ next if $page eq $parent; ++ if (IkiWiki::pagespec_match($page, $spec, location => $parent)) { ++ return IkiWiki::SuccessReason->new("$parent can match $spec against $page"); ++ } ++ } ++ return IkiWiki::FailReason->new("$parent can't match $spec against anything"); ++} #}}} ++ ++sub match_has_child($$;@) { #{{{ ++ my $page = shift; ++ my $childname = shift; ++ my $spec; ++ if ($childname) { #{{{ ++ $spec = "$page/$childname or $page/*/$childname"; ++ } #}}} ++ else { #{{{ ++ $spec = "$page/*"; ++ } #}}} ++ ++ return match_relative($page, $spec, @_); ++} #}}} ++ ++1 +</pre>
\ No newline at end of file |