====== Постраничный вывод данных в WACT-шаблонах ====== Чаще всего списки слишком длинные, чтобы их показывать на одной странице. Для решения этой проблемы применяют разбиение списков на страницы. Этот список страниц обычно называют пейджером (pager). Задача по разбиению длинных списков на страницы состоит из 2 под-задач: * Вывод pager-а. * Лимитирование списка, так что бы он содержал данные для текущей страницы. В случае с выборкой из базы данных - применение limit, offset. ===== Вывод pager-а ===== Для вывода pager-а используется группа тегов Pager Tags. Приведем пример: Показаны новости: с {$BeginItemNumber} по {$EndItemNumber} Первая страница {$number} {$number} Последняя страница Всего новостей: {$TotalItems} Центральный тег при постраничном разбиении - [[.:tags:pager_tags:pager_navigator_tag|]], который ограничивает пейджер. Он содержит атрибут **items**, который указывает, какое количество элементов списка выводить на одной странице. Тег [[.:tags:pager_tags:pager_list_tag|]] - организует вывод номеров страниц pager-а. Остальные теги * [[.:tags:pager_tags:pager_first_tag|]] - выводит ссылку на первую страницу * [[.:tags:pager_tags:pager_prev_tag|]] - на предыдущую (здесь не использовался) * [[.:tags:pager_tags:pager_current_tag|]] - на текущую, * [[.:tags:pager_tags:pager_next_tag|]] - на следующую (здесь не использовался) * [[.:tags:pager_tags:pager_last_tag|]] - на последнюю страницу * [[.:tags:pager_tags:pager_number_tag|]] - на страницу с определенным номером. Внутри каждого тега доступна переменная **$href**, содержащая ссылку на нужную страницу. Теги и также содержат переменную **$number** - номер страницы. Также внутри тега доступны следующие предопределенные свойства: * **{$%%TotalItems%%}** - общее количество элементов в списке, * **{$%%BeginItemNumber%%}** - номер элемента, с которого начинается текущая страница, * **{$%%EndItemNumber%%}** - номер элемента, которым заканчивается текущая страница. * **{$%%HasMoreThanOnePage%%}** - true, если страниц больше чем одна. Обычно проекте реализуют один (или несколько) pager-ов, которые обычно подключаются к спискам по мере необходимости при помощи тега [[.:tags:core_tags:core_include_tag|]]. ===== Лимитирование списка ===== ==== В php-скрипте ==== Допустим у нас есть шаблон: First Prev [...] Next Last
{$name} {$description|default:" "|raw}
Для связи 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 поддерживают эти методы). ==== В шаблоне при помощи тега ==== Связывать pager-ы и список в php-скрипте каждый раз довольно утомительно, поэтому начиная с версии WACT 0.3 стал доступен тег [[.:tags:pager_tags:paginate_tag|]], который проводит связывание прямо в шаблоне. Вот модифицированный код примеры с использованием тега : First Prev [...] Next Last
{$name} {$description|default:" "|raw}
Теперь наш php-скрипт можно сделать намного короче: $template = new WactTemplate('page.html'); $data = ...;// заполнение переменной data $template->setChildDataset('modules', $data); $template->display(); Обратите внимание, что данные в списке должны быть до момента отработки тега . Если вы используете WACT традиционным способом - данные ставятся напрямую в шаблон, то это не будет проблемой. ==== В шаблоне при помощи тегов и ==== Если вы используете пакет WEB_APP и из него теги [[.:tags:fetch_tags:fetch_tag|]] или [[.:tags:iterator_tags:iterator_transfer_tag|]], тогда вы можете связать pager со списком при помощи атрибута **navigator**, например: [...] [...] Здесь действует только одно условие - контейнер данных, который получается из 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]. см. также описание тега [[.:tags:pager_tags:pager_navigator_tag|]]. ==== Разрывы (elipses) ==== Для вывода разрывов используется тег [[limb3:ru:packages:wact:tags:pager_tags:pager_elipses_tag|]], а также атрибуты **pages_in_middle** и **pages_in_sides** тега . Пример: {$number} {$number} ... - Выведет приблительно следующий pager: 1-2-3...6-7-8-9-10...15-16-17 ==== Секции (sections) ==== Для вывода секций используется тег [[.:tags:pager_tags:pager_section_tag|]], а также атрибут **pages_per_section** тега . Пример: [{$number_begin}..{$number_end}] {$number} {$number} - Внутри тега можно использовать переменные **$number_begin** и **$number_end**. Выведет приблизительно следующий pager: [1..5][6..10]11-12-13-14-15[16..17] ===== Отказ от вывода pager-а, если список содержит только 1 страницу ===== Тег [[.:tags:pager_tags:pager_navigator_tag|]] содержит предопределенное свойство **$%%HasMoreThanOnePage%%**. На основе данного свойства можно прятать остальное содержимое pager-а, если в списке всего одна страница: Всего в списке : {$TotalItems}. Показаны элементы: от {$BeginItemNumber} до {$EndItemNumber} [...] ===== Дополнительные примеры ===== * Очень подробный пример использования группы тегов Pager Tags приведен на странице описание тега [[.:tags:pager_tags:pager_navigator_tag|]]. * Рабочие примеры использование pager-ов см. в папке **limb/wact/examples/tag/pager/**.