Cum să împarți o buclă în mai multe coloane

14 feb. 2011, 13:58:16
Vizualizări: 31.3K
Voturi: 11

Dacă am o buclă care rulează dintr-o interogare de categorie precum:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<ul>
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<li>.. </li><?php wp_reset_query(); ?>
<?php endwhile; ?>
</ul>

Cum aș putea crea o clauză if care să întrerupă lista la un anumit interval și să înceapă una nouă? De exemplu, la al 10-lea articol, să returneze un </ul> și să înceapă unul nou <ul> la al 11-lea.

Următorul cod este incorect, dar ilustrează obiectivul meu:

<?php $count =0;
    while($count <=50){
        if ($count == 9){
            echo "<li><a href='<?php the_permalink(); ?>'>
                      <?php the_title(); ?></a></li></ul>";
            } 
        elseif ($count == 10){
        echo "<ul><li><a href='<?php the_permalink(); ?>'>
                          <?php the_title(); ?></a></li>";
        }
        else {
        echo "<li><a href='<?php the_permalink(); ?>'><?php the_title(); ?></a></li>";
        }

Care este modalitatea corectă de a include această logică în buclă?

1
Comentarii

Am actualizat răspunsul meu cu ceva care ar trebui să fie în general ușor de utilizat și testat.

hakre hakre
14 feb. 2011 18:13:41
Toate răspunsurile la întrebare 5
0
22

Crează coloane pentru interogarea și afișarea simplă

În teme, este probabil mai util să ai ceva care se integrează bine în etichetele de șablon și bucla. Prima mea răspuns nu s-a concentrat prea mult pe asta. În plus, am considerat că este puțin prea complicat pentru o adoptare rapidă.

O abordare mai ușoară care mi-a venit în minte a fost să extind "bucla" cu coloane și am ajuns la această soluție până acum:

Un obiect WP_Query_Columns "extinde" orice interogare standard WP cu coloane peste care se poate itera ușor. Primul parametru este variabila de interogare, iar al doilea parametru este numărul de elemente care trebuie afișate pe coloană:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<?php foreach(new WP_Query_Columns($the_query, 10) as $column_count) : ?>
    <ul>
        <?php while ($column_count--) : $the_query->the_post(); ?>
        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
    </ul>
<?php endforeach; ?>

Pentru a-l utiliza, adaugă pur și simplu clasa WP_Query_Columns din acest gist în fișierul function.php al temei tale.

Utilizare avansată

Dacă ai nevoie de numărul coloanei pe care o afișezi în prezent (de exemplu, pentru unele clase CSS even/odd, poți obține asta și din foreach:

<?php foreach(new WP_Query_Columns($the_query, 10) as $column => $column_count) : ?>

Și numărul total de coloane este disponibil și el:

<?php 
    $the_columns = new WP_Query_Columns($the_query, 10);
    foreach($the_columns as $column => $column_count) : 
?>
    <h2>Coloana <?php echo $column; ?>/<?php echo sizeof($the_columns); ?></h2>
    <ul>...

Exemplu Twenty Ten

Am putut modifica rapid tema twenty ten pentru un test și am adăugat titluri deasupra oricărei bucle în acest fel. Este inserat în loop.php, începutul este codul temei:

<?php /* Dacă nu există postări de afișat, cum ar fi o pagină de arhivă goală */ ?>
<?php if ( ! have_posts() ) : ?>
    <div id="post-0" class="post error404 not-found">
        <h1 class="entry-title"><?php _e( 'Nu a fost găsit', 'twentyten' ); ?></h1>
        <div class="entry-content">
            <p><?php _e( 'Ne cerem scuze, dar nu au fost găsite rezultate pentru arhiva solicitată. Poate căutarea vă va ajuta să găsiți o postare relevantă.', 'twentyten' ); ?></p>
            <?php get_search_form(); ?>
        </div><!-- .entry-content -->
    </div><!-- #post-0 -->
<?php endif; ?>

<!-- WP_Query_Columns -->
<?php 
    ### Necesită WP_Query_Columns --- vezi http://wordpress.stackexchange.com/q/9308/178
    $query_copy = clone $wp_query; // salvează pentru a restaura mai târziu
    foreach( new WP_Query_Columns($wp_query, 3) as $columns_index => $column_count ) : ?>
    <ul>
        <?php 
        while ( $column_count-- ) : the_post(); ?>
            <li><h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Legătură permanentă către %s', 'twentyten' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2></li>
        <?php endwhile; ?>
    </ul>       
<?php endforeach; ?>
<?php $wp_query = $query_copy;?>

<?php
    /* Începe bucla.
    ...

Pentru un răspuns mai lung:

(care este practic cum am ajuns la lucrurile de mai sus, dar explică mai bine cum să rezolvi efectiv problema cu operații matematice simple. Noua mea soluție este să iterezi peste ceva pre-calculat.)

Depinde puțin de cât de mult trebuie să rezolvi efectiv problema.

De exemplu, dacă numărul de elemente pe coloană este egal cu unu, acest lucru este foarte simplu:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>    
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<ul>
    <li>.. </li>
<ul>
<?php endwhile;  wp_reset_query(); ?>
</ul>

Chiar și cu acest cod simplu, se poate observa că există mai multe decizii de luat:

  • Câte elemente sunt într-o coloană?
  • Câte elemente sunt în total?
  • Există o nouă coloană de început?
  • Și există o coloană de încheiat?

Ultima întrebare este destul de interesantă pentru ieșirea HTML, deoarece probabil dorești să închizi nu doar elementele, ci și coloana cu elemente HTML.

Din fericire, cu codul, putem seta toate acestea în variabile și putem crea un cod care să se calculeze întotdeauna în funcție de nevoile noastre.

Și uneori, nici măcar nu putem răspunde la fiecare întrebare de la început. De exemplu, numărul total de elemente: Există vreunul, câteva, multiple, un număr exact care se potrivește cu un număr întreg de coloane în total?

Chiar dacă răspunsul lui Jan Fabry ar putea funcționa în unele cazuri (ca exemplul meu de mai sus pentru scenariul cu un element pe coloană), s-ar putea să fii interesat de ceva care funcționează pentru orice număr de elemente returnate de WP_Query.

Mai întâi pentru matematică:

//
// exemplu aritmetic:
//
# configurație:
$colSize = 20;  // numărul de elemente într-o coloană
$itemsTotal = 50; // numărul de elemente (total)

# calcul:
$count = 0; // o variabilă contor bazată pe zero
$isStartOfNewColum = 0 === ($count % $colSize); // operație modulo
$isEndOfColumn = ($count && $isStartOfNewColum) || $count === $itemsTotal; // încapsulare

Acest cod nu rulează, așa că să-l transformăm într-un exemplu simplu de text

//
// exemplu simplu de text:
//
$column = 0; // inițializează un contor de coloană
for($count=0; $count<= $itemsTotal; $count++) {
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // actualizează contorul de coloană

    if ($isEndOfColumn) {
        printf("/Sfârșitul coloanei: %d\n", $column-1);
    }

    if ($isStartOfNewColum) {
        printf("<începutul coloanei: %d\n", $column);
    }

    printf(" * elementul %d\n", $count);
}
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    printf("/Sfârșitul coloanei: %d\n", $column);
}

printf("Terminat. Numărul total de coloane: %d.\n", $column);

Acesta rulează efectiv și face deja o ieșire:

<începutul coloanei: 1
 * elementul 0
 * elementul 1
 * elementul 2
 * elementul 3
...
 * elementul 17
 * elementul 18
 * elementul 19
/Sfârșitul coloanei: 1
<începutul coloanei: 2
 * elementul 20
 * elementul 21
 * elementul 22
...
 * elementul 37
 * elementul 38
 * elementul 39
/Sfârșitul coloanei: 2
<începutul coloanei: 3
 * elementul 40
 * elementul 41
 * elementul 42
...
 * elementul 48
 * elementul 49
 * elementul 50
/Sfârșitul coloanei: 3
Terminat. Numărul total de coloane: 3.

Acesta simulează deja destul de bine cum ar putea arăta într-un șablon WordPress:

//
// exemplu WordPress:
//
$count = 0; // inițializează contorul de elemente
$column = 0; // inițializează contorul de coloană
$colSize = 10; // dimensiunea coloanei de zece de data aceasta
$the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');
$itemsTotal = $the_query->post_count;
?>
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<?php
    # variabile de afișare a coloanelor 
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // actualizează contorul de coloană

    if ($isEndOfColumn) {
        print('</ul>');
    }

    if ($isStartOfNewColum) {
        printf('<ul class="col-%d">', $column);
    }
?>
    <li> ... fă-ți ziua ...
    </li>
<?php endwhile; ?>
<?php
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    print('</ul>');
}
// Nu trebuie să faci asta în fiecare buclă, doar o dată la sfârșit ar trebui să fie suficient
wp_reset_query();
?>

(Nu am executat ultimul exemplu într-un mediu WP, dar ar trebui să fie cel puțin sintactic corect.)

14 feb. 2011 15:03:48
5

Aceasta este mai mult o întrebare generală de programare, dar iată ideea de bază:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<ul>
<?php
$post_counter = 0;
while ($the_query->have_posts()) :
    $the_query->the_post();
    $post_counter++;
?>
    <li>.. </li>
<?php
    if ( 0 == $post_counter % 10 ) {
        echo '</ul><ul>';
    }
endwhile;
?>
</ul>
<?php
// Nu este necesar să faceți acest lucru în fiecare buclă, doar o singură dată la sfârșit este suficient
wp_reset_query();
?>
14 feb. 2011 14:06:15
Comentarii

Operația modulo este practic răspunsul matematic. Dar exemplul tău nu are o structură HTML semantică. Am propus ceva similar în răspunsul meu, după cum îți poți imagina, a durat ceva mai mult ;)

hakre hakre
14 feb. 2011 15:12:40

wp_reset_query(); nu are legătură cu variabila $the_query. Nu este deloc necesar, nu-i așa?

hakre hakre
14 feb. 2011 17:26:21

@hakre: $the_query->the_post() va suprascrie variabila globală $post, iar wp_reset_query() restaurează aceasta (prin apelarea wp_reset_postdata() - care ar putea fi suficient și de la sine?).

Jan Fabry Jan Fabry
14 feb. 2011 20:11:27

Bine, am amestecat cumva wp_query și post puțin, credeam că va afecta $wp_query dar în exemplu a fost folosit $the_query. Totuși, am greșit, o voi adăuga în a doua mea răspuns pentru completitudine.

hakre hakre
14 feb. 2011 20:21:24

Nu iei în considerare ultimul element. Dacă bucla se termină pe un număr divizibil cu 10, vei obține un set gol de <ul></ul>.

Dan Gayle Dan Gayle
15 feb. 2011 02:08:59
4

Nu este nevoie să creezi o variabilă separată pentru numărare, deoarece variabila query deja numără la: $wp_query->current_post. De asemenea, trebuie să iei în considerare și ultima intrare din listă, astfel încât să nu ai <ul></ul> goale în markup-ul tău.

<?php 
$the_query = new WP_Query('showposts=21&orderby=title&order=asc'); 
echo "<ul>";
while ($the_query->have_posts()) :
    $the_query->the_post();
    echo "<li>{$the_query->current_post}</li>";

    // Reține că postarea este deja numărată în variabila $the_query->current_post când ești în buclă. Adaugă unu pentru a traduce numărarea array-ului la numărări reale.
    // Exemplul lui Jan nu ținea cont de ultima intrare din listă. Nu vrem să avem <ul>-uri goale
    if ((($the_query->current_post+1) % 10 == 0) && ($the_query->current_post+1 !== count($the_query->posts))):
        echo "</ul><ul>";
    endif;
endwhile;
echo "</ul>";
?>
14 feb. 2011 21:41:31
Comentarii

Notat. Am adăugat exemplul.

Dan Gayle Dan Gayle
15 feb. 2011 01:54:42

Super, îmi place adăugarea pentru că acum ´<ul></ul>` gol este doar pentru 0 postări (dar pentru acelea încă este) - dar din ce am învățat astăzi, această formă este cea mai compactă fără a introduce o funcție nouă.

hakre hakre
15 feb. 2011 02:50:52

Adăugare frumoasă. Văd că WP_Query are și o variabilă $post_count, poți folosi asta în loc de count($the_query->posts). Zac, poți "anula acceptarea" răspunsului meu și accepta altul dacă ți-a rezolvat problema mai bine.

Jan Fabry Jan Fabry
15 feb. 2011 13:25:15

@Jan - Aș prefera variabila encapsulată în locul celei globale, deoarece acest lucru crește modularitatea. Dar e bine de știut că există una.

hakre hakre
16 feb. 2011 10:27:42
0

Adaugă funcția get_columns_array() în fișierul tău function.php. Apoi poți itera cu ușurință peste coloanele tale:

În tema ta, poți folosi un foreach pentru a parcurge coloanele:

<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<?php foreach(get_columns_array($post_count) as $column_count) : ?>
    <ul>
        <?php while ($column_count--) : $the_query->the_post(); ?>
        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
    </ul>
<?php endforeach; wp_reset_postdata(); ?>

Am setat dimensiunea implicită a unei coloane la 10. Poți folosi al doilea parametru pentru a seta dimensiunea unei coloane după preferințe. De exemplu, la 7: get_columns_array($post_count, 7);.

14 feb. 2011 20:15:05
0

Iată o altă abordare pe care o poți folosi:

$article = 0;

<?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
        <?php $article = $article + 1; ?>
        <?php if ($article % 3 == 1) echo '<div class="row-fluid">';  ?>
            <div class="span4">
            <h2><a href="<?php esc_url( the_permalink() ); ?>" title="Legătură permanentă către <?php the_title(); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
            </div><!--/span-->
        <?php if ($article % 3 == 0) echo '</div><!--/row-->';  ?>
    <?php endwhile;?>
<?php else: ?>
<h2>...</h2>
<?php endif; ?>
11 sept. 2012 20:33:52