wp_query publicación aleatoria
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>

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.

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

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

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?

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

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...

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

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 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.

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!

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

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.

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

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.

@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

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>';
}
