Loop dentro un loop?
Sto usando un paio di loop wp_query personalizzati nella mia pagina, il primo recupera notizie da una determinata categoria e mostra un piccolo estratto con il permalink.
Il secondo è un altro wp_query che ottiene un tipo di post personalizzato con alcuni campi personalizzati avanzati.
Il problema è che vorrei un altro loop all'interno del secondo che prenda 3 post dalla sezione news con una miniatura (praticamente l'opposto del primo loop, prenderà tutte le altre categorie). Dopo aver letto innumerevoli articoli sul loop non riesco a capire come creare un loop 'nidificato' all'interno del mio secondo loop. Sono sicuro che deve essere semplice, sembra qualcosa di facile da fare.
Ecco il mio codice con molto HTML rimosso.
<?php
/*
* Nome Template: Homepage
*/
?>
<?php get_header(); ?>
<div class="thenews">
<div class="newsinner">
<div class="grid-1">
<h6 class="nsix">ultime notizie</h6>
</div> <!-- fine div grid-1 -->
<div class="grid-2">
<?php
$recentPosts = new WP_Query();
$recentPosts->query('cat=5&showposts=1');
?>
<?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
<p><?php echo ''.get_the_twitter_excerpt(); ?>...</p>
</div> <!-- fine div grid-2 -->
<div class="grid-3">
<a href="<?php the_permalink() ?>">Leggi</a>
<?php endwhile; wp_reset_query(); ?>
</div> <!-- fine div grid-3 -->
</div> <!-- fine div newsinner -->
</div> <!-- fine div thenews -->
<div id="main-content">
<div class="typograhpy">
<div class="home-grid-1">
<div class="home-grid-1-inner">
<?php
$portfolio_query = new WP_Query(array(
'post_type' => 'headerhome',
'showposts' => 1
) );
?>
<?php while ($portfolio_query->have_posts()) : $portfolio_query->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
<div class="anyres">
<p> <?php the_field('anyresolution'); ?></p>
</div> <!-- fine div anyres -->
</div> <!-- fine home-gird-1-inner -->
</div> <!-- fine home-grid-1 -->
<div class="home-grid-2">
<div class="inner-home-1">
<div class="inside-home-1-1">
<h2><?php the_field('services_'); ?></h2>
<p> <?php the_field('services_text'); ?></p>
</div> <!-- fine div inside-home-1-1 -->
<div class="inside-home-1-2">
<p> <?php the_field('services_text_right'); ?></p>
</div> <!-- fine div inside-home-1-2 -->
</div> <!-- fine div inner-home-1 -->
<div class="margindiv"></div>
<div class="inner-home-2">
<div class="brushpic"></div> <!-- fine div brushpic -->
<h3><?php the_field('services_1_header') ?></h3>
<p><?php the_field('services_1_content'); ?></p>
</div><!-- fine div inner-home-2 -->
<div class="inner-home-3">
<div class="cloudpic"></div> <!-- fine div cloudpic -->
<h3><?php the_field('services_2_header') ?></h3>
<p><?php the_field('services_2_content'); ?></p>
</div> <!-- fine div inner-home-3 -->
<div class="inner-home-4">
<div class="onetwoone"></div> <!-- fine div onetwoone -->
<h3><?php the_field('services_3_header') ?></h3>
<p><?php the_field('services_3_content'); ?></p>
</div> <!-- fine div inner-home-4 -->
</div> <!-- fine div home-grid-2 -->
<div style="clear:both"></div>
</div> <!-- fine div typograhpy -->
<div class="graphgrid">
</div> <!-- fine div graphgrid -->
<div class="sizesdes">
<blockquote><?php the_field('gallery_blockquote_') ?></blockquote>
<p><?php the_field('gallery_content'); ?></p>
<?php endwhile; wp_reset_query(); ?>
</div>
</div><!-- fine div main-content -->
<?php get_footer(); ?>
Codice funzionante, anche se non recupera the_post_thumbnail
<?php
global $post;$backup=$post;
$inner_query = new WP_Query();
$inner_query->query('showposts=3');
?>
<?php while ($inner_query->have_posts()) : $inner_query->the_post(); $post=$backup; ?>
<?php the_post_thumbnail(); ?>
<p><?php echo ''.get_the_custom_excerpt(); ?>...</p>
<a href="<?php the_permalink() ?>">Leggi</a>
<?php endwhile; ?>
Puoi creare qualsiasi numero di loop che desideri istanziando più oggetti WP_Query
$query = new WP_Query($args);
while ($query->have_posts()) :
// inizializzazione per $inner_args & backup del global $post corrente
$inner_query = new WP_Query($inner_args);
while ($inner_query->have_posts()) :
// fai qualcosa
endwhile;
// ripristina il global $post dal backup creato precedentemente
endwhile;
SPIEGAZIONE COME RICHIESTO
Ogni volta che chiami un template tag come the_title();
, questo mostra qualcosa relativo al post corrente nel loop. Ma come fa a sapere qual è il post corrente? Lo fa leggendo le informazioni dai global postdata (memorizzati in una variabile globale $post
)
Quando usi un loop utilizzi sempre $query->the_post()
come prima istruzione. Questa funzione imposta quei dati globali al prossimo post dell'oggetto WP_Query
(il contenuto precedente viene perso)
Qui quando hai chiamato il loop interno, i postdata relativi al loop esterno venivano persi quando il loop interno iniziava a lavorare. Poi qualsiasi funzione usi dopo la fine del loop interno troverà ancora solo i dati del loop interno.
Nella soluzione hai prima salvato i dati del loop esterno in un'altra variabile prima che il contenuto venga perso. Poi il loop lavora come dovrebbe (cancellando tutti i dati del loop esterno).
Poi quando il lavoro del loop interno è completato, ora hai bisogno di usare i dati del loop esterno ma sono persi a causa del loop interno. È qui che prendi i dati salvati precedentemente & li sostituisci. Ora sei tornato alla posizione in cui eri quando hai iniziato il loop interno

Ho modificato il mio primo post, ma non riesco a farlo funzionare correttamente. Sono sicuro che sto facendo qualcosa di sbagliato.

Hai fatto il backup dei dati globali del post? Aggiungi global $post;$backup=$post;
prima del while interno e $post=$backup;
dopo il while interno.

Ah, funziona quando lo scrivo così (vedi modifica al primo post), ma the_post_thumbnail non funziona più.

Ah giusto, ora funziona. Puoi spiegarmi cosa fa global $post;$backup=$post; nel contesto del loop? Così capisco esattamente cosa sto facendo.
E grazie per l'aiuto, lo apprezzo molto!

Puoi utilizzare anche WP_Query::reset_postdata() per questo scopo.
$query = new WP_Query($args);
while ($query->have_posts()) :
// inizializzazione per $inner_args e backup del global $post corrente
$inner_query = new WP_Query($inner_args);
while ($inner_query->have_posts()) :
// fai qualcosa
endwhile;
// ripristina il global $post dal backup creato precedentemente
$query->reset_postdata();
endwhile;

La tua risposta è iniziata bene. Ti consiglio di spiegare come e perché questo codice risolve il problema, in modo che altri possano imparare da esso. Consulta la guida alle risposte per ulteriori consigli.
