File Coverage: lib/Yukki/Web/Response.pm

# File Coverage

File: | lib/Yukki/Web/Response.pm
Coverage: | 93.2%

line | stmt | bran | cond | sub | pod | time | code
--- | --- | --- | --- | --- | --- | --- | ---
1 |  |  |  |  |  |  | package Yukki::Web::Response;
2 |
3 | 3 3 |  |  | 3 |  | 21 6 | use v5.24;
4 | 3 3 3 |  |  | 3 |  | 23 4 14 | use utf8;
5 | 3 3 3 |  |  | 3 |  | 37 3 12 | use Moo;
6 |
7 | 3 3 3 |  |  | 3 |  | 626 4 15 | use Type::Utils;
8 | 3 3 3 |  |  | 3 |  | 2895 5 11 | use Types::Standard qw( Str );
9 | 3 3 3 |  |  | 3 |  | 1295 5 12 | use Yukki::Types qw( BreadcrumbLinks NavigationMenuMap );
10 |
11 | 3 3 3 |  |  | 3 |  | 1715 3961 44 | use Plack::Response;
12 |
13 | 3 3 3 |  |  | 3 |  | 11 3 13 | use namespace::clean;
14 |
15 |  |  |  |  |  |  | # ABSTRACT: the response to the client
16 |
17 - 32 |  |
    =head1 DESCRIPTION

    An abstraction around the HTTP response that is astonishingly similar to L<Plack::Response>. Call C<finalize> to get the final PSGI response.

    =head1 ATTRIBUTES

    =head2 response

    This is the internal L<Plack::Response> object. Do not use.

    Use the delegated methods instead:

      status headers body header content_type content_length content_encoding
      redirect location cookies finalize

    =cut
33 |
34 |  |  |  |  |  |  | has response => (
35 |  |  |  |  |  |  | is => 'ro',
36 |  |  |  |  |  |  | isa => class_type('Plack::Response'),
37 |  |  |  |  |  |  | required => 1,
38 |  |  |  |  |  |  | lazy => 1,
39 |  |  |  |  |  |  | builder => '_build_response',
40 |  |  |  |  |  |  | handles => [ qw(
41 |  |  |  |  |  |  | status headers body header content_type content_length content_encoding
42 |  |  |  |  |  |  | redirect location cookies finalize
43 |  |  |  |  |  |  | ) ],
44 |  |  |  |  |  |  | );
45 |
46 |  |  |  |  |  |  | sub _build_response {
47 | 3 |  |  | 3 |  | 551 | my $self = shift;
48 | 3 |  |  |  |  | 29 | return Plack::Response->new(200, [ 'Content-type' => 'text/html; charset=utf-8' ]);
49 |  |  |  |  |  |  | }
50 |
51 - 55 |  |
    =head2 page_title

    This is the title to give the page in the HTML.

    =cut
56 |
57 |  |  |  |  |  |  | has page_title => (
58 |  |  |  |  |  |  | is => 'rw',
59 |  |  |  |  |  |  | isa => Str,
60 |  |  |  |  |  |  | predicate => 'has_page_title',
61 |  |  |  |  |  |  | );
62 |
63 - 75 |  |
    =head2 navigation

    This is the navigation menu to place in the page. This is an array of hashes. Each entry should look like:

      {
          label => 'Label',
          href  => '/link/to/somewhere',
          sort  => 50,
      }

    A sorted list of items is retrieved using L</navigation_menu>. New items can be added with the L</add_navigation_item> and L</add_navigation_items> methods.

    =cut
76 |
77 |  |  |  |  |  |  | has navigation => (
78 |  |  |  |  |  |  | is => 'rw',
79 |  |  |  |  |  |  | isa => NavigationMenuMap,
80 |  |  |  |  |  |  | required => 1,
81 |  |  |  |  |  |  | default => sub { +{} },
82 |  |  |  |  |  |  | );
83 |
84 |  |  |  |  |  |  | sub navigation_menu_names {
85 | 0 |  |  | 0 | 1 | 0 | my $self = shift;
86 | 0 |  |  |  |  | 0 | keys $self->navigation->%*;
87 |  |  |  |  |  |  | }
88 |
89 - 93 |  |
    =head2 breadcrumb

    This is the breadcrumb to display. It is an empty array by default (meaning no breadcrumb). Each element of the breadcrumb is formatted like navigation, except that C<sort> is not used here.

    =cut
94 |
95 |  |  |  |  |  |  | has breadcrumb => (
96 |  |  |  |  |  |  | is => 'rw',
97 |  |  |  |  |  |  | isa => BreadcrumbLinks,
98 |  |  |  |  |  |  | required => 1,
99 |  |  |  |  |  |  | default => sub { [] },
100 |  |  |  |  |  |  | );
101 |
102 |  |  |  |  |  |  | sub breadcrumb_links {
103 | 1 |  |  | 1 | 1 | 23 | my $self = shift;
104 | 1 |  |  |  |  | 11 | $self->breadcrumb->@*;
105 |  |  |  |  |  |  | }
106 |
107 |  |  |  |  |  |  | sub has_breadcrumb {
108 | 2 |  |  | 2 | 1 | 386 | my $self = shift;
109 | 2 |  |  |  |  | 29 | scalar $self->breadcrumb->@*;
110 |  |  |  |  |  |  | }
111 |
112 - 120 |  |
    =head1 METHODS

    =head2 navigation_menu

      my @items = $response->navigation_menu('repository');

    Returns a sorted list of navigation items  for the named menu.

    =cut
121 |
122 |  |  |  |  |  |  | sub navigation_menu {
123 | 8 |  |  | 8 | 1 | 65 | my ($self, $name) = @_;
124 | 15 |  | 50 50 |  |  | 69 | return sort { ($a->{sort}//50) <=> ($b->{sort}//50) }
125 | 8 8 |  | 100 |  |  | 14 135 | @{ $self->navigation->{$name} // [] };
126 |  |  |  |  |  |  | }
127 |
128 - 142 |  |
    =head2 add_navigation_item

    =head2 add_navigation_items

      $response->add_navigation_item(menu_name => {
          label => 'Link Title',
          url   => '/path/to/some/place',
          sort  => 50,
      });

    Add one or more items to the named menu. The first argument is always the name or names of the menu. Mutliple names may be given in an array reference. If multiple names are given, the menu items given will be added to each menu named. The remaining arguments are hash references that must have a C<label> and a C<url>. The C<sort> is optional.

    L</add_navigation_item> is a synonym for L</add_navigation_items>.

    =cut
143 |
144 | 15 |  |  | 15 | 1 | 266 | sub add_navigation_item { shift->add_navigation_items(@_) }
145 |
146 |  |  |  |  |  |  | sub add_navigation_items {
147 | 15 |  |  | 15 | 1 | 19 | my $self = shift;
148 | 15 |  |  |  |  | 18 | my $name_or_names = shift;
149 |
150 | 15 | 100 |  |  |  | 29 | my @names = ref $name_or_names ? @$name_or_names : ($name_or_names);
151 |
152 | 15 |  |  |  |  | 21 | for my $name (@names) {
153 | 21 |  | 100 |  |  | 252 | $self->navigation->{$name} //= [];
154 | 21 21 |  |  |  |  | 104 230 | push @{ $self->navigation->{$name} }, @_;
155 |  |  |  |  |  |  | }
156 |  |  |  |  |  |  | }
157 |
158 - 174 |  |
    =head2 breadcrumb_links

    Convenience accessor that returns C<breadcrumbs> as a list.

    =head2 has_breadcrumb

    Returns a true value if C<breadcrumbs> has any items in it.

    =head2 has_page_title

    Returns a true value if C<page_title> is set.

    =head2 navigation_menu_names

    Convenience accessor that returns C<navigation> as a list.

    =cut
175 |
176 |  |  |  |  |  |  | 1;