Можно ли правильно разбить посты на страницы, отсортированные случайным образом?

30

Я нашел эту проблему в Wordpress Support, и тема, к сожалению, сейчас закрыта. У меня такая же проблема ... (читай ниже)


Мы создали сайт, на котором участники могут рекомендовать такие вещи, как любимые книги, фильмы, песни и т. Д. Для этой проблемы я буду использовать страницу «Фильмы» в качестве примера.

Страница «Фильмы» - это, в конечном счете, пользовательский шаблон страницы, который просит wordpress отобразить случайный список ВСЕХ сообщений, которым была присвоена категория «фильмы» (категория 31). Он отображает название этих фильмов в случайном порядке, используя код ниже.

<?php 
$rand = new WP_Query("cat=31&showposts=-1&orderby=rand"); 
while($rand->have_posts()) : $rand->the_post();
?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?>
<?php endwhile; ?>

Проблема в том, что список становится довольно длинным, и я хотел бы разделить его на две или более страниц по 10 фильмов в каждой. Чтобы добиться этого, я использовал код ниже.

<?php 
$page = (get_query_var('paged')) ? get_query_var('paged') : 1; 
query_posts("cat=31&orderby=rand&showposts=10&paged=$page"); 
while ( have_posts() ) : the_post() 
?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?>
<?php endwhile; ?>

Но есть проблема, потому что, хотя он разбивает данные на страницы по 10 постов каждая (разбивает на страницы), он не включает новый набор из 10 постов на странице 2 и т. Д. Другими словами, поскольку он перечисляет вещи в случайном порядке, он просто выходит и получает еще 10 случайных постов (или в данном случае названия фильмов). В результате мы имеем несколько повторяющихся постов с заголовками фильмов вместо нового набора из 10 случайных заголовков фильмов на странице 2 и т. Д.

У меня вопрос: что я могу добавить к этому коду, чтобы WordPress «запомнил», какие случайные 10 постов были включены на страницу 1, а затем получил новый набор из 10 постов для размещения на страницах 2, 3 и т. Д. До все сообщения отображаются. Я бы хотел, чтобы на каждой странице было только одно вхождение поста при случайной сортировке по 10 штук.

user9604
источник

Ответы:

38

Вы можете использовать фильтр для изменения оператора ORDER BY в WP_query.

Таким образом, вы можете вручную настроить запрос на использование ORDER BY RAND ($ seed);

Mysql RAND () принимает начальное значение в качестве необязательного аргумента. Используя начальное значение, оно будет возвращать один и тот же случайный набор результатов каждый раз.

Таким образом, вы можете сгенерировать случайное число при загрузке первой страницы, затем сохранить его в переменной SESSION и использовать его в качестве $ seed для дальнейших разбивок на страницы

Например, если вы пытаетесь добиться этого в своем основном цикле, вы можете добавить следующее в свой файл functions.php.

session_start();

add_filter('posts_orderby', 'edit_posts_orderby');

function edit_posts_orderby($orderby_statement) {

    $seed = $_SESSION['seed'];
    if (empty($seed)) {
      $seed = rand();
      $_SESSION['seed'] = $seed;
    }

    $orderby_statement = 'RAND('.$seed.')';
    return $orderby_statement;
}
Ник Рилль
источник
идеальное решение. Большое спасибо
Фейсал Рамзан
4

Начиная с последних версий WordPress, теперь вы можете добавить начальное значение к значению orderby параметра WP_Query:

$query = new WP_Query([
    'orderby' => 'RAND($seed)',
    ...
]);

$seedэто случайное число Вы должны сохранить его как переменную сеанса PHP. Не забудьте включить сеанс PHP в WordPress, вызвавsession_start() вам functions.php:

if (!session_id()) {
    session_start();
}

С этим синтаксисом вам не нужно использовать posts_orderbyфильтр. Более того, вам не нужно убедиться, что фильтр применяется только к целевому WP_Query.

Для получения дополнительной информации, пожалуйста, прочитайте эту заявку на WordPress Core.

Guicara
источник
ответ может быть технически правильным, но это отстой. пожалуйста, отредактируйте и объясните причину этого вместо того, чтобы отправлять людей в RTFM
Марк Каплун
Я отредактировал свой ответ, чтобы объяснить, почему он может быть лучшим выбором вместо использования фильтра в данном конкретном случае.
Гикара
позднее +1, но вместо сессий следует использовать куки. в основном сеансы никогда не должны использоваться, поскольку они слишком проблематичны во всех отношениях.
Марк Каплун
очень помог .. спасибо
Фейсал Рамзан