diff options
-rw-r--r-- | IkiWiki/Plugin/pedigree.pm | 57 | ||||
-rw-r--r-- | doc/plugins/pedigree.mdwn | 112 | ||||
-rwxr-xr-x | t/pedigree.t | 109 | ||||
-rw-r--r-- | t/pedigree/templates/pedigree.tmpl | 6 |
4 files changed, 69 insertions, 215 deletions
diff --git a/IkiWiki/Plugin/pedigree.pm b/IkiWiki/Plugin/pedigree.pm index f91ea94b4..eb8bfa83b 100644 --- a/IkiWiki/Plugin/pedigree.pm +++ b/IkiWiki/Plugin/pedigree.pm @@ -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 diff --git a/doc/plugins/pedigree.mdwn b/doc/plugins/pedigree.mdwn index 41f70745c..15c032838 100644 --- a/doc/plugins/pedigree.mdwn +++ b/doc/plugins/pedigree.mdwn @@ -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. diff --git a/t/pedigree.t b/t/pedigree.t index aa78cbe67..74871cfa8 100755 --- a/t/pedigree.t +++ b/t/pedigree.t @@ -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'}); diff --git a/t/pedigree/templates/pedigree.tmpl b/t/pedigree/templates/pedigree.tmpl index 3590244ee..5fa25733a 100644 --- a/t/pedigree/templates/pedigree.tmpl +++ b/t/pedigree/templates/pedigree.tmpl @@ -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> |