web-dev-qa-db-fra.com

En utilisant PHP boucle pour ajouter des lignes Bootstrap et les numéros de colonne appropriés aux éléments

J'essaie de créer le frontal suivant à l'aide d'une boucle PHP et du système de grille à 12 colonnes de Twitter Bootstrap:

 enter image description here

La sortie HTML est:

<div class="row">
    <div class="col-lg-4">
        Content...
    </div>
    <div class="col-lg-4">
        Content...
    </div>
    <div class="col-lg-4">
        Content...
    </div>
</div>

<div class="row">
    <div class="col-lg-4">
        Content...
    </div>
    <div class="col-lg-4">
        Content...
    </div>
    <div class="col-lg-4">
        Content...
    </div>
</div>

<div class="row">
    <div class="col-lg-6">
        Content...
    </div>
    <div class="col-lg-6">
        Content...
    </div>
</div>

Dans PHP (WordPress), j'emballe tous les 3 éléments dans un .row div:

<?php $i=0; // counter ?>

<?php while ( have_posts() ) : the_post(); ?> 

    <?php if ($i%3==0) { // if counter is multiple of 3 ?>
    <div class="row">
    <?php } ?>

    <div class="col-md-4">
        Content...
    </div>        

    <?php $i++; ?>

    <?php if($i%3==0) { // if counter is multiple of 3 ?>
    </div>
    <?php } ?>

<?php endwhile; ?>

<?php if($i%3!=0) { // put closing div if loop is not exactly a multiple of 3 ?>
</div>
<?php } ?>


Le problème:

Je ne sais pas comment ajouter le numéro de colonne approprié aux éléments de la dernière ligne pour qu'ils remplissent la grille de 12 colonnes. 

Par exemple, dans mon illustration ci-dessus, chaque élément de la dernière ligne a col-6 (développe 6 colonnes) remplissant le système de grille 12. Autre exemple, s'il y avait 1 élément dans la dernière ligne, il devrait avoir col-12

Remarque: chaque ligne contient 3 éléments au maximum, comme indiqué dans l'illustration et en PHP. 

Je sais ce qui suit:

  • Nombre total d'éléments $loop->post_count

  • Numéro d'article $i

  • Nombre d'éléments restants dans la dernière ligne $loop->post_count%3 (je pense)

  • Nombre total de colonnes 12 (12 pourraient être divisées par le nombre d'éléments restants pour déterminer le numéro de colonne à leur donner)

Question:

Comment puis-je utiliser ces données dans PHP ci-dessus pour modifier le numéro de colonne des éléments de la dernière ligne afin qu'ils remplissent la grille (en les centrant)?

13
CyberJunkie

Je pense avoir trouvé la solution en recherchant d'abord à quel élément commence la dernière ligne et en appliquant le numéro de colonne approprié à tous les éléments de cette ligne:

<?php
$max_columns = 3; //columns will arrange to any number (as long as it is evenly divisible by 12)
$column = 12/$max_columns; //column number
$total_items = $loop->post_count;
$remainder = $loop->post_count%$max_columns; //how many items are in the last row
$first_row_item = ($total_items - $remainder); //first item in the last row
?>

<?php $i=0; // counter ?>

<?php while ( have_posts() ) : the_post(); ?> 

    <?php if ($i%$max_columns==0) { // if counter is multiple of 3 ?>
    <div class="row">
    <?php } ?>

    <?php if ($i >= $first_row_item) { //if in last row ?>   
    <div class="col-md-<?php echo 12/$remainder; ?>">
    <?php } else { ?>
    <div class="col-md-<?php echo $column; ?>">
    <?php } ?>
        Content...
    </div>        

    <?php $i++; ?>

    <?php if($i%$max_columns==0) { // if counter is multiple of 3 ?>
    </div>
    <?php } ?>

<?php endwhile; ?>

<?php if($i%$max_columns!=0) { // put closing div if loop is not exactly a multiple of 3 ?>
</div>
<?php } ?>

L'avantage est que n'importe quel nombre (divisible par 12) peut être ajouté à $max_columns et les colonnes appropriées seront appliquées.

2
CyberJunkie

J'ai aimé votre question parce que je travaille sur une situation très similaire. Comme les autres réponses sont un peu plus longues, j'ai décidé de laisser les miennes ici à votre attention. Pour moi, moins vous utilisez de variables, meilleure est la solution.

BootstrapContentArranger.php

<?php
function BootstrapContentArrange($i) {
    $items = $i;                // qnt of items
    $rows = ceil($items/3);     // rows to fill
    $lr = $items%3;             // last row items
    $lrc = $lr;                 // counter to last row

    while ($items > 0) {        // while still have items
        $cell = 0;
        if ($rows > 1) {        // if not last row...
            echo '<div class="row">'.PHP_EOL;
            while ($cell < 3) {     // iterate with 3x4 cols
                echo '<div class="col-md-4">Content</div>'.PHP_EOL;
                $cell++;
            }
            echo "</div>".PHP_EOL;
        $rows--;        // end a row
        } elseif ($rows == 1 && $lr > 0) {      // if last row and still has items
            echo '<div class="row">'.PHP_EOL;
            while ($lrc > 0) {      // iterate over qnt of remaining items
                $lr == 2 ?      // is it two?
                    print('<div class="col-md-6">Content</div>'.PHP_EOL) :  // makes 2x6 row
                    print('<div class="col-md-12">Content</div>'.PHP_EOL); // makes 1x12 row
                $lrc--;
            } 
            echo "</div>".PHP_EOL;
            break;
        } else {        // if round qnt of items (exact multiple of 3)
            echo '<div class="row">'.PHP_EOL;
            while ($cell < 3) {     // iterate as usual
                echo '<div class="col-md-4">Content</div>'.PHP_EOL;
                $cell++;
            }
            echo "</div>".PHP_EOL;
            break;
        }
        $items--;       // decrement items until it's over or it breaks
    }
}

Cas de test

BootstrapContentArrange(3);
BootstrapContentArrange(11);
BootstrapContentArrange(1);
  1. 3 éléments , sorties:

<div class="row">
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
</div>

  1. 11 éléments , sorties:

<div class="row">
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
</div>
<div class="row">
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
</div>
<div class="row">
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
<div class="col-md-4">Content</div>
</div>
<div class="row">
<div class="col-md-6">Content</div>
<div class="col-md-6">Content</div>
</div>

  1. Un seul élément , sorties:

<div class="row">
<div class="col-md-12">Content</div>
</div>

Note : vous pouvez supprimer le PHP_EOL, je l'ai utilisé pour mieux lire la source.

8
Alan Machado

À chaque fois que j'en ai besoin, j'utilise simplement array_chunk pour créer un bloc de tableau approprié pour mes lignes et mes colonnes.

Par exemple, vous avez:

$posts = [['id' => 1], ['id' => 2] ...]

Au lieu de boucler et de calculer s'il faut ajouter une ligne, créez des morceaux de vos publications:

$posts = [['id' => 1], ['id' => 2] ...]

$postChunks = array_chunk($posts, 4); // 4 is used to have 4 items in a row
foreach ($postChunks as $posts) {
    <div class="row">
        foreach ($posts as $post) {
            <div class="col-md-3">
                <?=$post['id'];?>
            </div>     
        }
    </div>
}
6
dpitkevics

Imprimez une ligne à la fois en déterminant la classe html de chaque élément en fonction de son niveau de remplissage. pour 0 col-md-4, pour 1 col-md-12 ... Vous auriez besoin de structures d'assistance. Enfin, imprimez la dernière ligne s'il y a quelque chose dans la mémoire tampon.

/**
 * Prints the row in a grid
 * @param array $posts
 * @param string $class
 */
function printRow($posts, $class) {
    echo '<div class="row">';

    foreach ($posts as $post) {
        echo '<div class="' . $class . '">' . $post . '</div>';
    }

    echo '</div>';
}

$i = 0;
$htmlClasses = ['col-md-4', 'col-md-12', 'col-md-6']; //helper for setting html classes
$buffer = []; //helper array to hold row elements

while (have_posts()) {
    the_post();
    $i++;

    $mod = $i % 3;

    //determine html class
    $htmlClass = $htmlClasses[$mod];

    if ($mod > 0) {
        $buffer[] = $currentPost; //this is the post content
    } else {
        printRow($buffer, $htmlClass);
        $buffer = [];
    }
}

//printing final row if there are elements
if (!empty($buffer)) {
    printRow($buffer, $htmlClass);
}
1
Weltschmerz

Pourquoi n'évaluez-vous pas votre modulo?

$two = false; 
if($i%3 == 2)
{
      <div class="col-md-6">
         Content...
      </div>
      $two = true;  
}

if($i%3 == 1)
{
      if($two)
      {
          <div class="col-md-6">
              Content...
          </div>
      }
      else
      {
          <div class="col-md-12">
              Content...
          </div>              
      }          
}
1
Ralph Melhem
        <?php
            //total products or items you have
            $total_pr = count($products);

            //grid of columns you want 
            $grid = 3;
            $tol_raw = ceil($total_pr / $grid);
            $count =0;
        ?>


        <?php for($i=0;$i<$tol_raw;$i++): ?>
            <?php

            $repeat = $grid;
            if($total_pr<$grid)$repeat = $total_pr;
            $total_pr -= $repeat;

            ?>
            <div class="row">
                <?php for($pr=0;$pr<$repeat;$pr++):?>
                    <?php $product = $products[$count]; ?>
                     <!-- column selection is based onn your grid -->
                    <div class="col-md-4">
                         //do whatever you want to do here
                    </div>
                    <?php $count++; ?>
                <?php endfor; ?>
            </div>
        <?php endfor; ?>
0
Ashok Choudhary