Allow hooks to add sorting functions to pagespec_match_list
authorSimon McVittie <smcv@debian.org>
Wed, 24 Mar 2010 00:29:10 +0000 (00:29 +0000)
committerSimon McVittie <smcv@debian.org>
Wed, 24 Mar 2010 00:29:10 +0000 (00:29 +0000)
IkiWiki.pm
doc/ikiwiki/pagespec/sorting.mdwn
doc/plugins/write.mdwn
t/pagespec_match_list.t

index 022bfe3bd7c0e3901311e7768a7abc5571e756d8..1a4dc47dd8e0fbe2782c8db49f7a1d05bdba7b37 100644 (file)
@@ -2035,7 +2035,11 @@ sub pagespec_match_list ($$;@) {
 
        if (defined $params{sort}) {
                my $f;
-               if ($params{sort} eq 'title') {
+
+               if (exists $hooks{sort}{$params{sort}}{call}) {
+                       $f = sub { $hooks{sort}{$params{sort}}{call}($a, $b) };
+               }
+               elsif ($params{sort} eq 'title') {
                        $f=sub { pagetitle(basename($a)) cmp pagetitle(basename($b)) };
                }
                elsif ($params{sort} eq 'title_natural') {
index 697818a2a944811c043f15d81c872cbd6fa792ea..9007c23bfc1b38cfd8c2ac5fc9f1ad08db608642 100644 (file)
@@ -10,4 +10,6 @@ orders can be specified.
   installed. Orders by title, but numbers in the title are treated
   as such, ("1 2 9 10 20" instead of "1 10 2 20 9")
 
+Plugins can add additional sort orders.
+
 [[!meta robots="noindex, follow"]]
index 96a2aa16d02c84697072f71f51ff63226e29be8b..bfa6617bd554d7f35b2f2f6b253abcf605db1245 100644 (file)
@@ -588,6 +588,21 @@ describes the plugin as a whole. For example:
 This hook is used to inject C code (which it returns) into the `main`
 function of the ikiwiki wrapper when it is being generated.
 
+### sort
+
+       hook(type => "sort", id => "foo", call => \&sort_by_foo);
+
+This hook adds an additional [[ikiwiki/pagespec/sorting]] order or overrides
+an existing one. The callback is given two page names as arguments, and
+returns negative, zero or positive if the first page should come before,
+close to (i.e. undefined order), or after the second page.
+
+For instance, the built-in `title` sort order could be reimplemented as
+
+       sub sort_by_title {
+               pagetitle(basename($_[0])) cmp pagetitle(basename($_[1]));
+       }
+
 ## Exported variables
 
 Several variables are exported to your plugin when you `use IkiWiki;`
index dd5dcc5b087bcff878b9c35e1904fdee856edb7c..b34ee769f6c139425da64ce0e836131254c14458 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 88;
+use Test::More tests => 89;
 
 BEGIN { use_ok("IkiWiki"); }
 
@@ -9,6 +9,8 @@ BEGIN { use_ok("IkiWiki"); }
 $config{srcdir}=$config{destdir}="/dev/null";
 IkiWiki::checkconfig();
 
+hook(type => "sort", id => "path", call => sub { $_[0] cmp $_[1] });
+
 %pagesources=(
        foo => "foo.mdwn",
        foo2 => "foo2.mdwn",
@@ -34,6 +36,8 @@ is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 50)],
 is_deeply([pagespec_match_list("foo", "post/*", sort => "title",
                          filter => sub { $_[0] =~ /3/}) ],
        ["post/1", "post/2"]);
+is_deeply([pagespec_match_list("foo", "*", sort => "path", num => 2)],
+       ["bar", "foo"]);
 my $r=eval { pagespec_match_list("foo", "beep") };
 ok(eval { pagespec_match_list("foo", "beep") } == 0);
 ok(! $@, "does not fail with error when unable to match anything");