foto

Скрипт постраничной навигации

Автор темы: 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. Код не окончательный. По мере необходимости буду его дорабатывать
foto
  • Администратор
Добавить комментарий
  • Логин
  • E-mail (не обязательно)
Повторите рисунок:
antibot
© Sander-Development. 2009-2018.
При копировании, ссылка на источник обязательна.