1package Data::Page::Pageset; 2use Carp; 3use strict; 4use Data::Page::Pageset::Chunk; 5use POSIX; 6 7use base 'Class::Accessor::Fast'; 8__PACKAGE__->mk_accessors( qw( 9 total_pages 10 first_pageset 11 last_pageset 12 current_pageset 13 previous_pageset 14 next_pageset 15 ) ); 16# add this for make more version to be 1.02 17our $VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /: (\d+)\.(\d+)/; 18 19sub new { 20 my $class = shift; 21 my $page = shift; 22 my $param = shift; 23 24 croak("The first is not a Data::Page object!") 25 unless $page->UNIVERSAL::isa('Data::Page'); 26 27 my $self = bless {}, $class; 28 $self->{_page} = $page; 29 $self->{_total_pagesets} = []; 30 $self->{_MAX_PAGESETS} = 1; 31 $self->{_PAGE_PER_SET} = 2; 32 33 if ( not defined $param or ref $param eq '' ){ 34 $self->pages_per_set( $param || 10 ); 35 36 }elsif ( defined $param->{max_pagesets} ){ 37 $self->max_pagesets( $param->{max_pagesets} ); 38 39 }elsif ( defined $param->{pages_per_set} ){ 40 $self->pages_per_set( $param->{pages_per_set} ); 41 } 42 43 return $self; 44} 45 46sub total_pagesets { 47 my $self = shift; 48 if ( $_[0] ){ 49 $self->{_total_pagesets} = $_[0]; 50 } 51 return ( wantarray ) ? @{$self->{_total_pagesets}} : $self->{_total_pagesets}; 52} 53 54sub max_pagesets { 55 my ( $self, $number ) = @_; 56 if ( defined $number ){ 57 $number = int $number; 58 croak("Fewer than one pagesets!") if $number < 1; 59 return $self->{_MAX_PAGESETS} if $number == $self->{_MAX_PAGESETS}; 60 $self->{_MAX_PAGESETS} = $number; 61 $self->pages_per_set( POSIX::ceil( $self->{_page}->last_page / $number ) ); 62 } 63 return $self->{_MAX_PAGESETS}; 64} 65 66sub pages_per_set { 67 my ( $self, $number ) = @_; 68 if ( defined $number ){ 69 $number = int $number; 70 croak("Fewer than two pages per set!") if $number < 2; 71 return $self->{_PAGE_PER_SET} if $number == $self->{_PAGE_PER_SET}; 72 $self->{_PAGE_PER_SET} = $number; 73 $self->_refresh; 74 } 75 return $self->{_PAGE_PER_SET}; 76} 77 78sub _refresh { 79 my $self = shift; 80 my $number = $self->pages_per_set; 81 my $page = $self->{_page}; 82 83 my $current_page = $page->current_page; 84 my @total_pages = ( $page->first_page .. $page->last_page ); 85 $self->total_pages( scalar @total_pages ); 86 87 my @pageset; 88 while ( @total_pages ){ 89 my @array = splice( @total_pages, 0, $number ); 90 my $chunk = Data::Page::Pageset::Chunk->new( @array ); 91 push @pageset, $chunk; 92 if ( $current_page >= $chunk->first and $current_page <= $chunk->last ){ 93 $chunk->is_current(1); 94 $self->current_pageset( $chunk ); 95 $self->previous_pageset( $pageset[-2] ) if $#pageset; 96 } 97 $self->next_pageset( $chunk ) if ( $#pageset and $pageset[-2]->is_current ); 98 } 99 $self->first_pageset( $pageset[0] ); 100 $self->last_pageset( $pageset[-1] ) if $#pageset; 101 $self->total_pagesets( \@pageset ); 102} 103 1041; 105 106=head1 NAME 107 108Data::Page::Pageset - change long page list to be shorter and well navigate 109 110=head1 DESCRIPTION 111 112Pages number can be very high, and it is not comfortable to show user from the first page to the last page list. Sometimes we need split the page list into some sets to shorten the page list, the form is like: 113 114 1-6 7-12 13 14 15 16 17 18 19-24 25-30 31-36 37-41 115 116the first two part indicats the two pagesets, and in current pageset, we provide the normal page list from the first one to the last one, and provide the rest pagesets to indicate the pages scope. 117 118In this module, you can specify the pages_per_set or max_pagesets for fine showing. 119 120=head1 SYNOPSIS 121 122 use Data::Page::Pageset; 123 # we use Data::Page object, so do prepare 124 my $page = Data::Page->new($total_entries, $entries_per_page, $current_page); 125 # create the pageset object 126 my $pageset = Data::Page::Pageset->new( $page ); 127 my $pageset = Data::Page::Pageset->new( $page, 12 ); 128 my $pageset = Data::Page::Pageset->new( $page, { max_pagesets => $max_pagesets } ); 129 my $pageset = Data::Page::Pageset->new( $page, { pages_per_set => $pages_per_set } ); 130 131 # for using 132 foreach my $chunk ( $pageset->total_pagesets ){ 133 if ( $chunk->is_current ){ 134 map { print "$_ " } ( $chunk->first .. $chunk->last ); 135 }else{ 136 print "$chunk "; 137 } 138 } 139 140=head1 METHODS 141 142=over 143 144=item new() 145 146 # default page_per_set is 10 147 my $pageset = Data::Page::Pageset->new( $page ); 148 149 # set the page_per_set to be 12 150 my $pageset = Data::Page::Pageset->new( $page, 12 ); 151 # another the same by passing hashref 152 my $pageset = Data::Page::Pageset->new( $page, { pages_per_set => $pages_per_set } ); 153 154 # set the max_pagesets value, default is 1 155 my $pageset = Data::Page::Pageset->new( $page, { max_pagesets => $max_pagesets } ); 156 # if max_pagesets supplies, the pages_per_set setting will be ignore 157 my $pageset = Data::Page::Pageset->new( $page, 158 { max_pagesets => $max_pagesets, pages_per_set => $pages_per_set } ); 159 160We must need $page(isa Data::Page) object. 161 162=item max_pagesets( $number ) 163 164 # set the max_pagesets value, and the $pageset's info will changed immediately 165 $pageset->max_pagesets( $number ); 166 167=item pages_per_set( $number ) 168 169 # set the pages_per_set value, and the $pageset's info will changed immediately 170 $pageset->pages_per_set( $number ); 171 my $present_setting = $pageset->pages_per_set(); 172 173=item $pageset->total_pages 174 175return total pages' number. 176 177=item $pageset->total_pagesets 178 179return the actual pagesets number. 180 181=item $pageset->first_pageset 182 183 my $chunk = $pageset->first_pageset; 184 185return the first pageset, it's Data::Page::Pageset::Chunk object 186 187=item $pageset->last_pageset 188 189 my $chunk = $pageset->last_pageset; 190 191return the last pageset, it's Data::Page::Pageset::Chunk object 192 193=item $pageset->current_pageset 194 195 my $chunk = $pageset->current_pageset; 196 197return the current pageset which current page is in this pageset, it's Data::Page::Pageset::Chunk object 198 199=item $pageset->previous_pageset 200 201 my $chunk = $pageset->previous_pageset; 202 203return the previous pageset, it's Data::Page::Pageset::Chunk object 204 205=item $pageset->next_pageset 206 207 my $chunk = $pageset->next_pageset; 208 209return the next pageset, it's Data::Page::Pageset::Chunk object 210 211=back 212 213=head1 Data::Page::Pageset::Chunk object 214 215a $pageset gives you some $chunk to do more stuff as you see above. Here gives the $chunk methods 216 217=over 218 219=item first 220 221 # return the first page number in this chunk 222 $chunk->first; 223 224=item last 225 226 # return the last page number in this chunk 227 $chunk->last; 228 229=item middle 230 231 # return the middle page number in this chunk 232 $chunk->middle; 233 234=item pages 235 236 # return the pages number in this chunk 237 $chunk->pages; 238 239=item is_current 240 241 # return true if this $chunk contains the current_page 242 $chunk->is_current; 243 244=item as_string 245 246 # if this chunk is from page 3 to 7, then print '3-7' 247 print $chunk; 248 print $chunk->as_string; 249 print $chunk->as_string('-'); 250 251 # you can change default '-' as: 252 print $chunk->as_string('~'); 253 254if the $chunk only contains one page, it will only return the page number. 255 256=back 257 258=head1 SEE ALSO 259 260L<Data::Page|Data::Page> is what we need, L<Data::Pageset|Data::Pageset> is the similar one, L<Template::Plugin::Pageset|Template::Plugin::Pageset> is the wrapper for this to using it more converiently in TT2 tempale. 261 262=head1 BUGS 263 264just mail me to <me@chunzi.org> 265 266=head1 COPYRIGHT AND LICENSE 267 268Copyright 2004 by Chun Sheng. 269 270This library is free software; you can redistribute it and/or modify 271it under the same terms as Perl itself. 272 273=head1 AUTHOR 274 275Chun Sheng, <me@chunzi.org> 276 277=cut 278