Czy można poprawnie paginować posty, które są losowo sortowane?

30

Znalazłem ten problem na pomocy Wordpress i temat niestety jest teraz zamknięty. Mam ten sam problem ... (czytaj poniżej)


Stworzyliśmy witrynę, na której członkowie mogą polecać takie rzeczy, jak ulubione książki, filmy, piosenki itp. W tym celu wykorzystam stronę Filmy jako przykład.

Strona „Filmy” jest ostatecznie niestandardowym szablonem strony, który prosi wordpress, aby wyświetlał losową listę WSZYSTKICH postów, które otrzymały kategorię „filmy” (kategoria 31). Wyświetla tytuł tych filmów w losowej kolejności, korzystając z poniższego kodu.

<?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; ?>

Problem w tym, że lista jest dość długa i chciałbym podzielić ją na dwie lub więcej stron po około 10 filmów. Aby to osiągnąć, wykorzystałem poniższy kod.

<?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; ?>

Ale jest problem, ponieważ chociaż dzieli dane na strony po 10 postów (paginuje), nie zawiera nowego zestawu 10 postów na stronie 2 i tak dalej. Innymi słowy, ponieważ wyświetla listę rzeczy w losowej kolejności, po prostu wychodzi i otrzymuje kolejne 10 losowych postów (lub w tym przypadku tytuły filmowe). W rezultacie mamy kilka powtarzających się postów z tytułami filmów zamiast nowego zestawu 10 losowych tytułów filmów na stronie 2 itp.

Moje pytanie brzmi - co mogę dodać do tego kodu, aby Wordpress „zapamiętał”, które losowe 10 postów zawierał na stronie 1, a następnie poprosił o nowy zestaw 10 postów do umieszczenia na stronach 2, 3 itd. Do wszystkie posty są wyświetlane. Chciałbym, aby było tylko jedno wystąpienie posta na stronę, gdy jest losowo sortowane w zestawach po 10.

użytkownik9604
źródło

Odpowiedzi:

38

Możesz użyć filtru, aby zmodyfikować instrukcję ORDER BY w WP_query.

W ten sposób możesz ręcznie ustawić zapytanie tak, aby używało ORDER BY RAND ($ seed);

Mysql RAND () akceptuje ziarno jako opcjonalny argument. Za pomocą nasiona zwróci za każdym razem ten sam losowy zestaw wyników.

Możesz więc wygenerować losową liczbę przy ładowaniu pierwszej strony, a następnie zapisać ją w zmiennej SESSION i użyć jej jako zarodka $ dla dalszych stronicowanych żądań.

Jeśli próbujesz na przykład osiągnąć to w głównej pętli, możesz dodać następujące pliki do pliku 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;
}
Nick Ryall
źródło
idealne rozwiązanie. dziękuję bardzo
Faisal Ramzan
4

Od ostatnich wersji WordPressa możesz teraz dodać ziarno do wartości orderbyparametru WP_Query:

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

$seedjest liczbą losową. Powinieneś zapisać go jako zmienną sesji PHP. Nie zapomnij włączyć sesji PHP w WordPress, dzwoniąc session_start()do Ciebie functions.php:

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

Dzięki tej składni nie musisz używać posts_orderbyfiltra. Co więcej, nie musisz się upewnić, że filtr jest stosowany tylko do docelowego WP_Query.

Aby uzyskać więcej informacji, przeczytaj ten bilet na WordPress Core.

Guicara
źródło
odpowiedź może być technicznie poprawna, ale jest do bani. edytuj i wyjaśnij, dlaczego tak jest, zamiast wysyłać ludzi do RTFM
Mark Kaplun,
Zredagowałem swoją odpowiedź, aby wyjaśnić, dlaczego może to być lepszy wybór niż stosowanie filtra w tym konkretnym przypadku.
Guicara,
późny +1, ale zamiast sesji powinny być używane pliki cookie. w zasadzie nigdy nie należy używać sesji, ponieważ są zbyt problematyczne na wiele sposobów.
Mark Kaplun
bardzo pomógł .. dzięki
Faisal Ramzan