Перейти к содержимому

Пагинация (Pagination)

Класс Pagination — это мощный инструмент для автоматического разбиения больших списков кнопок на страницы. Вместо того чтобы вручную высчитывать смещения (offset) и рисовать кнопки навигации (<, >), вы просто передаете массив всех элементов, а библиотека делает остальное.

Принцип работы

  1. Вы создаете массив всех кнопок (например, 50 товаров).
  2. Передаете их в Pagination.
  3. Настраиваете отображение (сколько кнопок на странице, стиль навигации).
  4. Указываете текущую страницу.
  5. Метод create() возвращает готовый массив кнопок для метода inlineKbd().

Базовое использование

Создадим простой список из 20 кнопок и отобразим первую страницу.

php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ZenithGram\ZenithGram\ZG;
use ZenithGram\ZenithGram\Button; // Используем современный класс кнопок

$tg = ZG::create(BOT_TOKEN);

// 1. Генерируем тестовый массив кнопок
$items = [];
for ($i = 1; $i <= 20; $i++) {
    // Создаем callback-кнопку для каждого товара
    $items[] = Button::cb("Товар #$i", "buy_item_$i");
}

// 2. Создаем пагинацию
$keyboard = $tg->pagination()
    ->setItems($items)          // Передаем наши кнопки
    ->setPerPage(5)             // 5 товаров на странице
    ->setPage(1)                // Показываем 1-ю страницу
    ->setPrefix('page_')        // Префикс для кнопок навигации (data будет page_1, page_2...)
    ->create();                 // Генерируем массив

// 3. Отправляем сообщение
$tg->msg("Список товаров (Страница 1):")
    ->inlineKbd($keyboard)
    ->send();

Обработка переключений (Интерактивность)

Самое важное в пагинации — заставить кнопки навигации работать. Кнопки навигации генерируют callback_data в формате: {prefix}{номер_страницы}.

Для обработки удобно использовать плейсхолдер в методе onCallback.

php
// Обработчик переключения страниц
// Ловим паттерн "page_" + число
$bot->onCallback('pagination_handler', 'page_{page}')
    ->func(function(ZG $tg, $page) use ($items) {
        $query_id = $tg->getQueryId();
        $tg->answerCallbackQuery($query_id); // Убираем "часики"

        // Генерируем клавиатуру для новой страницы
        // Важно: здесь нужно заново создать объект пагинации с теми же настройками
        $keyboard = $tg->pagination()
            ->setItems($items)
            ->setPerPage(5)
            ->setPage($page)     // Устанавливаем пришедшую страницу
            ->setPrefix('page_')
            ->create();

        // Редактируем сообщение
        $tg->msg("Список товаров (Страница $page):")
           ->inlineKbd($keyboard)
           ->editText();
    });

Продвинутая настройка

Библиотека позволяет гибко настраивать внешний вид пагинатора.

1. Режим навигации (Стрелки vs Цифры)

Вы можете выбрать, как будут выглядеть кнопки переключения страниц: классические стрелки или ряд номеров.

php
use ZenithGram\ZenithGram\Enums\PaginationMode;

// Режим: Стрелки (По умолчанию)
// Вид: [ < ] [ > ]
$tg->pagination()->setMode(PaginationMode::ARROWS);

// Режим: Номера страниц
// Вид: [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ]
$tg->pagination()->setMode(PaginationMode::NUMBERS);

2. Стилизация номеров страниц

Если выбран режим NUMBERS, вы можете настроить стиль цифр.

php
use ZenithGram\ZenithGram\Enums\PaginationNumberStyle;

// Классические цифры: 1, 2, 3...
$tg->pagination()->setNumberStyle(PaginationNumberStyle::CLASSIC);

// Эмодзи: 1️⃣, 2️⃣, 3️⃣...
$tg->pagination()->setNumberStyle(PaginationNumberStyle::EMOJI);

// Кастомный стиль (через функцию)
$tg->pagination()->setNumberStyle(fn($page) => "[ Стр. $page ]");

3. Расположение кнопок навигации (Layout)

Управляйте тем, как группируются кнопки навигации, если их много (например, "Назад", "Вперед", "В начало", "В конец").

php
use ZenithGram\ZenithGram\Enums\PaginationLayout;

// В одну строку (По умолчанию)
// [<<] [<] [>] [>>]
$tg->pagination()->setNavigationLayout(PaginationLayout::ROW);

// Разделение на две строки
// Строка 1: [<] [>]
// Строка 2: [<<] [>>]
$tg->pagination()->setNavigationLayout(PaginationLayout::SPLIT);

// Умная группировка (SMART)
// Автоматически разбивает на строки, если кнопок больше 2-х, чтобы они не были узкими.
$tg->pagination()->setNavigationLayout(PaginationLayout::SMART);

4. Быстрая навигация и выход

Добавьте кнопки "В начало / В конец" и кнопку "Назад в меню".

php
$tg->pagination()
    // Включаем кнопки быстрого перехода
    ->setSideSigns('⏮️ Начало', 'Конец ⏭️')
    
    // Меняем текст основных стрелок
    ->setSigns('⬅️ Назад', 'Вперед ➡️')
    
    // Добавляем отдельную кнопку "Вернуться" под пагинацией
    ->addReturnBtn('🔙 Выйти в меню', 'main_menu');

5. Формат активной страницы

Вы можете выделить текущую страницу, чтобы пользователь понимал, где находится (особенно актуально для режима номеров).

php
// Устанавливает обрамление для текущей страницы
// Если текущая страница 3, кнопка будет выглядеть как: - 3 -
$tg->pagination()->setActivePageFormat('- %s -');

Полный пример (Магазин "Pro")

Пример реализации сложного каталога с нумерацией страниц смайликами, умной группировкой кнопок и кнопкой возврата.

php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ZenithGram\ZenithGram\ZG;
use ZenithGram\ZenithGram\Bot;
use ZenithGram\ZenithGram\Button;
use ZenithGram\ZenithGram\Enums\PaginationMode;
use ZenithGram\ZenithGram\Enums\PaginationNumberStyle;
use ZenithGram\ZenithGram\Enums\PaginationLayout;

$tg = ZG::create(BOT_TOKEN);
$bot = new Bot($tg);

// Функция-помощник для создания клавиатуры
function getShopKeyboard(ZG $tg, int $page): array {
    // 1. Генерируем данные (30 товаров)
    $items = [];
    for ($i = 1; $i <= 30; $i++) {
        $items[] = Button::cb("📦 Товар $i", "buy_$i");
    }

    // 2. Настраиваем пагинацию
    return $tg->pagination()
        ->setItems($items)
        ->setPerPage(6)                         // 6 товаров на странице
        ->setColumns(2)                         // В 2 колонки
        ->setPage($page)                        // Текущая страница
        ->setPrefix('shop_page_')               // Префикс навигации
        
        // Включаем режим номеров с эмодзи
        ->setMode(PaginationMode::NUMBERS)
        ->setNumberStyle(PaginationNumberStyle::EMOJI)
        ->setMaxPageBtn(5)                      // Макс. 5 кнопок страниц (1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣)
        
        // Добавляем кнопку "В меню"
        ->addReturnBtn('🔙 В главное меню', 'main_menu')
        
        ->create();
}

// 1. Точка входа: команда /shop
$bot->onBotCommand('shop', '/shop')
    ->func(function(ZG $tg) {
        $kbd = getShopKeyboard($tg, 1);
        $tg->msg("🏪 Витрина магазина:")->inlineKbd($kbd)->send();
    });

// 2. Обработчик навигации (shop_page_1, shop_page_2...)
$bot->onCallback('shop_nav', 'shop_page_{page}')
    ->func(function(ZG $tg, $page) {
        $tg->answerCallbackQuery($tg->getQueryId());
        
        $kbd = getShopKeyboard($tg, $page);
        
        // Редактируем сообщение с новой клавиатурой
        $tg->msg("🏪 Витрина магазина (Стр. $page):")
           ->inlineKbd($kbd)
           ->editText();
    });

// 3. Обработчик кнопки возврата
$bot->onCallback('menu', 'main_menu')
    ->text('Вы вернулись в главное меню.')
    ->removeKbd() // Удаляем inline клавиатуру (редактируем на текст без кнопок)
    ->editText();

$bot->run();

Опубликовано под лицензией MIT.