Il caricatore di modelli di WordPress includerà il file di modello contestuale appropriato in molte circostanze, anche se la query per quel contesto non restituisce alcun post. Per esempio:
- L'indice principale dei post sul blog
- Indice archivio categorie (la categoria esiste, ma non ha post)
- Indice archivio tag (il tag esiste, ma non ha post)
- Indice archivio autore (l'autore esiste, ma non ha post)
- Indice dei risultati di ricerca
Pertanto, in questi casi, verrà caricato il file modello appropriato, ma non verranno emessi post, poiché la query non restituisce alcun post.
Esempi di prove concettuali:
Quindi, in questi contesti, è utile che il file modello includa il if ( have_posts() )
condizionale.
In altri contesti, il file modello non verrà mai caricato se la query non restituisce alcun post. Per esempio:
- Post di blog singolo
- Pagina statica
In questi contesti, if ( have_posts() )
probabilmente non è necessario.
modificare
Capisco che la query è invocata da the_post (), giusto? E se while (have_posts ()) esiste, la query non si verifica mai se non ci sono post.
Per capire cosa sta succedendo, devi guardare l'ordine delle azioni di WordPress . A partire da wp_loaded
(e omettendone alcuni per chiarezza):
wp_loaded
parse_request
send_headers
parse_query
pre_get_posts
wp
template_redirect
get_header
wp_head
the_post
wp_footer
Quindi, cosa sta succedendo e in quale ordine?
- La query viene invocata:
parse_query
pre_get_posts
wp
- Il modello è selezionato:
- Il modello è caricato / emesso. Le seguenti azioni vengono attivate dal modello :
get_header
wp_head
the_post
dynamic_sidebar
get_footer
wp_footer
Quindi, the_post
attivato da the_post()
, accade molto tempo dopo che la query viene analizzata, i post vengono recuperati e il modello viene caricato.
Sono molto grato che tu abbia dato molte informazioni che non sapevo, ma non è quello che ti ho chiesto.
Oh, ma credo che sia esattamente quello che hai chiesto.
La vera domanda è: che cos'è un ritorno di query valido ? Per contesti come l'indice di archivio delle categorie, la query è valida e il modello di categoria viene caricato, se esiste l'ID categoria richiesto, anche se non ci sono post assegnati a quella categoria .
Perché? Perché la query da analizzare è (IIRC) &cat={ID}
- che è una query valida anche se non ci sono post assegnati a quella categoria , e quindi non risulta in un 404 al momento dell'analisi.
In tal caso, ottieni una query valida e un file modello caricato, ma nessun post . Così, if ( have_posts() )
, è, di fatto rilevanti. Ancora una volta, ecco un esempio: la categoria esiste, ma non ha post assegnati. Il file del modello di categoria viene caricato e if ( have_posts() )
restituitofalse
.
Ciò non sarà valido per le query che includono una variabile post ( &p={ID}
) come singoli post di blog e pagine statiche, poiché il post non esisterà effettivamente e, se analizzato, la query non restituirà un oggetto valido.
Modifica 2
Se capisco giustamente se non esiste if (have_posts ()) in un modello di categoria e la categoria non ha post, allora restituisce 404.php, anche se dovrebbe essere restituito category-sample.php senza post. È giusto?
No. Ricorda: il modello è selezionato in template_redirect
. Pertanto, se la query è valida, viene caricato il file modello appropriato. Se la query non è valida, viene caricato il modello 404.
Quindi, una volta caricato un modello, ad esempio il modello di categoria, una volta che il ciclo è stato emesso, il modello non cambia .
Guarda di nuovo l'ordine delle azioni:
parse_query
pre_get_posts
wp
template_redirect
- il modello viene scelto e caricato qui. Questo è il punto di non ritorno del modello . Il modello non può cambiare dopo questo punto.
- ...
the_post
- postdata è impostato qui, come parte della chiamata in loop. Viene chiamato all'interno del modello e il modello non cambia in base ai dati disponibili nell'oggetto query
Modifica finale
E sto affermando che, mentre controlla l'esistenza dei post, perché dovrei eseguire lo stesso test due volte. Questa è la mia domanda dal primo punto che ho chiesto solo a tale proposito.
E con ciò, finalmente capisco: la tua domanda non ha avuto niente a che fare con WordPress o WordPress Loop . Stai chiedendo di racchiudere qualsiasi while
loop PHP arbitrario all'interno di un if
condizionale che controlla la stessa condizione.
Questa domanda non rientra nell'ambito di applicazione di WPSE, ma spiegherò brevemente:
Un if
condizionale è una valutazione binaria: è uno true
o false
, e ciò che accade all'interno di quel condizionale viene eseguito una volta .
Un while
condizionale è un ciclo : rimane vero per un certo periodo discreto, basato su una sorta di contatore; e ciò che accade all'interno di quel condizionale viene eseguito più volte - una volta per ogni iterazione del contatore.
Quindi, supponiamo che tu voglia produrre un elenco non ordinato di cose, se l'elenco delle cose è popolato. Se usi un while
ciclo e ometti il if
wrapper, il markup sarebbe simile al seguente:
<ul>
<?php while ( list_of_things() ) : ?>
<li><?php the_list_item(); ?></li>
<?php endwhile; ?>
</ul>
E se list_of_things()
fosse vuoto, l'output renderizzato sarebbe:
<ul>
</ul>
Ciò lascia un markup non necessario (e non valido).
Ma se aggiungi un if
wrapper condizionale, puoi farlo:
<?php if ( list_of_things() ) : ?>
<ul>
<?php while ( list_of_things() ) : ?>
<li><?php the_list_item(); ?></li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
E se list_of_things()
fosse vuoto, non verrebbe emesso alcun markup.
Questo è solo un esempio. Esistono molti usi per quel if
wrapper condizionale e il if
wrapper condizionale ha uno scopo completamente diverso rispetto al while
loop.