File Coverage

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

linestmtbrancondsubpodtimecode
1package Yukki::Web::Response;
2
3
3
3
21
6
use v5.24;
4
3
3
3
23
4
14
use utf8;
5
3
3
3
37
3
12
use Moo;
6
7
3
3
3
626
4
15
use Type::Utils;
8
3
3
3
2895
5
11
use Types::Standard qw( Str );
9
3
3
3
1295
5
12
use Yukki::Types qw( BreadcrumbLinks NavigationMenuMap );
10
11
3
3
3
1715
3961
44
use Plack::Response;
12
13
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
34has 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
46sub _build_response {
47
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
57has 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
77has navigation => (
78    is          => 'rw',
79    isa         => NavigationMenuMap,
80    required    => 1,
81    default     => sub { +{} },
82);
83
84sub navigation_menu_names {
85
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
95has breadcrumb => (
96    is          => 'rw',
97    isa         => BreadcrumbLinks,
98    required    => 1,
99    default     => sub { [] },
100);
101
102sub breadcrumb_links {
103
1
1
23
    my $self = shift;
104
1
11
    $self->breadcrumb->@*;
105}
106
107sub has_breadcrumb {
108
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
122sub navigation_menu {
123
8
1
65
    my ($self, $name) = @_;
124
15
69
    return sort { ($a->{sort}//50) <=> ($b->{sort}//50) }
125
8
8
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
1
266
sub add_navigation_item { shift->add_navigation_items(@_) }
145
146sub add_navigation_items {
147
15
1
19
    my $self = shift;
148
15
18
    my $name_or_names = shift;
149
150
15
29
    my @names = ref $name_or_names ? @$name_or_names : ($name_or_names);
151
152
15
21
    for my $name (@names) {
153
21
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
1761;