wp_query post casuale
Voglio mostrare tutti i post come mywebsite.com/postname/1/
, mywebsite.com/postname/2/
...... mywebsite.com/postname/7/
..
Il codice qui sotto funziona perfettamente per me, l'unico problema è che mostra solo i primi post mywebsite.com/postname/
...
Come posso farlo?
<?php
/**
* Nome Template: Post Casuale
* Questo template mostrerà solo il contenuto inserito nell'editor della pagina
*/
?>
<html>
<head>
</head>
<body>
<?php
/*
Selettore Post Casuale
Usa sulla pagina per inviare il visitatore a un post casuale con query opzionale
*/
// imposta gli argomenti per WP_Query sui post pubblicati per ottenerne 1 casuale
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'rand',
'order' => 'DESC',
// Utilizzo di date_query per filtrare i post dell'ultima settimana
'date_query' => array(
array(
'after' => '2 week ago'
)
)
);
// È il momento! Vai in un posto casuale
$my_random_post = new WP_Query ( $args );
while ( $my_random_post->have_posts () ) {
$my_random_post->the_post ();
// reindirizza al post casuale
wp_redirect ( get_permalink () );
exit;
}
?>
</body>
</html>
Fare questo in PHP è una pessima idea:
- Questa pagina è impossibile da memorizzare nella cache
- Ordinare in modo casuale è estremamente costoso per la query, poiché comporta la creazione di tabelle temporanee nel database e scansioni, dato che deve copiare l'intera tabella dei post, poi riordinarli casualmente, e infine eseguire la query effettiva sulla nuova tabella prima di distruggerla
- Questo ti espone ad attacchi di esaurimento delle risorse
Ad esempio, questo comando eseguirà ripetutamente il ping del tuo URL di post casuale. Se eseguito abbastanza volte su abbastanza computer, farà cadere il tuo database:
for i in `seq 1 20000`; do curl http://miosito.com/nomepost; done
Se sei su un hosting condiviso economico, potrebbe essere sufficiente chiamare il tuo URL in diverse schede del browser contemporaneamente per causare problemi.
Per non parlare del fatto che il tuo reindirizzamento invia intestazioni HTTP, ma il codice emette tag in anticipo, quindi le intestazioni sono già state inviate, rompendo tutto e attivando avvisi PHP.
L'Alternativa Super Veloce e Facile
Quindi, invece, esegui una query normale ordinata per data e restituisci i dati come JSON. Poi in JavaScript sul browser, seleziona casualmente uno di quei post e fai un reindirizzamento lato client.
In questo modo la pagina può essere memorizzata nella cache, il tuo database è protetto e il browser fa tutto il lavoro pesante. La query del database sarà molto più veloce in confronto.
Ora il tuo problema si riduce a emettere un po' di dati in una lista, selezionare casualmente qualcosa dalla lista in JS, quindi usare window.location= ...
per reindirizzare. Non è necessaria alcuna conoscenza di WP

+1 per l'alternativa lato client. Ma una domanda: impostare random in WP_Query
selezionerà un post casuale tra, diciamo, 15.000 post. Ma è efficiente inviare una risposta JSON contenente almeno 15K stringhe al browser?

No, inviare 15k post non è efficiente, né lo è interrogare il database per 15k post. Qualsiasi operazione che coinvolga casualità e database sarà eccessivamente costosa. Invece, fornisci una scelta più intelligente, ad esempio i 20 post più recenti o i 20 post con più commenti. Ci sono così tante alternative al casuale quando si elencano i post, e raramente "casuale" significa ciò che le persone pensano. Se il sito restituisse lo stesso post 10 volte, sarebbe un output valido di una selezione veramente casuale, così come 5 post tutti di seguito, ma in realtà le persone intendono 10 post distribuiti uniformemente nell'intervallo

Quindi, cosa suggerisci per un blog che ha migliaia di post? Impostare un offset casuale e poi interrogare 1 post è una buona idea?

no, il mio suggerimento è di non provare a selezionare casualmente tra migliaia di post, nello stesso modo in cui prelevare 1 milione di sterline dalla banca è altrettanto costoso indipendentemente dal fatto che lo si faccia con carta, assegno o altri mezzi. Il casuale è una cattiva idea, il veramente casuale è ancora peggio, devi scendere a compromessi e dare l'aspetto della casualità, o limitare il tuo ambito. Ci sono un'enorme quantità di alternative che sembrano uguali, ottenere un numero veramente casuale da 15k post senza conoscerli tutti in anticipo è fondamentalmente costoso

Interessante. Ma se l'utente sta visualizzando una versione memorizzata nella cache della pagina (page caching), non avrebbe importanza, giusto? Ovviamente, il post restituito in modo casuale rimarrà lo stesso finché la cache non viene svuotata. A meno che, ovviamente, in qualche modo il 'orderby' => 'rand'
non attivi una cache frammentata...

Sì, dovresti memorizzare nella cache solo quelle parti della pagina, a meno che non lo facessi in javascript, in ogni caso il casuale è un'idea terribile, e non significa mai quello che intendi comunque

Ciao Tom, so che questo post è vecchio, ma potresti fornire un esempio con json? Non so nemmeno da dove iniziare.

@rudtek qualsiasi endpoint REST API restituirà dati formattati in JSON, e JSON è lo stesso di oggetti e array in javascript, ad esempio [1,2,3,4,5]
è JSON, è anche un array in javascript. Come scegliere un elemento casuale in un array in JS è una domanda per stackoverflow, e come decodificare una risposta JSON da una chiamata AJAX è anche una domanda per stackoverflow, così come come includere un array di elementi in una pagina HTML per l'uso in JS. Per tutto il resto, c'è json_encode
, PHP standard vanilla. Onestamente c'è pochissimo WordPress coinvolto, se non del tutto

C'è anche una via di mezzo in PHP: shuffle($my_random_post->posts)
- se usato direttamente prima del loop - creerà anche un ordine "casuale" - ma nota che ordinare un gran numero di post CASUALMENTE sarà sempre molto costoso e può essere gestito meglio nel browser come suggerisce @TomJNowell!

Solo 1 articolo viene visualizzato sul tuo sito perché stai utilizzando exit()
nel tuo loop. Nel tuo codice, quando WP_Query inizia e il loop termina dopo un conteggio.
Rimuovi exit()
e usa questo codice:
<?php
/*
* Selettore casuale di articoli
* Utilizza questa pagina per indirizzare i visitatori a un articolo casuale, opzionalmente modificando la query
*/
// imposta gli argomenti per WP_Query sugli articoli pubblicati per ottenerne 1 casuale
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'rand',
'order' => 'DESC',
// Utilizzando date_query per filtrare gli articoli delle ultime settimane
'date_query' => array(
array(
'after' => '2 week ago'
)
)
);
// È il momento! Vai da qualche parte in modo casuale
$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>';
}
}
?>

Voglio che venga visualizzato un solo post e che ci sia il reindirizzamento al post completo. Il template usa "mywebsite.com/random/,,,, quando il visitatore usa mywebsite.com/random/ voglio che l'utente venga reindirizzato al post completo, ma in modo casuale tra tutti i post, come ho spiegato " mywebsite.com/postname/15/..... e così via, il post è come una galleria, con "prossimo post" voglio che il visitatore venga reindirizzato casualmente a qualche numero di post, non solo al post.

usando la mia pagina random reindirizzo gli utenti a post casuali. stesso dominio. mypage.com/random/ a mypage.com/somepost/ .... mypage.com/anotherpost/.... fino a questo punto è tutto ok, voglio di più.... > mypage.com/somepost/2/..mypage.com/somepost/3

Scusa, non ho capito. Dimmi prima se questo permalink del codice non funziona o se vuoi cambiare il permalink dei post. Per favore, chiarisci il tuo compito.

@adikica se stai facendo un reindirizzamento PHP => devi farlo PRIMA che venga emesso qualsiasi HTML... non nel mezzo del template - puoi usare un reindirizzamento javascript lato client, oppure usare l'azione template_redirect

Non è necessario reindirizzare l'utente alla pagina del post casuale, e non potresti farlo anche se lo volessi, perché non è possibile essere reindirizzati a più luoghi contemporaneamente.
Quindi, semplicemente mostra i tuoi post casuali all'interno del tuo loop:
while ( $my_random_post->have_posts () ) {
$my_random_post->the_post ();
echo '<a href="'.get_the_permalink().'">'.get_the_title().'</a>';
}
