¿Es posible paginar las publicaciones correctamente ordenadas al azar?

30

Encontré este problema en el soporte de Wordpress y, lamentablemente, el tema ahora está cerrado. Tengo este mismo problema ... (lea a continuación)


Hemos creado un sitio donde los miembros pueden recomendar cosas como libros favoritos, películas, canciones, etc. Para este problema, usaré la página Películas como ejemplo.

La página "Películas" es, en última instancia, una plantilla de página personalizada que le pide a WordPress que muestre una lista aleatoria de TODAS las publicaciones que han recibido la categoría "películas" (categoría 31). Muestra el título de estas películas en orden aleatorio usando el siguiente código.

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

El problema es que la lista se está haciendo bastante larga y me gustaría dividirla en dos o más páginas de aproximadamente 10 películas cada una. Para lograr esto, he usado el siguiente código.

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

Pero hay un problema porque, aunque divide los datos en páginas de 10 publicaciones cada una (páginas), no incluye un nuevo conjunto de 10 publicaciones en la página 2 y así sucesivamente. En otras palabras, debido a que enumera las cosas en un orden aleatorio, simplemente se apaga y obtiene otras 10 publicaciones aleatorias (o en este caso títulos de películas). Como resultado, tenemos algunas publicaciones repetidas de títulos de películas en lugar de un nuevo conjunto de 10 títulos de películas al azar en la página 2, etc.

Mi pregunta es: ¿qué puedo agregar a este código para que WordPress "recuerde" qué 10 publicaciones aleatorias incluyó en la página 1, y luego obtener un nuevo conjunto de 10 publicaciones para poner en las páginas 2, 3, etc. hasta Se muestran todas las publicaciones. Me gustaría que solo haya una aparición de una publicación por página cuando se ordena al azar en conjuntos de 10.

usuario9604
fuente

Respuestas:

38

Puede usar un filtro para modificar la instrucción ORDER BY de WP_query.

De esa manera, puede configurar manualmente la consulta para usar ORDER BY RAND ($ seed);

Mysql RAND () acepta una semilla como argumento opcional. Usando una semilla, devolverá el mismo conjunto de resultados aleatorios cada vez.

Por lo tanto, puede generar un número aleatorio en la carga de la primera página y luego almacenarlo en una variable SESSION y usarlo como $ seed para solicitudes paginadas adicionales.

Si está tratando de lograr esto en su bucle principal, por ejemplo, puede agregar lo siguiente a su archivo 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
fuente
Solución perfecta. muchas gracias
Faisal Ramzan
4

Desde las últimas versiones de WordPress, ahora puede agregar una semilla al valor del orderbyparámetro de WP_Query:

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

$seedEs un número aleatorio. Debe almacenarlo como una variable de sesión PHP. No se olvidó de permitir sesión de PHP en WordPress llamando session_start()en la que functions.php:

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

Con esta sintaxis no necesita usar el posts_orderbyfiltro. Además, no tiene que asegurarse de que el filtro solo se aplique a la WP_Query de destino.

Para obtener más información, lea este ticket en WordPress Core.

Guicara
fuente
la respuesta puede ser técnicamente correcta, pero apesta. edite y explique por qué en lugar de enviar personas a RTFM
Mark Kaplun
He editado mi respuesta para explicar por qué podría ser una mejor opción en lugar de usar un filtro en este caso particular.
Guicara
un +1 tardío, pero se deben usar cookies en lugar de sesiones. Básicamente, las sesiones nunca deben usarse, ya que son demasiado problemáticas en todo tipo de formas.
Mark Kaplun
ayudó mucho ... gracias
Faisal Ramzan