[Moscow.pm] Постраничный вывод (Pagination)
Alessandro Gorohovski
angel на domashka.kiev.ua
Пн Апр 23 09:26:54 PDT 2012
oleg alexeenkov <proler на gmail.com> писал(а) в своём письме Mon, 23 Apr
2012 19:11:11 +0300:
> Alessandro Gorohovski <angel на domashka.kiev.ua> писал(а) в своём письме
> Mon, 23 Apr 2012 19:58:41 +0400:
>
>> Andrew Shitov <andy на shitov.ru> писал(а) в своём письме Mon, 23 Apr 2012
>> 18:49:39 +0300:
>>
>>> http://search.cpan.org/search?query=pagination&mode=all
>>> ?
>>
Олег,
Спасибо большое!
:)
Любопытный код. Буду ковыряться.
>
> [вброс] давным давно наковырял такую штуку, работает с миллиардами
> страниц 8) причем скорее всего путь перехода со страницы X на страницу Y
> будет наименьшим среди аналогов (особенно если подкрутить параметры)
>
> sub gotopage {
> my ($fparam) = @_;
> my (%ret);
> #$fparam->{'total'} : total results, usually COUNT(*) as total
> #-----------size -- : size of one page in rows (LIMIT x,size)
> #current : current page number
> #actual : usually $DBI::rows, if total unknown
> #last : last page number (auto calculated from total/size if 0)
> #total_max = 1000 : maximum db results
> #printlog('dmp', 'gotopage start:', Dumper($fparam));
> $fparam->{'size'} = 100 unless defined $fparam->{'size'};
> return {} unless $fparam->{'size'};
> $fparam->{'actual'} = $fparam->{'size'} unless defined
> $fparam->{'actual'};
> $fparam->{'current'} ||= 1;
> $fparam->{'last'} ||=
> $fparam->{'size'} < 1
> ? undef
> : ( int( $fparam->{'total'} / ( $fparam->{'size'} || 1 ) ) + (
> $fparam->{'total'} % ( $fparam->{'size'} || 1 ) ? 1 : 0 ) );
> $fparam->{'buttonsb'} ||= $config{'gotopage_bb'} || 5; #before
> $fparam->{'buttonsa'} ||= $config{'gotopage_ba'} || 5; #after
> $fparam->{'align'} = 1 unless defined $fparam->{'align'};
> $fparam->{'jumpten'} = 1 unless defined $fparam->{'jumpten'};
> $fparam->{'power'} = 2 unless defined $fparam->{'power'};
> my $fromto = sub {
> my ($n) = @_;
> return (
> ( ( ( $n - 1 ) * $fparam->{'size'} ) + 1 ) . '-'
> . (
> ( $fparam->{'total'} and ( $fparam->{'total'} < $n *
> $fparam->{'size'} ) ) ? $fparam->{'total'} : $n * $fparam->{'size'}
> )
> );
> };
> my $align = sub {
> my $a = int(shift);
> my $len = shift || $fparam->{'align'};
> substr( $a, $len, length($a) - $len ) = '0' x ( length($a) - $len )
> if $len > 0 and length($a) > $len;
> return $a;
> };
> #printlog('dmp', 'gotopage calc:'," <br\n/>" .Dumper($fparam) .
> "<br\n/>");
> my $next = $fparam->{'actual'} >= $fparam->{'size'};
> if ( ( !$fparam->{'total'} and $fparam->{'actual'} > 0 )
> or $fparam->{'total'} >= $fparam->{'size'}
> or $fparam->{'current'} > 1 )
> {
> $ret{'prev'}{ $fparam->{'current'} - 1 } = $fromto->(
> $fparam->{'current'} - 1 ) if $fparam->{'current'} > 1;
> for my $n ( ( $fparam->{'current'} > $fparam->{'buttonsb'} ?
> $fparam->{'current'} - $fparam->{'buttonsb'} : 2 )
> .. $fparam->{'current'} + ( $next ? $fparam->{'buttonsa'} : 0 ) )
> {
> last if $fparam->{'total'} and $n > $fparam->{'last'};
> last if $fparam->{'total_max'} and $n * $fparam->{'size'} >
> $fparam->{'total_max'};
> ( ( !$fparam->{'total'} and $n > $fparam->{'current'} + 1 ) ? (
> \%{ $ret{'small'} } ) : ( \%{ $ret{'big'} } ) )->{$n} =
> $fromto->($n);
> }
> if ( $fparam->{'jumpten'} ) {
> $fparam->{'jumpfrom'} ||= '1' . ( 0 x ( length(
> $fparam->{'current'} - $fparam->{'buttonsb'} ) - 1 ) );
> $fparam->{'jumpto'} ||= '1' . ( 0 x length( $fparam->{'current'}
> + $fparam->{'buttonsa'} ) );
> $ret{'big'}{$_} = $fromto->($_)
> for grep { !$fparam->{'last'} or $_ <= $fparam->{'last'} }
> map { '1' . ( 0 x $_ ) } 1 .. length( $fparam->{'current'} ) -
> 1;
> if ($next) {
> $ret{'big'}{$_} = $fromto->($_)
> for map { '1' . ( 0 x $_ ) } length( $fparam->{'current'} )
> .. length( $fparam->{'last'} ) - 1;
> }
> }
> $fparam->{'jumpfrom'} ||= 1;
> $fparam->{'jumpto'} ||= $fparam->{'last'};
> #$fparam->{'jumpto'} = psmisc::min( $fparam->{'jumpto'},
> $fparam->{'last'} );
> $fparam->{'jumpto'} = $fparam->{'last'} if $fparam->{'last'} <
> $fparam->{'jumpto'};
> if ( $fparam->{'power'} > 1 ) {
> my ($n);
> $n = $fparam->{'current'} - $fparam->{'buttonsb'} *
> $fparam->{'power'};
> for (
> $_ = $fparam->{'buttonsb'} ;
> $fparam->{'jumpfrom'} >= 1 and $n > $fparam->{'jumpfrom'} and
> $n < $fparam->{'last'} ;
> $n -= ( $_ *= $fparam->{'power'} )
> )
> {
> $ret{'big'}{ $align->($n) } = $fromto->( $align->($n) );
> }
> $n = $fparam->{'current'} + $fparam->{'buttonsa'} *
> $fparam->{'power'};
> for ( $_ = $fparam->{'buttonsa'} ; $next and $n <
> $fparam->{'jumpto'} ; $n += ( $_ *= $fparam->{'power'} ) ) {
> $ret{'big'}{ $align->($n) } = $fromto->( $align->($n) );
> }
> }
> $ret{'big'}{ $fparam->{'last'} } = $fromto->( $fparam->{'last'} )
> if $fparam->{'last'} > 1 and $next;
> $ret{'big'}{1} ||= $fromto->(1)
> if ( $fparam->{'last'} > 1 or !$fparam->{'total'} )
> and $fparam->{'actual'} >= $fparam->{'size'};
> $ret{'next'}{ $fparam->{'current'} + 1 } = $fromto->(
> $fparam->{'current'} + 1 )
> if $next and !$fparam->{'last'}
> or $fparam->{'current'} < $fparam->{'last'};
> }
> #printlog('dmp', 'gotopage ret:', Dumper(\%ret));
> return wantarray ? ( sort { $a <=> $b } keys %{ $ret{'big'} }, keys
> %{ $ret{'small'} } ) : \%ret;
> }
Подробная информация о списке рассылки Moscow-pm