Loop dentro un loop?

6 nov 2012, 16:14:09
Visualizzazioni: 38.9K
Voti: 7

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; ?>
1
Commenti

Fai esattamente la stessa cosa. Imposta una nuova variabile all'interno del secondo ciclo while, e usa $that_query->has_posts() e ->the_post(), ma assicurati di non utilizzare alcun dato dal secondo ciclo dopo che il terzo è iniziato. Assicurati anche di usare wp_query_reset() dopo il tuo ciclo while.

Eric Holmes Eric Holmes
6 nov 2012 16:17:25
Tutte le risposte alla domanda 3
8
19

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

6 nov 2012 16:21:47
Commenti

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

andy andy
6 nov 2012 17:50:28

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.

Mridul Aggarwal Mridul Aggarwal
6 nov 2012 18:41:15

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

andy andy
6 nov 2012 18:47:34

$post=$backup; va dopo il ciclo while, cioè dopo il endwhile;

Mridul Aggarwal Mridul Aggarwal
6 nov 2012 18:52:31

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!

andy andy
6 nov 2012 19:03:24

ho aggiunto una spiegazione

Mridul Aggarwal Mridul Aggarwal
6 nov 2012 19:26:25

è necessario utilizzare wp_reset_postdata() con la query interna?

chap chap
12 giu 2015 10:16:46

è necessario utilizzare wp_reset_query dopo la query interna

Lane Lane
30 gen 2016 01:26:16
Mostra i restanti 3 commenti
0
10

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;
10 nov 2016 18:28:16
1

Aggiungi global $post;$backup=$post; prima del while interno e $post=$backup; dopo il while interno.

(Perché Mridul Aggarwal non ha scritto la cosa reale nella parte di codice?)

3 apr 2021 14:28:28
Commenti

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.

Matthew Brown aka Lord Matt Matthew Brown aka Lord Matt
3 apr 2021 22:54:44