Урок 6. Вывод списка постов на страницу и пагинация

Урок 6. Вывод списка постов на страницу и пагинация

Сегодня будет завершающая статья из серии уроков по разработки автокомплит плагина. В связи с расширением ф-ла плагина, было внесено множество правок. Так что код придется полностью рассмотреть с самого начала, но без особых подробностей. Если вкратце, то было добавлено два дополнительных шорткода для более гибкой манипуляции с результатом вывода. Один шорткод для вывода списка статей, второй - для отображения пагинации.

Небольшое отступление. Использование git в своих проектах, очень упрощает жизнь, и не требует практически никаких временных вложений, а финансовых тем более (привет bitbucket и gitlab). Просматривая код, видно прекрасно где что было изменено и на что.

А теперь, перейдем к работе

Добавляем в свойства класса, две переменные:

private $QueryPosts;
private $posts_per_page = 10;

что нам это дает?
$QueryPosts, мы будем использовать в двух других шорткодах (пагинация и вывод данных), поэтому мы выносим объект WP_Query в свойства класса.
$posts_per_page, содержит количество постов отображаемых на одной странице. Да, да, мы можем продублировать десятку в двух местах. Но… управлять этим все же лучше с одного места. К примеру, если мы захотим расширить наш базовый шорткод “[post-autocomplete-form]”, добавив в него параметр “постов на страницу”. К примеру так - “[post-autocomplete-form posts_per_page=10]”.

И в конструктор добавляем два новых шорткода:

add_shortcode('post-autocomplete-posts', array($this, 'shortcode_post_autocomplete_posts'));
add_shortcode('post-autocomplete-pagination', array($this, 'shortcode_post_autocomplete_pagination'));

Шорткод формы

За шорткод “[post-autocomplete-form]”, отвечает метод:

public function shortcode_post_autocomplete_form()
{
	global $post;

	$content = '';
	if(is_a($post, 'WP_Post'))
	{
		$content .= '<form action="' . get_permalink($post -> ID) . '" class="post-autocomplete-form" method="GET">';
		$content .= '<input type="text" name="text" class="post-autocomplete__field" placeholder="Введите текст для поиска" value="'.filter_input(INPUT_GET, 'text', FILTER_SANITIZE_STRING).'">';
		$content .= '</form>';
	}

	return $content;
}

На форму мы добавили атрибут actiion с ссылкой на текущую страницу, и чтобы не было ошибок. Добавили проверку глобальной переменной $post.

Шорткод отображающий список найденных постов

Его я назвал “[post-autocomplete-posts]”, и за него отвечает метод:

public function shortcode_post_autocomplete_posts()
{
	//Sets
	$content = '';
	$page = max(1, get_query_var('paged'));
	$text_search = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_STRING);
	$offset = $this -> posts_per_page * ($page - 1);

	if(empty($text_search))
	{
		return '';
	}

	$this -> QueryPosts = new WP_Query();
	$Posts = $this -> QueryPosts -> query([
		'posts_per_page' => $this -> posts_per_page,
		'offset' => $offset,
		's' => $text_search,
		'orderby' => 'title',
		'order' => 'ASC',
	]);

	if($this -> QueryPosts -> have_posts())
	{
		$content .= '<div>Найдено записей: '.$this -> QueryPosts -> found_posts.'</div>';
		$content .= '<ul class="post-autocomplete-posts">';
		foreach($Posts as $Post)
		{
			$content .= '<li>';
			$content .= '<a href="'.get_permalink($Post -> ID).'">';
			$content .= esc_attr($Post -> post_title);
			$content .= '</a>';
			$content .= '</li>';
		}
		$content .= '</ul>';
	}
	else
	{
		$content .= '<div class="post-autocomplete-nofound">';
		$content .= 'Ничего не найдено';
		$content .= '</div>';

		return $content;
	}
	wp_reset_postdata();


	return $content;
}

Разберем код подробнее:

$page = max(1, get_query_var('paged'));
$text_search = filter_input(INPUT_GET, 'text', FILTER_SANITIZE_STRING);
$offset = $this -> posts_per_page * ($page - 1);

1 строка. Если страница пагинации первая, то WP отдает - 0, а для второй страницы - 2, для третьей - 3, и так далее. Чтобы решить данную проблему, можно использовать оператор if или ф-ю max, которая вернет большее из чисел переданное ей как параметр.
2. Просто переприсваеваем данные из GET.
3. Рассчитываем смещение для выборки при пагинации.

Просто запрос к БД через core объект WP_Query:

$this -> QueryPosts = new WP_Query();
$Posts = $this -> QueryPosts -> query([
	'posts_per_page' => $this -> posts_per_page,
	'offset' => $offset,
	's' => $text_search,
	'orderby' => 'title',
	'order' => 'ASC',
]);

и сортируем данные по названию с А по Я.

Вообще, я предпочитаю использовать обертку над WP_Query - get_posts. Синтаксис короче, и количество аргументов ф-и такое же как и у метода query. Но в данном случае пришлось отойти от данной традиции, т.к. нам нужна информация о количестве найденных постов (для чего? для пагинации).
Чуть ниже по листингу (см. выше, листинг шорткода). У нас идет проверка - найдены ли какие-то данные, если нет - выводим сообщение. А если есть - формируем список названий постов.

Шорткод отображающий пагинацию

Для того чтобы отобразить пагинацию, разместите в конце статьи или страницы шорткод “[post-autocomplete-pagination]”. Код шорткода реализовать в методе “shortcode_post_autocomplete_pagination()”, и имеет следующее содержимое:

//Sets
$content = '';

if(!empty($this -> QueryPosts))
{
	$big = 999999999;
	$result = paginate_links([
		'base' => str_replace($big, '%#%', get_pagenum_link($big)),
		'format' => '',
		'current' => max(1, get_query_var('paged')),
		'total' => ceil($this -> QueryPosts -> found_posts / $this -> posts_per_page)
	]);

	$content .= str_replace('/page/1/', '', $result);
}

return $content;

как видно выше, мы используем проверку в if, и если она не пустая - переходим к формированию пагинации средствами стандартной ф-и WordPress - paginate_links().

Функция имеет ряд параметров которые мы предопределили, иначе будут использованы данные из глобального объекта $wp_query. А нам это не нужно, т.к. мы использовали свой запрос к БД.

Проверяем работу плагина вывода постов через автокомплит

Через админку ВП, создаем страницу и вставляем в него следующий код:

[post-autocomplete-form']

Давно выяснено, что при оценке дизайна и композиции читаемый текст мешает сосредоточиться. Lorem Ipsum используют потому, что тот обеспечивает более или менее стандартное заполнение шаблона, а также реальное распределение букв и пробелов в абзацах, которое не получается при простой дубликации "Здесь ваш текст..

[post-autocomplete-posts]

[post-autocomplete-pagination]

сохраняем, и переходим к просмотру результата. Вводим искомый текст, наблюдаем автокомплит. И если что-то в БД есть, кликам по одному из результатов. Страница перезагружается, и мы видим что найден один пост. Тестируем дальше. Вводим скажем букву “а” или “о”, или любую другую какую вспомнили. Нажимаем enter, перезагрузка, и в нашем списке теперь должно быть больше статей. И если их больше 10, то должна появиться пагинация. И если даже пагинация работает, и на последней ссылке пагинации есть данные и пагинация не пропала - том мы справились с нашей миссией и написали небольшой плагин с тремя шорткодами.

На этом все. Полный код плагина можно найти в репозитории по этой ссылке. Спасибо за внимание, до скорых встреч!

Список всех уроков темы

Поделиться в соцсетях:
Статьи на похожую тематику

С вашим WordPress сайтом проблемы? нужен дополнительный функционал? нестандартный плагин или сверстать новую страницу?
Тогда напишите мне через форму обратной связи, и я постараюсь вам помочь.

Комментарии
  1. Клок

    Постраничная навигация на странице результатов поиска не работает

    ответить
    1. Pavel
      14.10.2020 в 06:42 автор блога

      Проверю

      ответить
Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *