FunctionalPerl
view release on metacpan or search on metacpan
htmlgen/FunctionalPerl/Htmlgen/Nav.pm view on Meta::CPAN
sub _nav ($items, $nav_bar) {
my $nav
= FunctionalPerl::Htmlgen::Nav::TopEntry->new($items, $nav_bar, undef);
$nav->index_set(nav_index($nav))
}
sub entry ($path0, @subentries) {
FunctionalPerl::Htmlgen::Nav::RealEntry->new_(
path0 => $path0,
subentries => list(@subentries)
);
}
# Classes
package FunctionalPerl::Htmlgen::Nav::Entry {
use FP::Predicates ":all";
use FP::List qw(list_of); # should that be re-exported by
# FP::Predicates?
use FP::Ops qw(the_method);
use FP::List;
use FP::fix;
use FP::Equal qw(equal);
use FP::Struct [
[
list_of(instance_of "FunctionalPerl::Htmlgen::Nav::Entry"),
"subentries"
]
];
sub subentries_of_subentries($self) {
$self->subentries->map(the_method "subentries")
}
# An FP::List of all nav levels, including level 0, but unlike the
# result of nav_bar_level0, level 0 here is directly representing the
# top level of the {nav} config value (unknown pages are dropped, and
# non-existing pages show up). Feel free to drop it and replace with
# nav_bar_level0.
sub nav_bar_levels ($self, $viewed_at_item, $upitems) {
fix(
sub ($rec, $nav, $downitems, $upitem) {
# only show subnavs until the given location
# ($viewed_at_item), and then one more (to go down)?
if (my ($item, $rest) = $downitems->perhaps_first_and_rest) {
my $entries = $nav->subentries;
my $active = $entries->filter(sub { $_[0] eq $item })->xone;
cons($self->nav_bar->($entries, $item, $viewed_at_item),
&$rec($active, $rest, $item))
} else {
# the lowest level of the navigation stack: if the
# current item ($upitem, should also be the
# $viewed_at_item) has subentries, then show that
# (immediate) level as the last one. XX: this
# would better be shown in a different way; use
# (CSS based) mouse over submenu popups
# (advantage: show them on ~all the other items,
# too)?
if (is_pair(my $es = $upitem->subentries)) {
equal($upitem, $viewed_at_item) or die "bug?";
# hack: passing $upitem as the item here (*no*
# item should be marked as selected, this
# fulfills the purpose)
cons($self->nav_bar->($es, $upitem, $viewed_at_item),
null)
} else {
null
}
}
}
)->($self, $upitems->reverse, undef)
# an empty upitems list would be at odds with the given
# undef $upitem, but that doesn't happen.
}
_END_
}
package FunctionalPerl::Htmlgen::Nav::TopEntry {
use FP::Predicates ":all";
use FP::Ops qw(the_method string_cmp);
use FP::Combinators qw(compose);
use FP::Array_sort;
use FP::HashSet qw(hashset_to_predicate
array_to_hashset);
use FP::Struct [
[\&is_procedure, "nav_bar"],
[maybe(instance_of "FunctionalPerl::Htmlgen::Nav::Index"), "index"]
],
"FunctionalPerl::Htmlgen::Nav::Entry";
sub FP_Show_show ($self, $show) {
("nav(" . $self->subentries->map($show)->strings_join(", ") . ")")
}
# nav level 0: this is special since it does not just
# show what the navigation defines, but show all
# pages that are not in deeper levels
sub item_is_in_lower_hierarchy($self) {
compose(
hashset_to_predicate(
array_to_hashset(
$self->subentries_of_subentries->flatten->map(
the_method "path0"
)->array
)
),
the_method "path0"
)
}
# In the toplevel of the nav hierarchy, still also show pages that are
( run in 2.183 seconds using v1.01-cache-2.11-cpan-364913b4093 )