Comment diviser une boucle en plusieurs colonnes

11

Si une boucle est en cours d'exécution à partir d'une requête de catégorie telle que:

<?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>

Comment créer une clause if qui casse la liste à un certain intervalle et en commence une nouvelle. Ainsi, par exemple, à la 10e publication, retournez un </ul> et démarrez-en un nouveau <ul> à 11.

Ceci est incorrect mais pour illustrer mon objectif:

<?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>";
        }

Quelle est la bonne façon d’inclure cette logique dans la boucle?

    
posée zac 14.02.2011 - 12:58

5 réponses

21

Créer des colonnes pour votre requête et un affichage facile

Dans les thèmes, il est probablement plus utile d’avoir quelque chose qui s’intègre bien dans les balises de modèles et dans la boucle. Ma première réponse ne s'est pas concentrée sur cela. De plus, je pensais que c'était un peu trop compliqué pour une adoption rapide.

Une approche plus simple qui m'est venue à l'esprit était d'étendre "la boucle" avec des colonnes et d'arriver à cette solution jusqu'à présent:

Un objet WP_Query_Columns "étend" toute requête WP standard avec des colonnes pouvant être facilement itérées. Le premier paramètre est la variable de requête et le second paramètre est le nombre d'éléments à afficher par colonne:

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

Pour l'utiliser, ajoutez simplement la classe WP_Query_Columns de cet élément à votre fichier function.php.

.

Utilisation avancée

Si vous avez besoin du numéro de colonne que vous affichez actuellement (par exemple, pour certaines classes CSS paires / impaires, vous pouvez également l'obtenir auprès de foreach:

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

Et le nombre total de colonnes est également disponible:

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

Exemple Twenty Ten

Je pourrais rapidement pirater vingt-dix thèmes pour un test et ajouter des titres au-dessus de toute boucle de cette façon. Il est inséré dans loop.php, le début est le code du thème:

<?php /* If there are no posts to display, such as an empty archive page */ ?>
<?php if ( ! have_posts() ) : ?>
    <div id="post-0" class="post error404 not-found">
        <h1 class="entry-title"><?php _e( 'Not Found', 'twentyten' ); ?></h1>
        <div class="entry-content">
            <p><?php _e( 'Apologies, but no results were found for the requested archive. Perhaps searching will help find a related post.', 'twentyten' ); ?></p>
            <?php get_search_form(); ?>
        </div><!-- .entry-content -->
    </div><!-- #post-0 -->
<?php endif; ?>

<!-- WP_Query_Columns -->
<?php 
    ### Needs WP_Query_Columns --- see http://wordpress.stackexchange.com/q/9308/178
    $query_copy = clone $wp_query; // save to restore later
    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__( 'Permalink to %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
    /* Start the Loop.
    ...

Pour une réponse plus longue:

(c’est en gros ainsi que j’ai abordé ce qui précède, mais explique mieux comment résoudre le problème à l’aide d’opérations mathématiques simples. Ma nouvelle solution consiste à effectuer une itération sur un élément précalculé.)

Cela dépend un peu du montant dont vous avez réellement besoin pour résoudre le problème.

Par exemple, si le nombre d'éléments par colonne est égal à un, c'est très simple:

<?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>

Même avec ce code simple, on peut voir qu'il y a plusieurs décisions à prendre:

  • Combien y a-t-il d'éléments dans une colonne?
  • Combien y a-t-il d'articles au total?
  • Y a-t-il une nouvelle colonne à commencer?
  • Et y a-t-il une colonne à terminer?

La dernière question est assez intéressante pour la sortie HTML car vous souhaitez probablement inclure non seulement des éléments, mais également la colonne contenant des éléments html.

Heureusement avec le code, nous pouvons définir toutes ces variables dans et créer un code toujours adapté à nos besoins.

Et parfois même, nous ne pouvons même pas répondre à toutes les questions depuis le début. Par exemple, le nombre total d'éléments: existe-t-il des nombres exacts, multiples, qui correspondent à un nombre entier de colonnes?

Même la réponse de Jan Fabry peut fonctionner dans certains cas (comme le montre l'exemple ci-dessus pour le scénario à un élément par colonne), vous pourriez être intéressé par quelque chose qui fonctionne pour n'importe quel nombre d'éléments renvoyés par WP_Query.

D'abord pour le calcul:

//
// arithmetical example:
//
# configuration:
$colSize = 20;  // number of items in a column
$itemsTotal = 50; // number of items (total)

# calculation:
$count = 0; // a zero-based counter variable
$isStartOfNewColum = 0 === ($count % $colSize); // modulo operation
$isEndOfColumn = ($count && $isStartOfNewColum) || $count === $itemsTotal; // encapsulation

Ce code ne fonctionne pas, alors mettons cela dans un exemple de texte simple

//
// simple-text example:
//
$column = 0; // init a column counter
for($count=0; $count<= $itemsTotal; $count++) {
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // update column counter

    if ($isEndOfColumn) {
        printf("/End of Column: %d\n", $column-1);
    }

    if ($isStartOfNewColum) {
        printf("<start of Column: %d\n", $column);
    }

    printf(" * item %d\n", $count);
}
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    printf("/End of Column: %d\n", $column);
}

printf("Done. Total Number of Columns: %d.\n", $column);

Cela fonctionne et produit déjà une sortie:

<start of Column: 1
 * item 0
 * item 1
 * item 2
 * item 3
...
 * item 17
 * item 18
 * item 19
/End of Column: 1
<start of Column: 2
 * item 20
 * item 21
 * item 22
...
 * item 37
 * item 38
 * item 39
/End of Column: 2
<start of Column: 3
 * item 40
 * item 41
 * item 42
...
 * item 48
 * item 49
 * item 50
/End of Column: 3
Done. Total Number of Columns: 3.

Ceci simule déjà assez bien à quoi il pourrait ressembler dans un modèle wordpress:

//
// wordpress example:
//
$count = 0; // init item counter
$column = 0; // init column counter
$colSize = 10; // column size of ten this time
$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
    # columns display variables 
    $isStartOfNewColum = 0 === ($count % $colSize); // modulo
    $isEndOfColumn = ($count && $isStartOfNewColum);
    $isStartOfNewColum && $column++; // update column counter

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

    if ($isStartOfNewColum) {
        printf('<ul class="col-%d">', $column);
    }
?>
    <li> ... make your day ...
    </li>
<?php endwhile; ?>
<?php
if ($count && !$isEndOfColumn && --$count === $itemsTotal) {
    print('</ul>');
}
// You don't have to do this in every loop, just once at the end should be enough
wp_reset_query();
?>

(Je n'ai pas exécuté le dernier exemple dans un environnement WP, mais il devrait être au moins syntaxiquement correct.)

    
réponse donnée hakre 14.02.2011 - 14:03
2

Ceci est plutôt une question de programmation générale, mais voici l’idée de base:

<?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
// You don't have to do this in every loop, just once at the end should be enough
wp_reset_query();
?>
    
réponse donnée Jan Fabry 14.02.2011 - 13:06
1

Il n'est pas nécessaire de créer une variable distincte pour le comptage, car la requête var la compte déjà à: $wp_query->current_post . De plus, vous devez rendre compte de la dernière entrée de la liste pour ne pas avoir <ul></ul> vide dans votre balisage.

<?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>";

    // Note that the post is already counted in the $the_query->current_post variable when in the loop. Add one to translate array counting to real counts.
    // Jan's example didn't account for the final entry in the list. Don't want empty <ul>'s hanging around
    if ((($the_query->current_post+1) % 10 == 0) && ($the_query->current_post+1 !== count($the_query->posts))):
        echo "</ul><ul>";
    endif;
endwhile;
echo "</ul>";
?>
    
réponse donnée Dan Gayle 14.02.2011 - 20:41
0

Ajoutez la fonction get_columns_array() à votre function.php. Vous pouvez ensuite facilement parcourir vos colonnes:

Dans votre thème, vous passez ensuite chaque boucle sur les colonnes:

<?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(); ?>

J'ai défini la taille par défaut d'une colonne sur 10. Vous pouvez utiliser le second paramètre pour définir vous-même la taille d'une colonne. Comme à 7: get_columns_array($post_count, 7); .

    
réponse donnée hakre 14.02.2011 - 19:15
0

Voici une autre approche que vous pouvez adopter:

$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="Permalink to <?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; ?>
    
réponse donnée Vincent 11.09.2012 - 19:33

Lire d'autres questions sur les étiquettes