File Coverage

blib/lib/Paginator/Lite.pm
Criterion Covered Total %
statement 43 43 100.0
branch 16 16 100.0
condition n/a
subroutine 13 13 100.0
pod 7 7 100.0
total 79 79 100.0


line stmt bran cond sub pod time code
1             package Paginator::Lite;
2             $Paginator::Lite::VERSION = '2.001003';
3 7     7   384567 use strict;
  7         9  
  7         179  
4 7     7   26 use warnings;
  7         9  
  7         152  
5              
6 7     7   3640 use Moo;
  7         60183  
  7         29  
7 7     7   10621 use URI;
  7         29710  
  7         4575  
8              
9             has curr => (
10             required => 1,
11             is => 'ro',
12             isa => sub { die "curr page must be > 0" unless $_[0] > 0 },
13             );
14              
15             has frame_size => (
16             required => 1,
17             is => 'ro',
18             isa => sub { die "frame_size must be >= 0" unless $_[0] >= 0 },
19             );
20              
21             has page_size => (
22             required => 1,
23             is => 'ro',
24             isa => sub { die "page_size must be > 0" unless $_[0] > 0 },
25             );
26              
27             has items => (
28             required => 1,
29             is => 'ro',
30             isa => sub { die "items must be > 0" unless $_[0] >= 0 },
31             );
32              
33             has base_url => (
34             required => 1,
35             is => 'ro',
36             isa => sub { die "base_url must be defined" unless defined $_[0] },
37             );
38              
39             has mode => (
40             is => 'ro',
41             default => sub { 'path' },
42             isa => sub {
43             my $mode = shift;
44             die "mode must be 'path' or 'query'" unless $mode =~ /path|query/;
45             },
46             );
47              
48             has first => ( is => 'ro' );
49              
50             has prev => ( is => 'ro' );
51              
52             has begin => ( is => 'ro' );
53              
54             has end => ( is => 'ro' );
55              
56             has next => ( is => 'ro' );
57              
58             has last => ( is => 'ro' );
59              
60             has params => ( is => 'ro' );
61              
62             sub BUILD {
63 14     14 1 89 my ($self) = @_;
64              
65 14         23 $self->{first} = 1;
66              
67 14         74 $self->{last} = _ceil( $self->items / $self->page_size );
68              
69 14 100       32 $self->{curr} = $self->{last} if $self->{curr} > $self->{last};
70              
71             $self->{prev} =
72             $self->{curr} == $self->{first}
73             ? 1
74 14 100       32 : $self->{curr} - 1;
75              
76             $self->{next} =
77             $self->{curr} == $self->{last}
78             ? $self->{last}
79 14 100       30 : $self->{curr} + 1;
80              
81 14 100       32 if ( $self->frame_size > 0 ) {
82 13         30 my $half_frame = int( 0.5 + $self->frame_size / 2 );
83              
84 13         34 $self->{begin} = $self->curr - $half_frame + 1;
85 13 100       28 $self->{begin} = $self->{first} if $self->{begin} < $self->{first};
86              
87 13         25 $self->{end} = $self->curr + $half_frame - 1;
88 13 100       71 $self->{end} = $self->{last} if $self->{end} > $self->{last};
89             }
90             else {
91 1         1 $self->{begin} = 0;
92 1         4 $self->{end} = -1;
93             }
94             }
95              
96 2     2 1 157 sub first_url { $_[0]->_custom_url( $_[0]->first ) }
97 2     2 1 1567 sub prev_url { $_[0]->_custom_url( $_[0]->prev ) }
98 2     2 1 1008 sub curr_url { $_[0]->_custom_url( $_[0]->curr ) }
99 2     2 1 982 sub next_url { $_[0]->_custom_url( $_[0]->next ) }
100 2     2 1 933 sub last_url { $_[0]->_custom_url( $_[0]->last ) }
101 2     2 1 970 sub page_url { $_[0]->_custom_url( $_[1] ) }
102              
103             sub _custom_url {
104 12     12   15 my ( $self, $page ) = @_;
105              
106 12         38 my $uri = URI->new( $self->base_url );
107              
108 12 100       4597 if ( $self->mode eq 'path' ) {
109 6         11 return $uri->path . '/' . $page;
110             }
111             else {
112 6         8 my $params = $self->params;
113 6         7 $params->{page} = $page;
114 6         13 $uri->query_form($params);
115 6         363 return $uri->as_string;
116             }
117             }
118              
119             sub _ceil {
120 14     14   15 my ( $val, $floor ) = @_;
121              
122 14         26 $floor = int $val;
123              
124 14 100       44 return $floor == $val ? $floor : $floor + 1;
125             }
126              
127             return 42;
128              
129             __END__
130              
131             =pod
132              
133             =encoding UTF-8
134              
135             =head1 NAME
136              
137             Paginator::Lite
138              
139             =head1 VERSION
140              
141             version 2.001003
142              
143             =head1 SYNOPSIS
144              
145             A simple tool to automate the creation of paging links
146              
147             use Paginator::Lite;
148            
149             my $paginator = Paginator::Lite->new({
150             curr => 3,
151             items => 65,
152             frame_size => 5,
153             page_size => 10,
154             base_url => '/foo/items',
155             mode => 'query',
156             params => {
157             bar => 123
158             },
159             });
160            
161             ...
162            
163             $paginator->first # 1
164             $paginator->last # 7
165             $paginator->begin # 1
166             $paginator->end # 5
167             $paginator->next # 4
168             $paginator->prev # 2
169             $paginator->base_url # '/foo/items'
170              
171             $paginator->first_url # '/foo/items?bar=123&page=1'
172             $paginator->prev_url # '/foo/items?bar=123&page=2'
173             $paginator->curr_url # '/foo/items?bar=123&page=3'
174             $paginator->next_url # '/foo/items?bar=123&page=4'
175             $paginator->last_url # '/foo/items?bar=123&page=7'
176              
177             =head1 DESCRIPTION
178              
179             When handle with huge amounts of data sometimes you want to display only a
180             portion of it and provide controls to naviagte through it.
181              
182             The classic way is to provide links or buttons to next, previous and some
183             pages around the current page, like this:
184              
185             (prev) 1 2 [3] 4 5 (next)
186              
187             But when the number of pages grow up too much this approach may be annoying:
188              
189             (prev) 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 16 18 19 20 21 (next)
190              
191             So Paginator::Lite helps you calculating the numbers to feed your view loops
192             and implements the concept of frame. A frame is a small portion of pages
193             around the current page that will be displayed in addition to (prev), (next)
194             and other permanent buttons:
195              
196             (prev) 10 11 12 [13] 14 15 16 (next)
197             \ /
198             ----- frame ----
199             7 of 21 pages
200              
201             =head1 NAME
202              
203             Paginator::Lite - A simple paginator
204              
205             =head1 VERSION
206              
207             2.1.0
208              
209             =head1 METHODS
210              
211             =head2 new
212              
213             Creates a Paginator::Lite object.
214              
215             You must provide all required arguments: C<base_url>, C<curr>, C<frame_size>,
216             C<items> and C<page_size>.
217              
218             C<params> is a optional argument that may be used to pass arbitrary data.
219              
220             See more details about them in documentation of their respective
221             accessors.
222              
223             =head2 base_url
224              
225             Returns the value of C<base_url>. It is the same value that you must supply
226             to constructor. This value will be used by the template to build the links to
227             direct pages.
228              
229             =head2 curr
230              
231             Returns the value of B<current page>. It is the same value that you must
232             supply to constructor.
233              
234             =head2 frame_size
235              
236             Returns the value of C<frame_size>. It is the same value that you must supply
237             to constructor. It is also the number of pages visible around current page.
238              
239             Usually C<frame_size> may be calculated by:
240              
241             my $frame_size = $pag->end - $pag->begin + 1
242              
243             However when current page is too close to C<first> or C<last>, the frame may
244             be deformed but still trying to center in the current page.
245              
246             =head2 page_size
247              
248             Returns the value of C<page_size>. It is the same value that you must supply
249             to constructor and means the number of items that you want display in a
250             single page.
251              
252             =head2 items
253              
254             Returns the value of C<items>. It is the same value the you must provide to
255             constructor and means the total number of items that you are paginating.
256              
257             =head2 first
258              
259             Returns the value of the first page, usually B<1>.
260              
261             =head2 last
262              
263             Returns the value of the last page. This value is calculated by dividing the
264             total amount of items by the number of items per page and then rounding up
265             the result.
266              
267             $self->{last} = ceil( $self->items / $self->page_size );
268              
269             =head2 begin
270              
271             Returns the value of the first page of current frame. Usually you will
272             iterate between C<begin> and C<end> in your view to create direct links to
273             those pages.
274              
275             =head2 end
276              
277             Returns the value of the last page of current frame.
278              
279             =head2 prev
280              
281             Returns the value of previous page. Usually this value is C<curr - 1>, except
282             when current page is B<1>.
283              
284             =head2 next
285              
286             Returns the value of next page. Usually this value is C<curr + 1>, except
287             when current page is C<last>.
288              
289             =head2 params
290              
291             Returns arbitrary data passed to contructor by C<params> argument.
292              
293             =head2 mode
294              
295             Returns the chosen mode (path or query) of resulting URLs.
296              
297             =head2 first_url
298              
299             Returns the URL of the first page.
300              
301             =head2 prev_url
302              
303             Returns the URL of the previous page.
304              
305             =head2 curr_url
306              
307             Returns the URL of the current page.
308              
309             =head2 next_url
310              
311             Returns the URL of the next page.
312              
313             =head2 last_url
314              
315             Returns the URL of the last page.
316              
317             =head2 page_url( $page )
318              
319             Returns the URL of given page.
320              
321             =head2 BUILD
322              
323             Private. It casts the magic when building the object.
324              
325             =head1 AUTHOR
326              
327             Blabos de Blebe, C<< <blabos at cpan.org> >>
328              
329             =head1 BUGS
330              
331             Please report any bugs or feature requests to
332             C<bug-paginator-lite at rt.cpan.org>, or through
333             the web interface at
334             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Paginator-Lite>.
335             I will be notified, and then you'll automatically be notified of progress
336             on your bug as I make changes.
337              
338             =head1 SUPPORT
339              
340             You can find documentation for this module with the perldoc command.
341              
342             perldoc Paginator::Lite
343              
344             You can also look for information at:
345              
346             =over 4
347              
348             =item * RT: CPAN's request tracker
349              
350             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Paginator-Lite>
351              
352             =item * AnnoCPAN: Annotated CPAN documentation
353              
354             L<http://annocpan.org/dist/Paginator-Lite>
355              
356             =item * CPAN Ratings
357              
358             L<http://cpanratings.perl.org/d/Paginator-Lite>
359              
360             =item * Search CPAN
361              
362             L<http://search.cpan.org/dist/Paginator-Lite/>
363              
364             =back
365              
366             =head1 COPYRIGHT & LICENSE
367              
368             Copyright 2012 Blabos de Blebe.
369              
370             This program is free software; you can redistribute it and/or modify it
371             under the terms of either: the GNU General Public License as published
372             by the Free Software Foundation; or the Artistic License.
373              
374             See http://dev.perl.org/licenses/ for more information.
375              
376             =head1 AUTHOR
377              
378             Blabos de Blebe <blabos@cpan.org>
379              
380             =head1 COPYRIGHT AND LICENSE
381              
382             This software is copyright (c) 2017 by Blabos de Blebe.
383              
384             This is free software; you can redistribute it and/or modify it under
385             the same terms as the Perl 5 programming language system itself.
386              
387             =cut