Новый вариант функции для постраничной навигации на PHP
Функция пагинации (постраничной навигации)
Появилась необходимость создания простой и эффективной функции для пагинации (постраничной навигации) на PHP для произвольного набора страниц.
Пришлось с нуля прорабатывать этот вопрос, и вот что у нас получилось:
Для начала мы исходили из 2 параметров: максимального количества страниц и текущей страницы: $max_p и $curr_p соответственно. Пагинацию решили сразу не выводить, а возвращать в качестве переменной.
Соответственно для вывода постраничной навигации на Ваших страницах нужно вставить такой код
echo cessel_corenavi($max_p,$curr_p,$link,$format);
Где:
$max_p = максимальное количество страниц;
$curr_p = номер текущей станицы
$link — базовая ссылка, ссылка на страницу категории, без номеров страниц
$format — формат добавления номеров страниц в ссылку (ex. ?page=1) в соответствии с форматом функции sprintf
А теперь по порядку:
Сама функция генерирует пагинацию из следующих блоков:
- Блок кнопки «Назад»
- Блок кнопок начала навигации (первые несколько страниц)
- Блок кнопок слева от текущей страницы
- Текущая страница
- Блок кнопок справа от текущей страницы
- Блок кнопок конца навигации (последние несколько страниц)
- Блок кнопки «Далее»
- Блок пробела между начальными страницами и средней частью пагинации
- Блок пробела между средней частью пагинации конечными страницами
- Соединение все в одну переменную для вывода.
Блок кнопки «Назад»
$prev_p = $curr_p-1;
$prev_text = '<span aria-hidden="true">«</span>';
if($curr_p==1)
{
$prev_block="<li class='disabled'><a href='#'>".$prev_text."</a></li>";
}
else
{
$prev_block = "<li><a href='".$link.sprintf ($format,$prev_p)."/' title='".$prev_text."'>".$prev_text."</a></li>";
}
Весьма все просто:
- $prev_text — то что отображается в самой кнопке «Назад» в данном случае это кавычки имитирующие стрелки влево.
- $prev_block — переменная для последующего вывода блока
- $prev_p — номер предыдущей страницы (в случае, когда страница первая, ссылка становиться не активной)
Блок кнопок начала навигации (первые несколько страниц)
$max_s = $curr_p - 2;
if($max_s>2)
{
$max_s=2;
}
if(($max_s > 2) && ($max_s < 1))
{
$start_block = '';
}
else
{
for($i=1;$i<=$max_s;$i++)
{
$start_block .= "<li><a href='".$link.sprintf ($format,$i)."/' title='Страница ".$i."'>".$i."</a></li>";
}
}
Тут несколько сложнее:
Первое мы определились, что начальных кнопок будет 2 (можно подставить любое число).
Далее нужно чтобы было красиво то есть текущая страница выделялась, а соответственно отображение кнопки текущей страницы и блоков слева и справа от нее будет приоритетным. А на практике — если блок кнопок текущей страницы с соседями, находится в начале, или в конце блока пагинации, то он замещает собой блок начала или конца пагинации. Ну а по мере увеличения номера страницы, и смещения блока текущей страницы и соседей, отображается уже блок начала (в конце точно также).
В приведенном выше коде:
$max_s — максимальный номер страница для отображения в начале пагинации
$start_block — переменная для последующего вывода блока
$i — переменная цикла для вывода всех начальных страниц
Блок кнопок слева от текущей страницы
$l_cp = $curr_p-1;
if($l_cp<1)
{
$left_cp_block='';
}
else
{
$left_cp_block = "<li><a href='".$link.sprintf ($format,$l_cp)."/' title='Страница ".$l_cp."'>".$l_cp."</a></li>";
}
Просто вывод на одно страницу назад. Не предусматривает изменения количества центральных страниц, в последующих версиях добавим такую возможность.
Текущая страница
$curr_block = "<li class='active'><a href='".$link.sprintf ($format,$curr_p)."/' title='Страница ".$curr_p."'>".$curr_p."</a></li>";
Блок кнопок справа от текущей страницы
$r_cp = $curr_p+1;
if($r_cp>$max_p)
{
$right_cp_block='';
}
else
{
$right_cp_block = "<li><a href='".$link.sprintf ($format,$r_cp)."/' title='Страница ".$r_cp."'>".$r_cp."</a></li>";
}
Аналогично блоку слева.
Блок кнопок конца навигации (последние несколько страниц)
$min_e = $curr_p + 2;
if($min_e <= ($max_p - 2))
{
$min_e = $max_p - 1;
}
if(($min_e < ($max_p - 1)) && ($min_e > $max_p))
{
$end_block = '';
}
else
{
$end_block = '';
for($i=$min_e;$i<=$max_p;$i++)
{
$end_block .= "<li><a href='".$link.sprintf ($format,$i)."/' title='Страница ".$i."'>".$i."</a></li>";
}
}
Аналогично блоку начала пагинации
Блок кнопки «Далее»
$next_text = '<span aria-hidden="true">»</span>';
if($next_p>=($max_p-1))
{
$next_block = "<li class='disabled'><a href=''>".$next_text."</a></li>";
}
else
{
$next_block = "<li><a href='".$link.sprintf ($format,$next_p)."/' title='".$next_text."'>".$next_text."</a></li>";
}
Аналогично блоку кнопки «Назад»
Блок пробела между начальными страницами и средней частью пагинации
if(($max_s<($l_cp-1)))
{
$spaces_l = "<li><a href='#...' title=''>...</a></li>";
}
Блок пробела между средней частью пагинации конечными страницами
if(($min_e>($r_cp+1)))
{
$spaces_r = "<li><a href='#...' title=''>...</a></li>";
}
Необходимы когда страниц больше 6 — заполняет пробелы между блоками номеров страниц в начале и в конце
Соединение все в одну переменную для вывода.
$pagination = "<div><ul class='pagination'>";
$pagination .= $prev_block;
$pagination .= $start_block;
$pagination .= $spaces_l;
$pagination .= $left_cp_block;
$pagination .= $curr_block;
$pagination .= $right_cp_block;
$pagination .= $spaces_r;
$pagination .= $end_block;
$pagination .= $next_block;
$pagination .= "</ul></div>";
Тут все блоки соединяются воедино. В одной переменной и оборачиваются в тег <div>.
В дальнейшем эту функцию можно доработать под себя, ну и, конечно, оформить с помощью CSS.
Функцию целиком вы можете найти у меня в репозитории.