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 )