wp_query publicación aleatoria

23 ago 2017, 15:16:44
Vistas: 25.6K
Votos: 1

Quiero mostrar todas las publicaciones como misitio.com/nombrepublicacion/1/, misitio.com/nombrepublicacion/2/ ...... misitio.com/nombrepublicacion/7/ ..

El código de abajo funciona perfectamente para mí, el único problema es que solo muestra las primeras publicaciones misitio.com/nombrepublicacion/...

¿Cómo puedo hacer esto?

<?php
/**
 * Nombre de la Plantilla: Publicación Aleatoria
 * Esta plantilla solo mostrará el contenido que ingresaste en el editor de páginas
 */
?>

<html>
<head>

</head>
<body>

<?php
/*
Selector de Publicación Aleatoria
Usar en página para enviar al visitante a una publicación aleatoria opcionalmente modificar consulta
*/

// establecer argumentos para WP_Query en publicaciones publicadas para obtener 1 aleatoria
$args = array(
    'post_type' => 'post',
    'post_status' => 'publish',
    'orderby' => 'rand',
    'order' => 'DESC',

    // Usando date_query para filtrar publicaciones de la última semana
    'date_query' => array(
        array(
            'after' => '2 week ago'
        )
    )
); 

// ¡Es hora! Vamos a algún lugar aleatorio
$my_random_post = new WP_Query ( $args );

while ( $my_random_post->have_posts () ) {
  $my_random_post->the_post ();

  // redirigir a la publicación aleatoria
  wp_redirect ( get_permalink () );
  exit;
}
?>

</body>
</html>
3
Comentarios

Ten en cuenta que ordenar por rand es extremadamente lento y costoso, y esa página no se puede almacenar en caché. Cualquier hacker medianamente competente ahora puede lanzar un ataque de denegación de servicio barato haciendo ping a esa URL repetidamente, para derribar tu servidor de base de datos por agotamiento de recursos

Tom J Nowell Tom J Nowell
23 ago 2017 16:01:21

creo que el hacker tendrá cosas mejores que hacer, ya que atacar mi servidor.it es solo un sitio web local y no un sitio web importante. sobre lo "lento", no habrá más de 50-100 usuarios en línea al mismo tiempo. aún así, podemos cambiar de "rand" a otra cosa. primero tengo que hacer que funcione como quiero.

adi kica adi kica
23 ago 2017 16:23:49

Solo tenía en mente 4 o 5 usuarios concurrentes cuando escribí mi comentario, pero es un problema que se puede evitar por completo, mi respuesta a continuación escalará a miles de millones de usuarios concurrentes mientras ofrece tiempos de carga de página significativamente más rápidos

Tom J Nowell Tom J Nowell
23 ago 2017 16:36:37
Todas las respuestas a la pregunta 3
10

Hacer esto en PHP es una pésima idea:

  • Esta página es imposible de cachear
  • Ordenar aleatoriamente es extremadamente costoso para la consulta, ya que implica crear tablas temporales en la base de datos y escaneos, pues debe copiar toda la tabla de publicaciones, luego reordenarlas aleatoriamente, y finalmente realizar la consulta real en la nueva tabla antes de destruirla
  • Esto te expone a ataques de agotamiento de recursos

Por ejemplo, este comando hará ping repetidamente a tu URL de publicación aleatoria. Ejecutado suficientes veces en suficientes computadoras, puede derribar tu base de datos:

for i in `seq 1 20000`; do curl http://miweb.com/nombredepost; done

Si estás en un hosting compartido económico, puede ser suficiente con abrir tu URL en varias pestañas del navegador al mismo tiempo para provocar problemas.

Sin mencionar que tu redirección envía encabezados HTTP, pero el código imprime etiquetas antes, por lo que los encabezados ya se enviaron, rompiendo cosas y generando advertencias en PHP.

La Alternativa Súper Rápida y Fácil

En su lugar, haz una consulta normal ordenada por fecha y muestra los datos como JSON. Luego, con JavaScript en el navegador, elige aleatoriamente una de esas publicaciones y haz una redirección del lado del cliente.

De esta manera la página puede cachearse, tu base de datos está protegida y el navegador hace todo el trabajo pesado. La consulta a la base de datos será muy rápida en comparación.

Ahora tu problema se reduce a mostrar un poco de datos en una lista, elegir algo aleatoriamente de esa lista con JS, y luego usar window.location= ... para redirigir. No se necesita conocimiento de WordPress.

23 ago 2017 16:11:09
Comentarios

+1 por la alternativa del lado del cliente. Pero una pregunta aquí, establecer random en WP_Query seleccionará una publicación aleatoria entre digamos, 15,000 publicaciones. Pero ¿es eficiente enviar una respuesta JSON que contenga al menos 15K cadenas al navegador?

Johansson Johansson
25 ago 2017 17:11:30

No, enviar 15k publicaciones no es eficiente, ni tampoco consultar 15k publicaciones. Cualquier cosa que involucre aleatoriedad y bases de datos va a ser excesivamente costoso. En su lugar, proporciona una opción más inteligente, por ejemplo, las 20 publicaciones más recientes o las 20 publicaciones con más comentarios. Hay tantas alternativas a la aleatoriedad al listar publicaciones, y rara vez la aleatoriedad significa lo que la gente piensa. Si el sitio devolviera la misma publicación 10 veces, sería una salida válida de una selección verdaderamente aleatoria, al igual que 5 publicaciones seguidas, pero la gente realmente quiere 10 publicaciones distribuidas uniformemente en el rango

Tom J Nowell Tom J Nowell
25 ago 2017 19:56:04

Entonces, ¿qué sugieres para un blog que tiene miles de publicaciones? ¿Es una buena idea establecer un desplazamiento aleatorio y luego consultar 1 publicación?

Johansson Johansson
25 ago 2017 20:54:48

no, mi sugerencia es no intentar seleccionar aleatoriamente entre miles de publicaciones, de la misma manera que retirar £1 millón del banco es igual de costoso sin importar si lo haces con tarjeta, cheque u otros medios. Aleatorio es una mala idea, verdaderamente aleatorio es aún peor, tienes que comprometerte y dar la apariencia de aleatoriedad, o limitar tu alcance. Hay un gran número de alternativas que parecen iguales, obtener un número verdaderamente aleatorio de 15k publicaciones sin conocerlas todas de antemano es fundamentalmente costoso

Tom J Nowell Tom J Nowell
25 ago 2017 21:40:31

Interesante. Pero si el usuario está viendo una versión en caché de la página (caché de página), no importaría, ¿verdad? Obviamente, la publicación aleatoria devuelta seguirá siendo la misma hasta que se borre la caché. A menos, por supuesto, que de alguna manera el 'orderby' => 'rand' active un caché fragmentado...

Christine Cooper Christine Cooper
11 jun 2018 13:59:15

Sí, tendrías que almacenar en caché solo esas partes de la página, a menos que lo hicieras en javascript, de cualquier manera aleatorio es una idea terrible, y nunca significa lo que pretendes de todos modos

Tom J Nowell Tom J Nowell
11 jun 2018 18:34:49

Hola Tom, sé que esta publicación es antigua, pero ¿podrías proporcionar un ejemplo de esto con json? Ni siquiera sé por dónde empezar.

rudtek rudtek
13 mar 2019 21:17:18

@rudtek cualquier endpoint de la API REST devolverá datos en formato JSON, y JSON es lo mismo que objetos y arrays en javascript, por ejemplo [1,2,3,4,5] es JSON, también es un array en javascript. Cómo elegir un elemento aleatorio en un array en JS es una pregunta para stackoverflow, y cómo decodificar una respuesta JSON de una llamada AJAX también es una pregunta para stackoverflow, al igual que cómo incluir un array de elementos en una página HTML para usar en JS. Para todo lo demás, está json_encode, PHP estándar. Honestamente hay muy poco de WordPress involucrado, si es que hay algo.

Tom J Nowell Tom J Nowell
13 mar 2019 22:17:30

También existe la vía intermedia en PHP: shuffle($my_random_post->posts) - si se usa directamente antes del bucle - también creará un orden "aleatorio" - ¡pero ten en cuenta que ordenar un gran número de posts ALEATORIAMENTE siempre será muy costoso y puede manejarse mejor en el navegador como sugiere @TomJNowell!

jave.web jave.web
11 ago 2019 08:24:40

Mezclarlo en PHP también funciona, el costo está en hacer que la base de datos maneje la aleatoriedad. Si puedes mover eso a otro lugar, ya sea PHP, el navegador o pre-calcularlo, entonces obtendrás mejoras significativas

Tom J Nowell Tom J Nowell
12 ago 2019 16:36:25
Mostrar los 5 comentarios restantes
6

Solo se muestra 1 publicación en tu sitio porque estás usando exit() en tu bucle. En tu código, cuando WP_Query comienza y el bucle termina después de un contador. Elimina exit() y usa este código:

<?php
/*
 * Selector aleatorio de publicaciones
 * Usar en página para enviar al visitante a una publicación aleatoria, opcionalmente modificar la consulta
 */

// establecer argumentos para WP_Query en publicaciones publicadas para obtener 1 al azar
$args = array(
    'post_type' => 'post',
    'post_status' => 'publish',
    'orderby' => 'rand',
    'order' => 'DESC',

    // Usando date_query para filtrar publicaciones de la última semana
    'date_query' => array(
        array(
            'after' => '2 week ago'
        )
    )
);

// ¡Es hora! Ir a un lugar aleatorio
$my_random_post = new WP_Query ( $args );
if($my_random_post->have_posts()){
    while ( $my_random_post->have_posts () ) {
        $my_random_post->the_post ();
        echo '<a href="'.get_the_permalink().'">'.get_the_title().'</a>';
    }
}
?>
23 ago 2017 15:50:20
Comentarios

Quiero que solo se muestre una publicación y que redirija a la publicación completa. La plantilla usa "miweb.com/random/,,,, cuando el visitante usa miweb.com/random/ quiero que el usuario sea redirigido a la publicación completa, pero de forma aleatoria a todas las publicaciones, como he explicado "miweb.com/nombredepost/15/..... y así sucesivamente, la publicación es como una galería, con "siguiente publicación". Quiero que el visitante sea redirigido aleatoriamente a algún número de publicación, no solo a la publicación.

adi kica adi kica
23 ago 2017 16:08:28

Quieres redirigir al usuario a otra página.

Jitender Singh Jitender Singh
23 ago 2017 16:38:08

Usando mi página random redirijo usuarios a publicaciones aleatorias. Mismo dominio. mipagina.com/random/ a mipagina.com/alguna-publicacion/ .... mipagina.com/otra-publicacion/.... hasta este punto todo bien, quiero más.... > mipagina.com/alguna-publicacion/2/..mipagina.com/alguna-publicacion/3

adi kica adi kica
23 ago 2017 16:45:56

Lo siento, no te entendí. Dime primero si este enlace permanente del código no funciona o si quieres cambiar el enlace permanente de las publicaciones. Por favor, aclara tu tarea.

Jitender Singh Jitender Singh
23 ago 2017 17:05:07

@adikica si estás haciendo una redirección en PHP => debes hacerlo ANTES de que se genere cualquier HTML... no en medio de la plantilla. Puedes usar una redirección con JavaScript del lado del cliente o usar la acción template_redirect

jave.web jave.web
11 ago 2019 08:20:15

@adikica También, si estás llamando a exit() después del primer post, no hay bucle - así que simplemente usa una declaración if

jave.web jave.web
11 ago 2019 08:21:00
Mostrar los 1 comentarios restantes
0

No necesitas redirigir al usuario a la página de publicaciones aleatorias, y ni siquiera podrías si quisieras, porque no se puede redirigir a múltiples lugares al mismo tiempo.

Así que, simplemente muestra tus publicaciones aleatorias dentro de tu bucle:

while ( $my_random_post->have_posts () ) {
  $my_random_post->the_post ();
  echo '<a href="'.get_the_permalink().'">'.get_the_title().'</a>';
}
23 ago 2017 15:36:03