pedigree: rewrote with different design
authorintrigeri <intrigeri@boum.org>
Tue, 15 Jul 2008 10:35:12 +0000 (12:35 +0200)
committerintrigeri <intrigeri@boum.org>
Tue, 15 Jul 2008 11:06:52 +0000 (13:06 +0200)
(and updated testsuite + docs accordingly)

Signed-off-by: intrigeri <intrigeri@boum.org>
IkiWiki/Plugin/pedigree.pm
doc/plugins/pedigree.mdwn
t/pedigree.t
t/pedigree/templates/pedigree.tmpl

index f91ea94b484a1ce3bde2966b10878aa593c319f2..eb8bfa83b38076ff7b1dd833a5d2f8a92b6a2981 100644 (file)
@@ -18,20 +18,22 @@ sub pedigree ($) { #{{{
        my $path="";
        my $title=$config{wikiname};
        my $i=0;
+       my $depth=0;
+       my $height=0;
 
        my @pagepath=(split("/", $page));
        my $pagedepth=@pagepath;
        foreach my $dir (@pagepath) {
                next if $dir eq 'index';
+               $depth=$i;
+               $height=($pagedepth - $depth);
                push @ret, {
                            url => urlto($path, $page),
                            page => $title,
-                           absdepth => $i,
-                           distance => ($pagedepth - $i),
-                           is_root => ($i eq 0),
-                           is_second_ancestor => ($i eq 1),
-                           is_grand_mother => ($i eq ($pagedepth - 2)),
-                           is_mother => ($i eq ($pagedepth - 1)),
+                           depth => $depth,
+                           height => $height,
+                           "depth_$depth" => 1,
+                           "height_$height" => 1,
                           };
                $path.="/".$dir;
                $title=IkiWiki::pagetitle($dir);
@@ -40,51 +42,14 @@ sub pedigree ($) { #{{{
        return @ret;
 } #}}}
 
-sub forget_oldest ($@) { #{{{
-       my $offset=shift;
-       my @pedigree=@_;
-       my @ret;
-       my $parent;
-       unless ($offset ge scalar(@pedigree)) {
-               for (my $i=0; $i < $offset; $i++) {
-                       shift @pedigree;
-               }
-               while (@pedigree) {
-                       # Doing so does not modify the original @pedigree, we've
-                       # got our own copy of its "content" (i.e. a pile of
-                       # references to hashes)...
-                       $parent=shift @pedigree;
-                       # ... but we have no copy of the referenced hashes, so we
-                       # actually are modifying them in-place, which
-                       # means the second (and following) calls to
-                       # this function overwrite the previous one's
-                       # reldepth values => known bug if PEDIGREE_BUT_ROOT and
-                       # PEDIGREE_BUT_TWO_OLDEST are used in the same template
-                       $parent->{reldepth}=($parent->{absdepth} - $offset);
-                       push @ret, $parent;
-               }
-       }
-       return @ret;
-} #}}}
-
 sub pagetemplate (@) { #{{{
        my %params=@_;
         my $page=$params{page};
         my $template=$params{template};
 
-       my @pedigree=pedigree($page)
-         if ($template->query(name => "pedigree")
-             or $template->query(name => "pedigree_but_root")
-             or $template->query(name => "pedigree_but_two_oldest")
-            );
-
-       $template->param(pedigree => \@pedigree)
-         if ($template->query(name => "pedigree"));
-       $template->param(pedigree_but_root => [forget_oldest(1, @pedigree)])
-         if ($template->query(name => "pedigree_but_root"));
-       $template->param(pedigree_but_two_oldest => [forget_oldest(2, @pedigree)])
-         if ($template->query(name => "pedigree_but_two_oldest"));
-
+       if ($template->query(name => "pedigree")) {
+               $template->param(pedigree => [pedigree($page)]);
+       }
 } # }}}
 
 1
index 41f70745ca7021a26fed4667161375fc9d6dbd1c..15c0328386c4908e5df1fb661195a5d8a040d79d 100644 (file)
@@ -1,98 +1,74 @@
 [[!template id=plugin name=pedigree author="intrigeri"]]
 [[!tag type/useful]]
 
-This plugin provides a bunch of loops that one can use in his/her
-`HTML::Template`'s to iterate over all or a subset of a page's
-parents. One can think of pedigree as "`PARENTLINKS` on steroids".
+This plugin offers a `HTML::Template` loop that iterates over all or
+a subset of a page's parents, providing a few bonus possibilities,
+such as styling the parent links depending on their place in the path.
+One can think of pedigree as "`PARENTLINKS` on steroids".
 
 [[!toc ]]
 
 Content
 =======
 
-Loop variables
---------------
+This plugin provides one template loop, called `PEDIGREE`, that
+returns the same parents list as `PARENTLINKS` would; as a bonus,
+every path element returned by the `PEDIGREE` loop has the following
+variables set:
 
-Inside any loop provided by the pedigree plugin, every path element
-has not only the `URL` and `PAGE` variables, as with `PARENTLINKS`,
-but also the following ones:
-
-* `ABSDEPTH` (positive integer): depth of the path leading to the
+* `URL` (string): url to the current path element
+* `PAGE` (string): title of the current path element
+* `DEPTH` (positive integer): depth of the path leading to the
   current path element, counting from the wiki's root, which has
-  `ABSDEPTH=0`
-* `DISTANCE` (positive integer): distance, expressed in path elements,
+  `DEPTH=0`
+* `HEIGHT` (positive integer): distance, expressed in path elements,
   from the current page to the current path element; e.g. this is
   1 for the current page's mother, 2 for its grand-mother, etc.
-* `IS_ROOT` (boolean): true if, and only if, this path element is the
-  wiki's root
-* `IS_SECOND_ANCESTOR` (boolean): true if, and only if, this path
-  element is the first one after the wiki's root, on the path leading
-  to the current page
-* `IS_GRAND_MOTHER` (boolean): true if, and only if, this path element
-  is the current page's grand-mother
-* `IS_MOTHER` (boolean): true if, and only if, this path element
-  is the current page's mother
-
-Loops
------
-
-### `PEDIGREE`
-
-Returns the same parents list as `PARENTLINKS` would, along with
-additional loop variables as explained above.
-
-### `PEDIGREE_BUT_ROOT`
-
-Returns the same parents list as `PEDIGREE` would, **but** the wiki
-root (i.e. homepage).
-
-In addition to pedigree's common loop variables, `PEDIGREE_BUT_ROOT`
-provides `RELDEPTH` (positive integer), whose value, for a given
-parent, is its relative depth, i.e. the depth of the path leading to
-it, counting from the first element returned by this loop.
-
-### `PEDIGREE_BUT_TWO_OLDEST`
-
-Returns the same parents list as `PEDIGREE` would, **but** the wiki
-root (i.e. homepage) and the next path component.
-
-In addition to pedigree's common loop variables,
-`PEDIGREE_BUT_TWO_OLDEST` provides `RELDEPTH`: depth of the path
-leading to the current parent, relative to the first element returned
-by this loop.
+* `DEPTH_n` (boolean): true if, and only if, `DEPTH==n`
+* `HEIGHT_n` (boolean): true if, and only if, `HEIGHT==n`
 
 Usage
 =====
 
+The `DEPTH_n` and `HEIGHT_n` variables allow the template writer to
+skip arbitrary elements in the parents list: they are arbitrary
+page-range selectors.
+
+The `DEPTH` and `HEIGHT` variables allow the template writer to apply
+general treatment, depending on one of these variables, to *every*
+parent: they are counters.
+
 Styling parents depending on their depth
 ----------------------------------------
 
 Say you want the parent links to be styled depending on their depth in
-the path leading to the current page; just add the following lines in
-`page.tmpl`:
+the path going from the wiki root to the current page; just add the
+following lines in `page.tmpl`:
 
        <TMPL_LOOP NAME="PEDIGREE">
-       <a href="<TMPL_VAR NAME="URL">" class="parentdepth<TMPL_VAR NAME="ABSDEPTH">">
+       <a href="<TMPL_VAR NAME="URL">" class="depth<TMPL_VAR NAME="DEPTH">">
          <TMPL_VAR NAME="PAGE">
        </a> / 
        </TMPL_LOOP>
 
-Then write the appropriate CSS bits for `a.parentdepth1`, etc.
+Then write the appropriate CSS bits for `a.depth1`, etc.
 
-Skip some parents, style the others depending on their distance
----------------------------------------------------------------
+Skip some parents, style the others depending on their distance to the current page
+-----------------------------------------------------------------------------------
 
-Say you want to display the parents links, skipping the wiki homepage,
-styled depending on their distance from the current page; just add the
+Say you want to display all the parents links but the wiki homepage,
+styled depending on their distance to the current page; just add the
 following lines in `page.tmpl`:
 
-       <TMPL_LOOP NAME="PEDIGREE_BUT_ROOT">
-       <a href="<TMPL_VAR NAME="URL">" class="parentdistance<TMPL_VAR NAME="DISTANCE">">
+       <TMPL_LOOP NAME="PEDIGREE">
+       <TMPL_IF NAME="DEPTH_0">
+       <TMPL_ELSE>
+       <a href="<TMPL_VAR NAME="URL">" class="height<TMPL_VAR NAME="HEIGHT">">
          <TMPL_VAR NAME="PAGE">
        </a> / 
        </TMPL_LOOP>
 
-Then write the appropriate CSS bits for `a.parentdistance1`, etc.
+Then write the appropriate CSS bits for `a.height1`, etc.
 
 Full-blown example
 ------------------
@@ -106,9 +82,9 @@ and/or CSS generated for some special path components; e.g.:
        <div id="oldestparents">
        <ul>
        <TMPL_LOOP NAME="PEDIGREE">
-         <TMPL_IF NAME="IS_GRAND_MOTHER">
+         <TMPL_IF NAME="HEIGHT_2">
          <TMPL_ELSE>
-           <TMPL_IF NAME="IS_MOTHER">
+           <TMPL_IF NAME="HEIGHT_1">
            <TMPL_ELSE>
              <li><a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a></li>
            </TMPL_IF>
@@ -119,12 +95,12 @@ and/or CSS generated for some special path components; e.g.:
        
        <!-- dedicated div's for mother and grand'ma -->
        <TMPL_LOOP NAME="PEDIGREE">
-         <TMPL_IF NAME="IS_GRAND_MOTHER">
+         <TMPL_IF NAME="HEIGHT_2">
            <div id="grandma">
              <a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a>
            </div>
          <TMPL_ELSE>
-           <TMPL_IF NAME="IS_MOTHER">
+           <TMPL_IF NAME="HEIGHT_1">
              <div id="mother">
                <a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a>
              </div>
@@ -135,11 +111,3 @@ and/or CSS generated for some special path components; e.g.:
        <!-- eventually, the current page title -->
        <TMPL_VAR NAME="TITLE">
        </div>
-
-Known bugs
-==========
-
-If `PEDIGREE_BUT_ROOT` and `PEDIGREE_BUT_TWO_OLDEST` are used in the
-same `HTML::Template`, `RELDEPTH` has wrong values inside the
-`PEDIGREE_BUT_ROOT` loop. This can be fixed if anyone needs this to
-be working.
index aa78cbe677df59bcba7d59addba5d38c6b98622e..74871cfa8f7766fc7cbe10d6b596cd31e659caf0 100755 (executable)
@@ -24,61 +24,15 @@ $expected{'pedigree'} =
   {
    "" => [],
    "ikiwiki" => [],
-   "ikiwiki/pagespec" => [
-                         {absdepth => 0,
-                          distance => 2,
-                          is_root => 1,
-                          is_second_ancestor => '',
-                          is_grand_mother => 1,
-                          is_mother => '',
-                         },
-                         {absdepth => 1,
-                          distance => 1,
-                          is_root => '',
-                          is_second_ancestor => 1,
-                          is_grand_mother => '',
-                          is_mother => 1,
-                         },
-                        ],
-   "ikiwiki/pagespec/attachment" => [
-                                    {absdepth => 0,
-                                     distance => 3,
-                                     is_root => 1,
-                                     is_second_ancestor => '',
-                                     is_grand_mother => '',
-                                     is_mother => '',
-                                    },
-                                    {absdepth => 1,
-                                     distance => 2,
-                                     is_root => '',
-                                     is_second_ancestor => 1,
-                                     is_grand_mother => 1,
-                                     is_mother => '',
-                                    },
-                                    {absdepth => 2,
-                                     distance => 1,
-                                     is_root => '',
-                                     is_second_ancestor => '',
-                                     is_grand_mother => '',
-                                     is_mother => 1,
-                                    },
-                                   ],
-  };
-
-$expected{'pedigree_but_root'} =
-  {
-   "" => [],
-   "ikiwiki" => [],
-   "ikiwiki/pagespec" => [],
-   "ikiwiki/pagespec/attachment" => [],
-  };
-
-$expected{'pedigree_but_two_oldest'} =
-  {
-   "" => [],
-   "ikiwiki" => [],
-   "ikiwiki/pagespec" => [],
-   "ikiwiki/pagespec/attachment" => [],
+   "ikiwiki/pagespec" =>
+     [ {depth => 0, height => 2, },
+       {depth => 1, height => 1, },
+     ],
+   "ikiwiki/pagespec/attachment" =>
+     [ {depth => 0, height => 3, depth_0 => 1, height_3 => 1},
+       {depth => 1, height => 2, },
+       {depth => 2, height => 1, },
+     ],
   };
 
 # Test function
@@ -87,15 +41,6 @@ sub test_loop($$) {
        my $expected=shift;
        my $template;
        my %params;
-       my $offset;
-
-       if ($loop eq 'pedigree') {
-               $offset=0;
-       } elsif ($loop eq 'pedigree_but_root') {
-               $offset=1;
-       } elsif ($loop eq 'pedigree_but_two_oldest') {
-               $offset=2;
-       }
 
        ok($template=template('pedigree.tmpl'), "template created");
        ok($params{template}=$template, "params populated");
@@ -103,12 +48,6 @@ sub test_loop($$) {
        while ((my $page, my $exp) = each %{$expected}) {
                my @path=(split("/", $page));
                my $pagedepth=@path;
-               my $expdepth;
-               if (($pagedepth - $offset) >= 0) {
-                       $expdepth=$pagedepth - $offset;
-               } else {
-                       $expdepth=0;
-               }
                my $msgprefix="$page $loop";
 
                # manually run the plugin hook
@@ -117,28 +56,18 @@ sub test_loop($$) {
                IkiWiki::Plugin::pedigree::pagetemplate(%params);
                my $res=$template->param($loop);
 
-               is(scalar(@$res), $expdepth, "$msgprefix: path length");
+               is(scalar(@$res), $pagedepth, "$msgprefix: path length");
                # logic & arithmetic validation tests
-               for (my $i=0; $i<$expdepth; $i++) {
+               for (my $i=0; $i<$pagedepth; $i++) {
                        my $r=$res->[$i];
-                       is($r->{distance}, $pagedepth - $r->{absdepth},
-                          "$msgprefix\[$i\]: distance = pagedepth - absdepth");
-                       ok($r->{absdepth} ge 0, "$msgprefix\[$i\]: absdepth>=0");
-                       ok($r->{distance} ge 0, "$msgprefix\[$i\]: distance>=0");
-                       unless ($loop eq 'pedigree') {
-                               ok($r->{reldepth} ge 0, "$msgprefix\[$i\]: reldepth>=0");
-                             TODO: {
-                                       local $TODO = "Known bug" if 
-                                         (($loop eq 'pedigree_but_root')
-                                          && ($i >= $offset));
-                                       is($r->{reldepth} + $offset, $r->{absdepth},
-                                          "$msgprefix\[$i\]: reldepth+offset=absdepth");
-                               }
-                       }
+                       is($r->{height}, $pagedepth - $r->{depth},
+                          "$msgprefix\[$i\]: height = pagedepth - depth");
+                       ok($r->{depth} ge 0, "$msgprefix\[$i\]: depth>=0");
+                       ok($r->{height} ge 0, "$msgprefix\[$i\]: height>=0");
                }
                # comparison tests, iff the test-suite has been written
-               if (scalar(@$exp) eq $expdepth) {
-                       for (my $i=0; $i<$expdepth; $i++) {
+               if (scalar(@$exp) eq $pagedepth) {
+                       for (my $i=0; $i<$pagedepth; $i++) {
                                my $e=$exp->[$i];
                                my $r=$res->[$i];
                                map { is($r->{$_}, $e->{$_}, "$msgprefix\[$i\]: $_"); } keys %$e;
@@ -151,6 +80,4 @@ sub test_loop($$) {
 }
 
 # Main
-map {
-       test_loop($_, $expected{$_});
-} ('pedigree', 'pedigree_but_root', 'pedigree_but_two_oldest');
+test_loop('pedigree', $expected{'pedigree'});
index 3590244ee98cd2af7eca64417a619de423c47b94..5fa25733a7cf771489a242d880a60da80c688454 100644 (file)
@@ -2,9 +2,3 @@
 
 <TMPL_LOOP NAME="PEDIGREE">
 </TMPL_LOOP>
-
-<TMPL_LOOP NAME="PEDIGREE_BUT_ROOT">
-</TMPL_LOOP>
-
-<TMPL_LOOP NAME="PEDIGREE_BUT_TWO_OLDEST">
-</TMPL_LOOP>