Скрипт постраничной навигации
Автор темы: Sander, 9 марта 2017г
• Sander
Отправлено: 9 март 2017, 23:46:36
Простой скрипт навигации, который можно легко использовать в модулях, админке и т.д.class navigation
{
/**
* @var string чистый URL по умолчанию
* В адресе может быть указано место для размещения блока с номером страницы, тег {page}
* Пример:
* /some_url{page}.html
* В итоге адрес будут:
* /some_url.html
* /some_url/page_2.html
* Если тег {page} не указан, то страницы будут дописываться в конец адреса
*/
var $base_url = '/';
/**
* @var string шаблон ссылки навигации
*/
var $tpl = 'page/{page}/';
/**
* @var string Обертка кнопок
*/
var $wrap = "\n<div class=\"navigation\">\n{pages}</div>\n\n";
/**
* @var int сколько показывать кнопок страниц до и после актуальной
* Пример:
* $spread = 2
* Всего 9 страниц навигации и сейчас просматривают 5ю
* 1 ... 3 4 5 6 7 ... 9
*/
var $spread = 5;
/**
* @var string разрыв между номерами страниц
*/
var $separator = "\t<i>...</i>\n";
/**
* @var string имя класса активной страницы
*/
var $active_class = 'link_active';
/**
* @var int номер просматриваемой страницы
*/
var $current_page = 0;
/**
* @var bool показывать кнопки "Вперед" и "Назад"
*/
var $next_prev = true;
/**
* @var string текст кнопки "Назад"
*/
var $prev_title = 'Назад';
/**
* @var string текст кнопки "Вперед"
*/
var $next_title = 'Вперед';
/**
* Инициализация класса
* @param string $base_url URL в конец которого будет добавляться навигация
*/
function __construct( $base_url = '/' )
{
$this->base_url = $base_url;
}
/**
* Строим навигации и формируем шаблон
* @param int $limit количество записей на 1 страницу
* @param int $count_all общее количество всех записей
* @param int $current_page номер просматриваемой страницы
* @return - Сформированный шаблон навигации готовый к выводу
*/
function build( $limit, $count_all, $current_page = 1 )
{
if( $limit < 1 OR $count_all <= $limit ) return;
$count_pages = ceil( $count_all / $limit );
if( $current_page > $count_pages ) {
header( "HTTP/1.0 301 Moved Permanently" );
header( "Location: " . $this->get_url( $count_pages ) );
die( "Redirect" );
}
if( $current_page == 1 AND $_SERVER['REQUEST_URI'] != $this->get_url( $current_page ) )
{
header( "HTTP/1.0 301 Moved Permanently" );
header( "Location: " . $this->get_url( $current_page ) );
die( "Redirect" );
}
$this->current_page = intval( $current_page );
if( $this->current_page < 1 ) $this->current_page = 1;
$shift_start = max( $this->current_page - $this->spread, 2 );
$shift_end = min( $this->current_page + $this->spread, $count_pages-1 );
if( $shift_end < $this->spread*2 ) $shift_end = min( $this->spread*2, $count_pages-1 );
if( $shift_end == $count_pages - 1 AND $shift_start > 3 ) $shift_start = max( 3, min( $count_pages - $this->spread*2 + 1, $shift_start ) );
$list = $this->get_item( 1 );
if( $shift_start == 3 ) $list .= $this->get_item( 2 );
elseif( $shift_start > 3 ) $list .= $this->separator;
for( $i = $shift_start; $i <= $shift_end; $i++ ) $list .= $this->get_item( $i );
$last_page = $count_pages - 1;
if( $shift_end == $last_page-1 ) $list .= $this->get_item( $last_page );
elseif( $shift_end < $last_page ) $list .= $this->separator;
$list .= $this->get_item( $count_pages );
if( $this->next_prev ) $list = $this->get_item( $this->current_page > 1 ? $this->current_page - 1 : 1, $this->prev_title, true ) . $list . $this->get_item( $this->current_page < $count_pages ? $this->current_page + 1 : $count_pages, $this->next_title, true );
return str_replace( "{pages}", $list, $this->wrap );
}
/**
* Формирование адреса
* @param int $page_num номер страницы
* @return string сформированный адрес
*/
private function get_url( $page_num = 0 )
{
$page = $page_num > 1 ? str_replace( '{page}', $page_num, $this->tpl ) : '';
if( stripos( $this->base_url, '{page}' ) !== false ) return str_replace( '{page}', $page, $this->base_url );
else return $this->base_url . $page;
}
/**
* Формирование кнопки/ссылки
* @param int $page_num номер страницы
* @param string $page_name если указано, будет выводиться текст вместо номера страницы
* @param bool $noclass
* @return - span блок с активной страницей или ссылку.
*/
private function get_item( $page_num, $page_name = '', $noclass = false )
{
$page_name = $page_name ?: $page_num;
$class = $noclass ? '' : ' class="' . $this->active_class . '"';
if( $this->current_page == $page_num ) return "\t<span" . $class . ">" . $page_name . "</span>\n";
return "\t<a href=\"" . $this->get_url( $page_num ) . "\">" . $page_name . "</a>\n";
}
}
Пример использования:
$navi = new navigation( $url_page . '/' );
echo $navi->build( $config['news_number'], $count_all, $_GET['cstart'] );
где:
$url_page - основной URL страницы со слешем на конце. К этому адресу будет добавлен код по шаблону, по умолчанию page/{page}/
$config['news_number'] - количество записей на страницу
$count_all - общее количество записей
$_GET['cstart'] - номер просматриваемой страницы
Пример с указанием индивидуальных параметров:
$navi = new navigation( $url_page );
$navi->tpl = "?page={page}"; //URL будет иметь вид: http://site.ru/some_page.html?page=4
$navi->wrap = "\n<div class=\"navigation\">\n{pages}</div>\n\n"; //Обертка для придания стилей навигации
$navi->spread = 2; //Количество страниц отображаемых по бокам от просматриваемой. Пример: 1 ... 5 6 [7] 8 9 ... 24
$navi->separator = "\t<i>...</i>\n"; //Ноу комментс.
$navi->next_prev = false; //По умолчанию слева и справа от страниц навигации отображаются кнопки "Назад" и "Вперед". Этот параметр их отключает.
$navi->prev_title = "Назад"; //Текст кнопки
$navi->next_title = "Вперед"; //Текст кнопки
echo $navi->build( $config['news_number'], $count_all, $_GET['cstart'] );
Пример 2. Если номер страницы указывается внутри ссылки, к примеру адрес имеет вид:
example.com/some_url.html
example.com/some_url,page=2.html
Следует подключать так:
$navi = new navigation( 'example.com/some_url{page}.html' );
$navi->tpl = ",page={page}";
Встроен редирект на последнюю существующую страницу, если к примеру материалы были удалены и более не существует указанного номер страницы.
Так же встроен редирект для первой страницы, для избежания дубля.
PS. Код не окончательный. По мере необходимости буду его дорабатывать