File Coverage

blib/lib/HiD/Pager.pm
Criterion Covered Total %
statement 32 59 54.2
branch 0 12 0.0
condition n/a
subroutine 11 17 64.7
pod 4 4 100.0
total 47 92 51.0


line stmt bran cond sub pod time code
1             # ABSTRACT: Class for paging thru sets of entries
2              
3              
4             package HiD::Pager;
5             our $AUTHORITY = 'cpan:GENEHACK';
6             $HiD::Pager::VERSION = '1.99';
7 12     12   73 use Moose;
  12         24  
  12         86  
8             # note: we also do 'with HiD::Role::DoesLogging', just later on because reasons.
9              
10 12     12   73964 use namespace::autoclean;
  12         33  
  12         182  
11              
12 12     12   1187 use 5.014; # strict, unicode_strings
  12         42  
13 12     12   69 use utf8;
  12         26  
  12         91  
14 12     12   339 use autodie;
  12         28  
  12         97  
15 12     12   56579 use warnings;
  12         29  
  12         482  
16 12     12   59 use warnings qw/ FATAL utf8 /;
  12         23  
  12         439  
17 12     12   73 use open qw/ :std :utf8 /;
  12         19  
  12         93  
18 12     12   1830 use charnames qw/ :full /;
  12         23  
  12         88  
19              
20 12     12   7392 use Data::Page;
  12         42815  
  12         62  
21 12     12   4024 use String::Errf qw/ errf /;
  12         125904  
  12         85  
22              
23              
24             has entries => (
25             is => 'ro',
26             isa => 'ArrayRef[HiD_Post]' ,
27             traits => [ qw/ Array / ] ,
28             handles => { total_entries => 'count' } ,
29             required => 1 ,
30             );
31              
32              
33             has entries_per_page => (
34             is => 'ro' ,
35             isa => 'HiD_PosInt' ,
36             default => 10 ,
37             );
38              
39              
40             has hid => (
41             is => 'ro' ,
42             isa => 'HiD' ,
43             required => 1 ,
44             handles => [ qw/ get_config / ],
45             );
46             with 'HiD::Role::DoesLogging'; # needs to see the get_config delegation
47              
48              
49             has page_pattern => (
50             is => 'ro',
51             isa => 'Str' ,
52             default => 'blog/%{page}' ,
53             );
54              
55              
56             has pager => (
57             is => 'ro' ,
58             isa => 'Data::Page' ,
59             lazy => 1,
60             init_arg => undef ,
61             builder => '_build_pager' ,
62             handles => {
63             page_number => 'current_page' ,
64             next_page => 'next_page' ,
65             prev_page => 'previous_page',
66             splice => 'splice',
67             total_pages => 'last_page' ,
68             }
69             );
70              
71             sub _build_pager {
72 0     0     my( $self ) = @_;
73              
74 0           my $pager = Data::Page->new();
75 0           $pager->total_entries($self->total_entries);
76 0           $pager->entries_per_page($self->entries_per_page);
77 0           $pager->current_page(1);
78              
79 0           return $pager;
80             }
81              
82             has _pager_page => (
83             is => 'rw' ,
84             isa => 'Maybe[Int]' ,
85             lazy => 1 ,
86             default => sub { shift->pager->current_page },
87             );
88              
89              
90             sub current_page_url {
91 0     0 1   my $self = shift;
92 0           return $self->_page_url( $self->page_number );
93             }
94              
95              
96             sub next {
97 0     0 1   my( $self ) = @_;
98              
99 0 0         return undef unless defined $self->_pager_page;
100              
101 0           $self->page_number( $self->_pager_page );
102 0           my @page_posts = $self->splice( reverse( $self->entries ));
103              
104 0           $self->_pager_page( $self->next_page );
105              
106             return {
107 0           current_page_url => $self->current_page_url ,
108             next_page => $self->next_page ,
109             next_page_url => $self->next_page_url ,
110             page_number => $self->page_number ,
111             posts => \@page_posts,
112             prev_page => $self->prev_page ,
113             prev_page_url => $self->prev_page_url ,
114             total_pages => $self->total_pages ,
115             };
116             }
117              
118              
119             sub next_page_url {
120 0     0 1   my $self = shift;
121 0 0         if ( my $next = $self->next_page ){
122 0           return $self->_page_url( $next );
123             }
124             }
125              
126              
127             sub prev_page_url {
128 0     0 1   my $self = shift;
129 0 0         if ( my $prev = $self->prev_page ){
130 0           return $self->_page_url( $prev );
131             }
132             }
133              
134             sub _page_url {
135 0     0     my( $self , $number ) = @_;
136              
137 0 0         confess('wtf') unless defined $number;
138              
139 0 0         $number = '' if $number == 1;
140              
141 0           my $url = errf $self->page_pattern , { page => $number };
142 0 0         $url .= '/index.html' unless $url =~ /html$/;
143 0           $url =~ s|//|/|g;
144              
145 0           return $url;
146             }
147              
148             __PACKAGE__->meta->make_immutable;
149              
150             __END__
151              
152             =pod
153              
154             =encoding UTF-8
155              
156             =head1 NAME
157              
158             HiD::Pager - Class for paging thru sets of entries
159              
160             =head1 SYNOPSIS
161              
162             To use pagination with just the blog pages, set the following config
163             options:
164              
165             pagination:
166             entries: 10
167             page: 'blog/%{page}s'
168             template: 'blog/index.html'
169              
170             C<pagination.entries> sets the number of entries per
171             page. C<pagination.page> sets the pattern for pages. C<pagination.template>
172             is the template file that will be used for each file in turn. A
173             C<index.html> will be appended to each page. Note that no 'page1' entry will
174             be generated; in the example above, the first page would be at
175             'blog/index.html', the second at 'blog/page2/index.html', and so on.
176              
177             If you need more control, or want to use pagination inside a
178             L<HiD::Generator>, you can instatiate one like so:
179              
180             my $pager = HiD::Pager->new({
181             entries => $site->posts ,
182             entries_per_page => 5 ,
183             hid => $site ,
184             page_pattern => 'blog/%{page}s' ,
185             });
186              
187             while( my $page_data = $pager->next() ) {
188             my $page = HiD::Page->new(
189             metadata => { page_data => $page_data },
190             # other page data here
191             );
192             # inject page into site, etc.
193             }
194              
195             # in page template, assuming Kolon template syntax
196             : for $page_data.posts -> $post {
197             : ## render page here
198             : }
199              
200             : # other useful info for creating intra-page links and metadata
201             : $page_data.current_page_url = url of current page
202             : $page_data.page_number = number of current page
203             : $page_data.total_pages = total number of pages
204             : $page_data.prev_page = number of previous page (undef if no previous)
205             : $page_data.prev_page_url = url of previous page (undef if no previous)
206             : $page_data.next_page = number of next page (undef if no next)
207             : $page_data.next_page_url = url of next page (undef if no next)
208              
209             =head1 DESCRIPTION
210              
211             Class providing pagination services for sets of posts. Can be used for main
212             blog post pages by setting up the appropriate configuration, or used inside a
213             C<HiD::Generator> class to provide paged sets of a subset of the posts on a
214             site.
215              
216             =head1 ATTRIBUTES
217              
218             =head2 entries
219              
220             Array of L<HiD::Post> objects being worked with
221              
222             =head2 entries_per_page
223              
224             Number of entries per page.
225              
226             =head2 hid
227              
228             All hail the God Object.
229              
230             =head2 page_pattern
231              
232             Regex used to generate per-page URLs
233              
234             =head2 pager
235              
236             The L<Data::Page> object that does all the work.
237              
238             =head1 METHODS
239              
240             =head2 current_page_url
241              
242             Returns the URL for the current page in the set.
243              
244             =head2 next
245              
246             Returns the data structure for the pager information.
247              
248             =head2 next_page_url
249              
250             Returns the URL for the next page in the set.
251              
252             =head2 prev_page_url
253              
254             Returns the URL for the previous page in the set.
255              
256             =head1 VERSION
257              
258             version 1.99
259              
260             =head1 AUTHOR
261              
262             John SJ Anderson <genehack@genehack.org>
263              
264             =head1 COPYRIGHT AND LICENSE
265              
266             This software is copyright (c) 2015 by John SJ Anderson.
267              
268             This is free software; you can redistribute it and/or modify it under
269             the same terms as the Perl 5 programming language system itself.
270              
271             =cut