Инструменты пользователя

Инструменты сайта


limb3:ru:packages:wact:pagination

Постраничный вывод данных в WACT-шаблонах

Чаще всего списки слишком длинные, чтобы их показывать на одной странице. Для решения этой проблемы применяют разбиение списков на страницы. Этот список страниц обычно называют пейджером (pager).

Задача по разбиению длинных списков на страницы состоит из 2 под-задач:

  • Вывод pager-а.
  • Лимитирование списка, так что бы он содержал данные для текущей страницы. В случае с выборкой из базы данных - применение limit, offset.

Вывод pager-а

Для вывода pager-а используется группа тегов Pager Tags.

Приведем пример:

<active:record using='src/model/News' target='news' navigator='my_pager'/>
 
<pager:NAVIGATOR id="my_pager" items="10">
 
Показаны новости: с <b>{$BeginItemNumber}</b> по <b>{$EndItemNumber}</b>
 
<pager:FIRST><a href="{$href}">Первая страница </a></pager:FIRST>
 
<pager:LIST>
 
<pager:CURRENT><b><a href="{$href}">{$number}</a></b></pager:CURRENT>
<pager:NUMBER><a href="{$href}">{$number}</a></limb:pager:NUMBER>
 
</pager:LIST>
 
<pager:LAST><a href="{$href}">Последняя страница</a></pager:LAST>
 
Всего новостей: <b>{$TotalItems}</b>
</pager:NAVIGATOR>

Центральный тег при постраничном разбиении - <pager:NAVIGATOR>, который ограничивает пейджер. Он содержит атрибут items, который указывает, какое количество элементов списка выводить на одной странице.

Тег <pager:list> - организует вывод номеров страниц pager-а.

Остальные теги

  • <pager:FIRST> - выводит ссылку на первую страницу
  • <pager:PREV> - на предыдущую (здесь не использовался)
  • <pager:CURRENT> - на текущую,
  • <pager:NEXT> - на следующую (здесь не использовался)
  • <pager:LAST> - на последнюю страницу
  • <pager:NUMBER> - на страницу с определенным номером.

Внутри каждого тега доступна переменная $href, содержащая ссылку на нужную страницу. Теги <pager:NUMBER> и <pager:CURRENT> также содержат переменную $number - номер страницы.

Также внутри тега <pager:NAVIGATOR> доступны следующие предопределенные свойства:

  • {$TotalItems} - общее количество элементов в списке,
  • {$BeginItemNumber} - номер элемента, с которого начинается текущая страница,
  • {$EndItemNumber} - номер элемента, которым заканчивается текущая страница.
  • {$HasMoreThanOnePage} - true, если страниц больше чем одна.

Обычно проекте реализуют один (или несколько) pager-ов, которые обычно подключаются к спискам по мере необходимости при помощи тега <core:include>.

Лимитирование списка

В php-скрипте

Допустим у нас есть шаблон:

<pager:navigator id="pager" items="5">
    <pager:first><a href='{$href}'>First</a></pager:first> <pager:prev><a href='{$href}'>Prev</a></pager:prev>
    <pager:list>
     [...]
    </pager:list>
    <pager:next><a href='{$href}'>Next</a></pager:next> <pager:last><a href='{$href}'>Last</a></pager:last>
</pager:navigator>
 
<list:LIST id='modules'>
  <TABLE width="100%" BORDER="1" ALIGN="CENTER">
    <list:ITEM>
      <TR>
        <TD>{$name}</TD>
        <TD>{$description|default:"&nbsp;"|raw}</TD>
      </TR>
    </list:ITEM>
  </TABLE>
</list:LIST>

Для связи pager-а со списком можно применить следующий код:

$template = new WactTemplate('page.html');
 
$data = ...;// заполнение переменной data
 
$list = $template->findChild('modules');
$list->registerDataset($data); // Переводит $data в объектный вид, если необходимо
 
$pager = $template->getChild('pager', $dataset);
$dataset = $list->getDataset();
$pager->setPagedDataSet($dataset);
$dataset->paginate($pager->getStartingItem(), $pager->getItemsPerPage());
 
$template->display();

Если метод registerDataset() получает в качетве аргумента обычный массив, то он обворачивает его в WactArrayIterator, который поддерживает разбиение массива на страницы. В противном случае, аргумент метода registerDataset() должен поддерживать метод countPaginated() и paginate() для того, чтобы его можно было использовать с pager-ом (Базовые классы Limb поддерживают эти методы).

В шаблоне при помощи тега <paginate>

Связывать pager-ы и список в php-скрипте каждый раз довольно утомительно, поэтому начиная с версии WACT 0.3 стал доступен тег <paginate>, который проводит связывание прямо в шаблоне.

Вот модифицированный код примеры с использованием тега <paginate>:

<paginate list='modules' with='pager'/>
 
<pager:navigator id="pager" items="5">
    <pager:first><a href='{$href}'>First</a></pager:first> <pager:prev><a href='{$href}'>Prev</a></pager:prev>
    <pager:list>
     [...]
    </pager:list>
    <pager:next><a href='{$href}'>Next</a></pager:next> <pager:last><a href='{$href}'>Last</a></pager:last>
</pager:navigator>
 
<list:LIST id='modules'>
  <TABLE width="100%" BORDER="1" ALIGN="CENTER">
    <list:ITEM>
      <TR>
        <TD>{$name}</TD>
        <TD>{$description|default:"&nbsp;"|raw}</TD>
      </TR>
    </list:ITEM>
  </TABLE>
</list:LIST>

Теперь наш php-скрипт можно сделать намного короче:

$template = new WactTemplate('page.html');
 
$data = ...;// заполнение переменной data
 
$template->setChildDataset('modules', $data);
$template->display();

Обратите внимание, что данные в списке должны быть до момента отработки тега <paginate>. Если вы используете WACT традиционным способом - данные ставятся напрямую в шаблон, то это не будет проблемой.

В шаблоне при помощи тегов <fetch> и <iterator:transfer>

Если вы используете пакет WEB_APP и из него теги <fetch> или <iterator:transfer>, тогда вы можете связать pager со списком при помощи атрибута navigator, например:

<fetch using='src/fetcher/NewsFetcher' target='news' navigator='my_pager'>
 
<pager:NAVIGATOR id="my_pager" items="10">
[...]
</limb:pager:NAVIGATOR>
 
<list:list id='news'>
[...]
</list:list>

Здесь действует только одно условие - контейнер данных, который получается из fetcher-а должен поддерживать метод paginate($offset, $limit). В большинстве случаев, если вы используете пакеты Limb (DATASOURCE или DBAL), вам об этом не нужно думать.

А если страниц очень много?

Если у вас слишком много страниц (ну скажем больше 20), то можно применить 2 варианта:

  • Ввести разрывы (elipses) - когда отображаются страницы в начале, в середине и в конце списка страниц, а в остальных местах - пропуски. Это выглядит приблизительно так: 1-2-3…7-8-9-10-11…17-18-19
  • Ввести секции (sections) - некоторые блоки страниц, которые показывают только начальную и конечную страницы блока. Только 1 секция активна в текущий момент. Это выглядит приблизительно так: [1-5]6-7-8-9-10[11-15][16-19].

см. также описание тега <pager:navigator>.

Разрывы (elipses)

Для вывода разрывов используется тег <pager:elipses>, а также атрибуты pages_in_middle и pages_in_sides тега <pager:navigator>.

Пример:

<pager:NAVIGATOR id="pager" items="5" pages_in_middle="5" pages_in_sides="3">
 
<pager:LIST>
<pager:CURRENT><b><a href="{$href}">{$number}</a></b></pager:CURRENT>
<pager:NUMBER><a href="{$href}">{$number}</a></pager:NUMBER>
<pager:ELIPSES>...</pager:ELIPSES>
<pager:SEPARATOR>-</pager:SEPARATOR>
</pager:LIST>
 
</pager:NAVIGATOR>

Выведет приблительно следующий pager:

 1-2-3...6-7-8-9-10...15-16-17

Секции (sections)

Для вывода секций используется тег <pager:section>, а также атрибут pages_per_section тега <pager:navigator>.

Пример:

<pager:NAVIGATOR id="pager" items="5" pages_per_section="5">
 
<pager:LIST>
<pager:SECTION><a href="{$href}">[{$number_begin}..{$number_end}]</a></pager:SECTION>
<pager:CURRENT><b><a href="{$href}">{$number}</a></b></pager:CURRENT>
<pager:NUMBER><a href="{$href}">{$number}</a></pager:NUMBER>
<pager:SEPARATOR>-</pager:SEPARATOR>
</pager:LIST>
 
</pager:NAVIGATOR>

Внутри тега <pager:section> можно использовать переменные $number_begin и $number_end.

Выведет приблизительно следующий pager:

[1..5][6..10]11-12-13-14-15[16..17]

Отказ от вывода pager-а, если список содержит только 1 страницу

Тег <pager:navigator> содержит предопределенное свойство $HasMoreThanOnePage. На основе данного свойства можно прятать остальное содержимое pager-а, если в списке всего одна страница:

<pager:NAVIGATOR id="site_pager" items="50">
<core:optional for='HasMoreThanOnePage'>
Всего в списке : {$TotalItems}. Показаны элементы: от <b>{$BeginItemNumber}</b> до <b>{$EndItemNumber}</b>
 
[...]
</core:optional>
</limb:pager:NAVIGATOR>

Дополнительные примеры

  • Очень подробный пример использования группы тегов Pager Tags приведен на странице описание тега <pager:navigator>.

* Рабочие примеры использование pager-ов см. в папке limb/wact/examples/tag/pager/.

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
   ___   _   __   ____   ____   ____
  / _ | | | / /  / __/  / __/  /  _/
 / __ | | |/ /  _\ \   / _/   _/ /  
/_/ |_| |___/  /___/  /_/    /___/
 
limb3/ru/packages/wact/pagination.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)