É possível paginar corretamente as postagens ordenadas aleatoriamente?

30

Encontrei esse problema no suporte ao Wordpress e o tópico agora está encerrado. Eu tenho esse mesmo problema ... (leia abaixo)


Criamos um site em que os membros podem recomendar coisas como livros favoritos, filmes, músicas etc. Para esse problema, usarei a página Filmes como exemplo.

A página "Filmes" é basicamente um modelo de página personalizado que solicita ao wordpress para exibir uma lista aleatória de TODAS as postagens que receberam a categoria "filmes" (categoria 31). Ele exibe o título desses filmes em ordem aleatória, usando o código abaixo.

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

O problema é que a lista está ficando bastante longa e eu gostaria de dividi-la em duas ou mais páginas de cerca de 10 filmes cada. Para conseguir isso, usei o código abaixo.

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

Mas há um problema porque, embora divida os dados em páginas de 10 postagens cada (paginadas), ele falha ao incluir um novo conjunto de 10 postagens na página 2 e assim por diante. Em outras palavras, por listar as coisas em uma ordem aleatória, ela sai e recebe outras 10 postagens aleatórias (ou, neste caso, títulos de filmes). Como resultado, temos algumas postagens repetidas para títulos de filmes, em vez de um novo conjunto de 10 títulos aleatórios de filmes na página 2, etc.

Minha pergunta é - o que posso adicionar a esse código para que o wordpress "lembre" quais 10 posts aleatórios incluíam na página 1 e, em seguida, obtenha um novo conjunto de 10 posts para colocar nas páginas 2, 3 etc. até todas as postagens são exibidas. Gostaria que houvesse apenas uma ocorrência de uma postagem por página, quando classificadas aleatoriamente em conjuntos de 10.

user9604
fonte

Respostas:

38

Você pode usar um filtro para modificar a instrução ORDER BY do WP_query.

Dessa forma, você pode definir manualmente a consulta para usar ORDER BY RAND ($ seed);

O Mysql RAND () aceita uma semente como argumento opcional. Usando uma semente, ele retornará o mesmo resultado aleatório definido a cada vez.

Portanto, você pode gerar um número aleatório no carregamento da primeira página e armazená-lo em uma variável SESSION e usá-lo como a semente $ para solicitações paginadas adicionais.

Se você está tentando obter isso no loop principal, por exemplo, pode adicionar o seguinte ao seu arquivo 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
fonte
solução perfeita. muito obrigado
Faisal Ramzan 11/11
4

Desde as últimas versões do WordPress, agora você pode adicionar uma semente ao valor do orderbyparâmetro de WP_Query:

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

$seedé um número aleatório. Você deve armazená-lo como uma variável de sessão PHP. Não se esqueça de ativar a sessão PHP no WordPress chamando session_start()você functions.php:

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

Com essa sintaxe, você não precisa usar o posts_orderbyfiltro. Além disso, você não precisa garantir que o filtro seja aplicado apenas ao WP_Query de destino.

Para mais informações, leia este ticket no WordPress Core.

Guicara
fonte
a resposta pode estar tecnicamente correta, mas é péssima. Edite e explicar o porquê dele em vez de enviar pessoas para RTFM
Mark Kaplun
Eu editei minha resposta para explicar por que poderia ser uma escolha melhor em vez de usar um filtro nesse caso específico.
Guicara 21/07
um +1 atrasado, mas os cookies devem ser usados ​​em vez de sessões. basicamente, as sessões nunca devem ser usadas, pois são muito problemáticas de todos os tipos.
27668 Mark Kaplun
ajudou muito .. obrigado
Faisal Ramzan 11/11