S3.Blog

23 Февраля 2017
A A A   RSS-лента
"Я знаю, что ничего не знаю, но многие не знают и этого". Сократ [?].

Perl: Разбивка по страницам в прямом и обратном порядке

Дата последнего изменения: 1 Октября 2009
Метки статьи: Готовые решения, © Авторское, Perl
Данный метод, split_page(), предназначен для разбивки данных по страницам в прямом и обратном порядке.
 

Использование и синтаксис вызова:

Получаем из CGI номер текущей страницы, при page = all отображаются все элементы массива, без постраничной разбивки
my $page = CGI->param('page') || 0;

Формируем анонимный массив @{$data} для последующей постраничной разбивки.
В эту же переменную возвращается обработанный массив с данными.
my $data = load_data(.....);

Передаем в метод split_page() сформированный массив, и на выходе получаем $data, $list_page, $show_page
где:
$list_page - список номеров страниц
$show_page - регистр показа/скрытия ссылок на страницы
my ($list_page, $show_page) = (0,0);

($data, $list_page, $show_page) = split_page({
	list_records => $data,
	page => $page,
	count_records_page => 5,
	page_left_right => 3,
	reverse => 0
});

Параметры split_page()

  • list_records
    массив для постраничной разбивки
     
  • page
    номер страницы
     
  • count_records_page
    количество элементов на одной странице
     
  • page_left_right
    отображение ссылок на страницы - сколько видимых номеров страниц будет от текущей
    • пример 1
      у нас 20 страниц. page_left_right=3. текущая страница номер 1
      визуально это будет так: 
      страницы: 1 2 3 ... 20
       
    • пример 2
      у нас 20 страниц. page_left_right=5. текущая страница номер 12
      визуально это будет так: 
      страницы: 1 ... 7 8 9 10 11 12 13 14 15 16 17 ... 20
       
  • reverse
    показ страниц и возвращение массива в установленном порядке
    • при reverse=0 (по умолчанию)
      идет отображение от первого к последнему элементу массива
      показ страниц: 1 2 3 4 5 6 ...
       
    • при reverse=1
      идет отображение в обратном порядке.
      самый первый элемент массива данных на самой первой странице будет соответствовать последнему элементу массива до его обработки
      показ страниц: 6 5 4 3 2 1 ...


Универсальный код для HTML-шаблонов, учитывающий возможный реверс и показывающий все возможности модуля

  • для HTML::Template
    <tmpl_if show_page>
    Страницы: 
    <tmpl_loop pages_loop>
    	<tmpl_if PAGE_NUMBER_START><a href="?page=1">первая страница</a></tmpl_if>
    	<tmpl_if PAGE_PREV><tmpl_unless select_all><a href="?page=<tmpl_var PAGE_PREV>">предыдущая страница</a></tmpl_unless></tmpl_if>
    	<tmpl_loop PAGE_START><tmpl_if select_page><tmpl_var page><tmpl_else><a href="?page=<tmpl_var page>"><tmpl_var page></a></tmpl_if>  </tmpl_loop>
    	<tmpl_if PAGE_SM>...</tmpl_if>
    	<tmpl_loop PAGE_MEDIUM><tmpl_if select_page><tmpl_var page><tmpl_else><a href="?page=<tmpl_var page>"><tmpl_var page></a></tmpl_if>  </tmpl_loop>
    	<tmpl_if PAGE_ME>...</tmpl_if>
    	<tmpl_loop PAGE_END><tmpl_if select_page><tmpl_var page><tmpl_else><a href="?page=<tmpl_var page>"><tmpl_var page></a></tmpl_if>  </tmpl_loop>
    	<tmpl_if PAGE_NEXT><tmpl_unless select_all><a href="?page=<tmpl_var PAGE_NEXT>">следующая страница</a></tmpl_unless></tmpl_if>
    	<tmpl_if PAGE_NUMBER_END><a href="?page=<tmpl_var PAGE_NUMBER_END>">последняя страница</a></tmpl_if>
    	<tmpl_unless select_all><a href="?page=all">все</a><tmpl_else>все</tmpl_unless> 
    </tmpl_loop>
    </tmpl_if>
  • для Template::Toolkit
    [% IF self.show_page %]
    Страницы: 
    [% FOREACH page IN self.pages_loop %]
    	[% IF page.PAGE_NUMBER_START %]<a href="?page=1">первая страница</a>[% END %]
    	[% IF page.PAGE_PREV %][% UNLESS page.select_all %]<a href="?page=[% page.PAGE_PREV %]">предыдущая страница</a>[% END %][% END %]
    	[% FOREACH p IN page.PAGE_START %][% IF p.select_page %][% p.page %][% ELSE %]<a href="?page=[% p.page %]">[% p.page %]</a>[% END %]  [% END %]
    	[% IF page.PAGE_SM %]...[% END %]
    	[% FOREACH p IN page.PAGE_MEDIUM %][% IF p.select_page %][% p.page %][% ELSE %]<a href="?page=[% p.page %]">[% p.page %]</a>[% END %]  [% END %]
    	[% IF page.PAGE_ME %]...[% END %]
    	[% FOREACH p IN page.PAGE_END %][% IF p.select_page %][% p.page %][% ELSE %]<a href="?page=[% p.page %]">[% p.page %]</a>[% END %]  [% END %]
    	[% IF page.PAGE_NEXT %][% UNLESS page.select_all %]<a href="?page=<tmpl_var PAGE_NEXT>">следующая страница</a>[% END %][% END %]
    	[% IF page.PAGE_NUMBER_END %]<a href="?page=<tmpl_var PAGE_NUMBER_END>">последняя страница</a>[% END %]
    	[% UNLESS page.select_all %]<a href="?page=all">все</a>[% ELSE %]все[% END %]
    [% END %]
    [% END %]


А вот и сам Perl-метод split_page(), который это всё реализует:
sub split_page {
	my $self = shift;
	my $p = shift || return undef;

	my $list_records = $p->{list_records};
	my $page = $p->{page}||'D';
	my $count_records_page  = $p->{count_records_page} || 10;
	my $page_left_right = $p->{page_left_right} || 1;
	my $reverse = $p->{reverse} || 0;

	return undef unless $list_records && scalar(@{$list_records})>0;

	my $select_all = 0;
	$select_all = 1 if ($page eq 'all');

	my $count_records_total = scalar(@{$list_records});
	my ($page_start,$page_medium,$page_end);
	my $pE = int($count_records_total/$count_records_page);

	$pE++ if ($count_records_total/$count_records_page) > $pE;
	$page =~ s/\D//gi;
	$page = ($reverse)?$pE:1 unless $page;
	@{$list_records} = reverse @{$list_records} if $reverse;

	$page = $pE if $page >= $pE;
	$page_start = [{page=>1,select_page=>(!$select_all && $page==1)?1:0}];
	$page_end = [{page=>$pE,select_page=>(!$select_all && $page==$pE)?1:0}];

	my $pSM = ($page-$page_left_right <= 2) ? 0 : 1;
	my $pME = ($page+$page_left_right >= $pE-1) ? 0 : 1;

	if ($reverse){
		for (my $t=$page+$page_left_right;$t>=$page-$page_left_right;$t--){
			if (($t > 1) && ($t < $pE)){
				push(@{$page_medium},{page=>$t,select_page=>(!$select_all && $page==$t)?1:0});
			}
		}
		@{$list_records} = splice @{$list_records}, ($pE-$page)*$count_records_page, $count_records_page unless $select_all;
	}else{
		for (my $t=$page-$page_left_right;$t<=$page+$page_left_right;$t++){
			if (($t > 1) && ($t < $pE)){
				push(@{$page_medium},{page=>$t,select_page=>(!$select_all && $page==$t)?1:0});
			}
		}
		@{$list_records} = splice @{$list_records}, ($page-1)*$count_records_page, $count_records_page unless $select_all;
	}

	my $page_list = {
		PAGE_START  => ($reverse) ? $page_end : $page_start,
		PAGE_MEDIUM => ($page_medium) ? $page_medium : [],
		PAGE_END    => ($reverse) ? $page_start : $page_end,
		PAGE_SM     => ($reverse) ? $pME : $pSM,
		PAGE_ME     => ($reverse) ? $pSM : $pME,
		PAGE_PREV   => ($page > 1) ? ($page-1) : 0,
		PAGE_NEXT   => ($page < $pE) ? ($page+1) : 0,
		select_all  => $select_all,
	};
	return $list_records, $page_list, ($pE>1)?1:0;
}



Похожие материалы:




 
  Имя *:   Решите пример *: =
 
Полужирный Курсив Подчеркнутый Перечеркнутый
 
Вставить изображение Сделать цитатой Вставить ссылку Вставить код

Вставить смайл
 
 

 



© S3.Blog: Если критикуешь, не предлагая решения проблемы, то ты становишься частью этой проблемы.