Как вывести конкретный пост перед циклом wordpress?
Итак, у меня продолжается цикл WordPress. Приведенный ниже код является страницей шаблона для страницы архива продуктов woocommerce. Вот пример использования того, что я пытаюсь выяснить, как достичь:
- Пользователь отображается на странице архива продукта (перечислены миниатюры продуктов, завернутые в ссылки).
- Пользователь нажимает на миниатюру (которая является ссылкой), и она переводит его на другую страницу, которая в основном совпадает с текущей, за исключением того, что отображается ползунок те же продукты, которые появились на предыдущей странице (вы знаете, количество постов на странице, которые появились на странице 1, странице 2 или странице 3, в зависимости от того, на какой пост был нажат).
- Эта страница будет содержать слайдер с увеличенным изображением всех продуктов, а выбранный продукт будет находиться в начале слайдера (мне нужно переместить его в начало цикла продуктов для этой страницы и соответствующим образом изменить порядок других сообщений).
TL;DR: Подводя итог, как можно Я перехожу на другую страницу, на которой есть точно такие же сообщения с точно таким же номером страницы (страница, как в расположении страницы), но с выбранным сообщением в начале цикла страницы, сохраняя при этом порядок сообщений по-прежнему актуальным (как в сообщениях до выбранного сообщения все еще будет перед ним, а те, которые после него, все еще будут после него)?
PS: Я бы предпочел не использовать решение для плагинов или решение на стороне клиента (я хочу, чтобы все это было сделано на сервере в PHP).
Например:
Я на странице 5:
Сообщения выглядят следующим образом: 41, 42, 43, 44, 45, 46, 47, 48, 49, 50.
Допустим, я нажал на 44.
Страница, на которую я попал, имеет те же циклы, но с 44 в начале, а остальные соответственно переставлены.
Цикл будет выглядеть следующим образом: 44, 45, 46, 47, 48, 49, 50, 41, 42, 43.
Затем, если я нажму на следующую страницу. Так как я на странице 5 и нажал на 6, цикл снова будет нормальным: 51, 52, 53...
<?php get_template_part('templates/page', 'header');
/**
* woocommerce_before_main_content hook
*
* @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content)
* @hooked woocommerce_breadcrumb - 20
*/
do_action('woocommerce_before_main_content');
do_action( 'woocommerce_archive_description' );
if ( have_posts() ) {
/**
* woocommerce_before_shop_loop hook
*
* @hooked woocommerce_result_count - 20
* @hooked woocommerce_catalog_ordering - 30
*/
do_action( 'woocommerce_before_shop_loop' );
woocommerce_product_loop_start();
woocommerce_product_subcategories();
while ( have_posts() ) {
the_post();
?>
<li>
<?php get_template_part( 'woocommerce/content', 'product' );
</li>
<?php
}
woocommerce_product_loop_end();
/**
* woocommerce_after_shop_loop hook
*
* @hooked woocommerce_pagination - 10
*/
do_action( 'woocommerce_after_shop_loop' );
} elseif ( ! woocommerce_product_subcategories( array( 'before' => woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) {
wc_get_template( 'loop/no-products-found.php' );
}
/**
* woocommerce_after_main_content hook
*
* @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content)
*/
do_action('woocommerce_after_main_content');
?>
1 answers
В 'the_posts'
крючок фильтра позволяет редактировать записи, которые будут отображаться в цикле.
Он запускается для всех запросов (основного и второстепенных), поэтому вам нужно проверить, что запрос, по которому вы действуете, является правильным.
Это говорит о том, что в вашем случае вы можете:
- отправьте переменную запроса, чтобы индивидуализировать выбранную запись
- используйте фильтр
'the_posts'
, чтобы переместить выбранную запись в начало массива записей
1. Отправить переменную запроса для индивидуализации выбранной должности
Миниатюры сообщений должны быть напечатаны примерно так:
<a href="<?php esc_url( add_query_arg( array('psel' => get_the_ID() ) ) ) ?>">
<?php the_thumbnail() ?>
</a>
add_query_arg()
добавьте переменную запроса к текущему URL-адресу, это означает, что если вы находитесь на странице с URL-адресом example.com/some/path/page/5
, нажав на миниатюру публикации для публикации с идентификатором 44, вы отправитесь по URL-адресу example.com/some/path/page/5?psel=44
.
Как только URL-адрес будет таким же, показанные сообщения будут такими же, но благодаря переменной url psel
вы можете изменить порядок сообщений, чтобы выбранная запись в начале массива записей.
2. Используйте фильтр 'the_posts'
, чтобы переместить выбранную запись в начало массива записей
Как только у вас есть выбранный идентификатор записи в переменной url, поместить связанный объект записи поверх массива записей - это всего лишь вопрос нескольких функций PHP
function get_selected_post_index() {
$selID = filter_input(INPUT_GET, 'psel', FILTER_SANITIZE_NUMBER_INT);
if ($selID) {
global $wp_query;
return array_search($selID, wp_list_pluck($wp_query->posts, 'ID'), true);
}
return false;
}
add_filter('the_posts', function($posts, $wp_query) {
// nothing to do if not main query or there're no posts or no post is selected
if ($wp_query->is_main_query() && ! empty($posts) && ($i = get_selected_post_index())) {
$sel = $posts[$i]; // get selected post object
unset($posts[$i]); // remove it from posts array
array_unshift($posts, $sel); // put selected post to the beginning of the array
}
return $posts;
}, 99, 2);
Предыдущий код гарантирует, что сообщения будут упорядочены так, как вы хотите.
Функцию get_selected_post_index()
также можно использовать в ваших шаблонах, чтобы узнать, есть ли выбранная запись или нет (и изменить ваш шаблон соответственно), потому что он возвращает false
, когда сообщение не выбрано (или если неверный идентификатор отправляется через переменную url psel
).