Я добавил пользовательский (дополнительный) запрос к файлу шаблона (шаблона пользовательской страницы). Как заставить WordPress использовать мой пользовательский запрос для разбивки на страницы вместо использования нумерации в основном цикле?
Добавлено
Я изменил запрос основного цикла через query_posts()
. Почему не работает разбиение на страницы, и как мне это исправить?
Проблема
По умолчанию в любом данном контексте WordPress использует основной запрос для определения нумерации страниц. Основной объект запроса хранится в глобальном
$wp_query
, который также используется для вывода основного цикла запроса:Когда вы используете пользовательский запрос, вы создаете совершенно отдельный объект запроса:
И этот запрос выводится через совершенно отдельный цикл:
Но теги шаблона нумерации страниц, в том числе
previous_posts_link()
,next_posts_link()
,posts_nav_link()
, иpaginate_links()
, базируются на основном объекте запроса main query object,$wp_query
. Этот основной запрос может быть или не быть разбит на страницы. Например, если текущий контекст представляет собой пользовательский шаблон страницы, основной объект $wp_query будет состоять только из одного сообщения — идентификатора страницы, которой назначен пользовательскому шаблону страницы.Если текущий контекст является каким-либо архивным индексом, основной
$wp_query
может состоять из достаточного количества сообщений, чтобы вызвать разбиение на страницы, что приводит к следующей части проблемы: для основного$wp_query Объект
, WordPress передает в запрос параметрpaged
, основанный на переменной запроса URLpaged
. Когда запрос извлекается, этот параметрpaged
будет использоваться для определения того, какой набор постраничных постов должен возвращаться. Если щелкнуть на отображаемую ссылку нумерации страниц и загрузить следующую страницу, ваш пользовательский запрос не сможет узнать, что нумерация страниц изменилась .Решение
Передача правильного постраничного параметра в пользовательский запрос
Предполагая, что пользовательский запрос использует массив args:
Вам нужно будет передать в массив правильный параметр
paged
. Это можно сделать, выбрав переменную запроса URL-адреса, используемую для определения текущей страницы, с помощьюget_query_var()
:Затем вы можете добавить этот параметр в ваш массив args запроса:
Примечание. Если ваша страница является статической главной страницей , обязательно используйте
page
вместоpaged
в качестве статической главной страницы.Теперь при получении пользовательского запроса будет возвращен правильный набор постраничных постов.
Использование пользовательского объекта запроса для функций разбиения на страницы
Чтобы функции разбиения на страницы могли выдавать правильный вывод, т. е. ссылки на предыдущую / следующую страницу, относящиеся к пользовательскому запросу, WordPress необходимо принудительно распознать пользовательский запрос. Это требует некоторого «взлома»: замена основного объекта
$ wp_query
на пользовательский объект запроса,$custom_query
:«Взлом» основного объекта запроса:
$temp_query = $wp_query
$wp_query = NULL;
Изменение пользовательского запроса на основной объект запроса:
$wp_query = $custom_query;
Этот хак должен быть выполнен перед вызовом любых функций нумерации страниц
Сбросить основной объект запроса
После того, как функции пагинации были выведены, сбросьте основной объект запроса:
Исправления функции пагинации
Функция
previous_posts_link ()
будет работать нормально, независимо от нумерации страниц. Она просто определяет текущую страницу, а затем выводит ссылку дляpage - 1
. Однако для корректного выводаnext_posts_link ()
требуется исправление. Это происходит потому, чтоnext_posts_link ()
используетmax_num_pages
параметр:Как и в случае с другими параметрами запроса, по умолчанию функция будет использовать
max_num_pages
для основного объекта$wp_query
. Чтобы заставитьnext_posts_link()
отвечать заОбъект $custom_query
, вам нужно будет передать функциюmax_num_pages
в функцию. Вы можете получить это значение из объекта$custom_query
:$custom_query- & gt; max_num_pages
: p>Все вместе
Ниже приведена базовая конструкция пользовательского цикла запроса с правильно функционирующими функциями нумерации страниц:
Приложение: Как насчет
query_posts()
?query_posts()
для дочерних цикловЕсли вы используете
query_posts()
для вывода пользовательского цикла, а не создание отдельного объекта для пользовательского запроса с помощьюWP_Query()
, тогда вы_doing_it_wrong()
столкнетесь с несколькими проблемами (не наименьшими из которых будут проблемы нумерации страниц). Первым шагом к решению этих проблем будет устранение неправильного использованияquery_posts()
на правильныйWP_Query()
. р>Использование
query_posts ()
для изменения основного циклаЕсли вы просто хотите изменить параметры для запроса основного цикла — например, изменить посты на странице или исключить категорию — у вас может возникнуть желание использовать
query_posts()
. Но все равно не нужно. Когда вы используетеquery_posts()
, вы заставляете WordPress заменить основной объект запроса. (На самом деле WordPress делает второй запрос и перезаписывает$wp_query
.) Однако проблема в том, что он выполняет эту замену слишком поздно, чтобы обновить нумерацию страниц.Решение состоит в том, чтобы отфильтровать основной запрос перед извлечением сообщений em>, с помощью ловушки
pre_get_posts
.Вместо добавления этого в файл шаблона категории (
category.php
):Добавьте следующий код в
functions.php
:Вместо файла (
home.php
):В
functions.php
:Таким образом, WordPress будет использовать уже измененный объект
$ wp_query
при определении нумерации страниц без необходимости изменения шаблона.Я использую этот код для пользовательского цикла с нумерацией страниц:
Еще один хороший учебник с вариантом этого ответа: callmenick.com/post/custom-wordpress-loop-with-pagination
Рассмотрим ситуацию, когда вы используете глобальный шаблон страницы, прикрепленный к странице для некоторого «вводного текста», и за ним следует подзапрос, который вы хотите поместить на страницу.
Используя paginate_links (), как вы упомянули выше, с большей частью значений по умолчанию (и при условии, что у вас включены ЧПУ), ваши ссылки на страницы будут по умолчанию будут иметь значение
mysite.ca/page-slug/page/#
Но будет ошибка404
, так как WordPress не знает об этой конкретной структуре URL и на самом деле будет искать дочернюю страницу «page», которая является дочерней для «page-slug».Хитрость заключается в том, чтобы вставить правило перезаписи, которое применяется только к тому конкретному слагу страницы «страница псевдоархива», который принимает структуру
/page/#/
и переписывает его в строку запроса, которую может понять WordPress, а именно:mysite.ca/?pagename=page-slug&paged=#
. Обратите внимание:pagename
иpaged
неname
иpage
.Вот правило перенаправления:
Как всегда, при изменении правил перезаписи не забудьте очистить ваши постоянные ссылки , зайдя в Настройки>Постоянные ссылки в административной части.
Если у вас есть несколько страниц, которые будут вести себя таким образом (например, при работе с несколькими пользовательскими типами записей), вы можете не создавать новое правило перезаписи для каждого блока страниц. Мы можем написать более общее регулярное выражение, которое будет работать для любого идентифицированного фрагмента страницы.
Например:
Недостатки / Предостережения
Одним из недостатков этого подхода является жесткое кодирование Page. Если администратор когда-либо изменит слаг этой страницы псевдоархива, правило перезаписи больше не будет совпадать, и вы получите ошибку 404.
Я не уверен, что могу придумать обходной путь для этого метода, но было бы неплохо, если бы это был глобальный шаблон страницы, который каким-то образом вызывал правило перезаписи.