Loop în interiorul unui loop?

6 nov. 2012, 16:14:09
Vizualizări: 38.9K
Voturi: 7

Folosesc câteva loop-uri personalizate wp_query pe pagina mea, primul extrage știri dintr-o anumită categorie și apoi afișează un mic fragment din acestea cu permalink-ul.

Al doilea este un alt wp_query care preia un tip de postare personalizat cu câteva câmpuri personalizate avansate.

Problema este că aș dori un alt loop în interiorul celui de-al doilea care să preia 3 postări din secțiunea de știri cu o miniatură (practic opusul primului loop, va prelua toate celelalte categorii). După ce am citit numeroase articole despre loop nu pot să îmi dau seama cum să fac un loop 'nested' în interiorul celui de-al doilea loop. Sunt sigur că trebuie să fie simplu, pare ceva ușor de făcut.

Iată codul meu cu mult HTML eliminat.

<?php 
/*
*  Template Name: Homepage
*/
?>

<?php get_header(); ?>

<div class="thenews">

    <div class="newsinner">

        <div class="grid-1">
            <h6 class="nsix">ultimele știri</h6>
        </div> <!-- sfârșitul 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> <!-- sfârșitul div grid-2 -->   

        <div class="grid-3">
            <a href="<?php the_permalink() ?>">Citește</a>
            <?php endwhile; wp_reset_query(); ?>
        </div> <!-- sfârșitul div grid-3 -->

    </div> <!-- sfârșitul div newsinner -->

</div> <!-- sfârșitul 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> <!-- sfârșitul div anyres -->

            </div> <!-- sfârșitul home-gird-1-inner -->

        </div> <!-- sfârșitul 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> <!-- sfârșitul div inside-home-1-1 -->
                <div class="inside-home-1-2">
                    <p> <?php the_field('services_text_right'); ?></p>
                </div> <!-- sfârșitul div inside-home-1-2 -->
            </div> <!-- sfârșitul div inner-home-1 -->

            <div class="margindiv"></div>

            <div class="inner-home-2">
                <div class="brushpic"></div> <!-- sfârșitul div brushpic -->
                <h3><?php the_field('services_1_header') ?></h3>       
                <p><?php the_field('services_1_content'); ?></p>
            </div><!-- sfârșitul div inner-home-2 -->

            <div class="inner-home-3">
                <div class="cloudpic"></div> <!-- sfârșitul div cloudpic -->
                <h3><?php the_field('services_2_header') ?></h3>       
                <p><?php the_field('services_2_content'); ?></p>
            </div> <!-- sfârșitul div inner-home-3 -->

            <div class="inner-home-4">
                <div class="onetwoone"></div> <!-- sfârșitul div onetwoone -->
                <h3><?php the_field('services_3_header') ?></h3>       
                <p><?php the_field('services_3_content'); ?></p>
            </div> <!-- sfârșitul div inner-home-4 -->

        </div> <!-- sfârșitul div home-grid-2 -->

        <div style="clear:both"></div>

    </div> <!-- sfârșitul div typograhpy -->

    <div class="graphgrid">
    </div> <!-- sfârșitul 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><!-- sfârșitul div main-content -->
<?php get_footer(); ?>

Cod funcțional, deși nu va prelua 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() ?>">Citește</a>

<?php endwhile; ?>
1
Comentarii

Fă exact același lucru. Definește o nouă variabilă în interiorul celui de-al doilea loop while și folosește $that_query->has_posts() și ->the_post(), dar asigură-te că nu utilizezi niciunul dintre datele din al doilea loop după ce începe al treilea. De asemenea, asigură-te să folosești wp_query_reset() după bucla ta while.

Eric Holmes Eric Holmes
6 nov. 2012 16:17:25
Toate răspunsurile la întrebare 3
8
19

Puteți crea oricâte bucle doriți prin crearea mai multor obiecte WP_Query

$query = new WP_Query($args);

while ($query->have_posts()) :

    // inițializare pentru $inner_args & salvare backup al variabilei globale $post curente
    $inner_query = new WP_Query($inner_args);

    while ($inner_query->have_posts()) :
        // faceți ceva
    endwhile;
    // restaurarea variabilei globale $post din backup-ul creat anterior

endwhile;

EXPLICATIE CONFORM CERINȚEI

Ori de câte ori apelați o funcție template precum the_title();, aceasta afișează informații despre postarea curentă din buclă. Dar cum știe care postare este cea curentă? Aceasta se face prin citirea informațiilor din datele globale ale postării (stocate într-o variabilă globală $post)

Când utilizați o buclă, întotdeauna folosiți $query->the_post() ca primă instrucțiune. Ceea ce face această funcție este să seteze acele date globale la următoarea postare din obiectul WP_Query (conținutul anterior se pierde)

Aici, când ați apelat bucla interioară, datele postării legate de bucla exterioară se pierdeau când bucla interioară începea să funcționeze. Apoi, orice funcție utilizați după încheierea buclei interioare găsește doar datele buclei interioare.

În soluție, mai întâi ați salvat datele buclei exterioare într-o altă variabilă înainte ca conținutul să se piardă. Apoi bucla funcționează așa cum ar trebui (ștergând toate datele buclei exterioare).

Apoi, când bucla interioară și-a încheiat activitatea, aveți nevoie să utilizați datele buclei exterioare, dar acestea au fost pierdute din cauza buclei interioare. Aici intervine backup-ul salvat anterior - îl înlocuiți. Acum vă întoarceți la poziția de la care ați început bucla interioară.

6 nov. 2012 16:21:47
Comentarii

Am editat primul meu post, nu reușesc să fac asta să funcționeze corect. Dar sunt sigur că fac ceva greșit.

andy andy
6 nov. 2012 17:50:28

Ai făcut backup la global postdata? Adaugă global $post;$backup=$post; înainte de inner while și $post=$backup; după inner while.

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

Ah, funcționează când o scriu așa (vezi editarea din primul post), dar the_post_thumbnail nu mai funcționează.

andy andy
6 nov. 2012 18:47:34

$post=$backup; se pune după bucla while, adică după endwhile;

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

Ah, da, acum funcționează. Poți să explici ce face global $post;$backup=$post; în contextul buclei? Doar ca să știu exact ce fac.

Și mulțumesc pentru ajutor, apreciez!

andy andy
6 nov. 2012 19:03:24

am adăugat explicația

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

trebuie să folosești wp_reset_postdata() cu interogarea interioară?

chap chap
12 iun. 2015 10:16:46

trebuie să folosești wp_reset_query după interogarea interioară

Lane Lane
30 ian. 2016 01:26:16
Arată celelalte 3 comentarii
0
10

Puteți folosi și WP_Query::reset_postdata() pentru asta.

$query = new WP_Query($args);

while ($query->have_posts()) :

    // inițializare pentru $inner_args și backup al postului global curent
    $inner_query = new WP_Query($inner_args);

    while ($inner_query->have_posts()) :
        // fă ceva
    endwhile;

    // restaurare post global din backup-ul creat anterior
    $query->reset_postdata();

endwhile;
10 nov. 2016 18:28:16
1

Adaugă global $post;$backup=$post; înainte de while-ul intern și $post=$backup; după while-ul intern.

(De ce nu a scris Mridul Aggarwal partea reală în secțiunea de cod?)

3 apr. 2021 14:28:28
Comentarii

Răspunsul tău are un început bun. Te rugăm să iei în considerare să explici cum și de ce acest cod rezolvă problema, astfel încât alții să poată învăța din el. Consultă ghidul pentru răspunsuri pentru sfaturi suplimentare.

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