Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using PHP loop to add Bootstrap rows and proper column numbers to elements

I'm trying to create the following front-end using a PHP loop and Twitter Bootstrap's 12 column grid system:

enter image description here

The HTML output is:

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

In PHP (WordPress) I'm wrapping every 3 items in a .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 } ?>


The Problem:

I don't know how to add the appropriate column number to the items in the last row so that they fill the 12 column grid.

For example, in my illustration above each item in the last row has col-6 (expands 6 columns) filling the 12 grid system. As another example, if there was 1 item in the last row it should have col-12.

Note: each row has 3 items at most as shown in the illustration and in PHP.

I know the following:

  • Total number of items $loop->post_count

  • Item number $i

  • Number of remainder items in the last row $loop->post_count%3 (I think)

  • Total number of columns 12 (12 could be divided by the number of remainder items to figure out the column number to give them)

Question:

How can I use that data in the PHP above to change the column number of the items in the last row so that they will fill the 12 grid (making them them centered)?

like image 442
CyberJunkie Avatar asked Sep 24 '15 16:09

CyberJunkie


3 Answers

Everytime I need to to this, I just use array_chunk to build a proper array chunk for my rows and columns.

For example You have:

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

Instead of looping and calculating whether to add row, make chunks of your posts:

$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>
}
like image 26
dpitkevics Avatar answered Nov 19 '22 09:11

dpitkevics


I liked your question because I'm working on a very similar situation. Since other answers are a bit longer, I decided to leave mine here for your consideration. For me, the less variables you use, the best the solution is.

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

Test Cases

BootstrapContentArrange(3);
BootstrapContentArrange(11);
BootstrapContentArrange(1);
  1. 3 items, outputs:

<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 items, outputs:

<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. A single item, outputs:

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

Note: you can remove the PHP_EOL, I used it to read the source better.

like image 153
al'ein Avatar answered Nov 19 '22 08:11

al'ein


I think I found the solution by first finding at which item the last row starts and applying the appropriate column number to all the items in that row:

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

The advantage is that any number (evenly divisible by 12) can be added to $max_columns and it will apply the proper columns.

like image 3
CyberJunkie Avatar answered Nov 19 '22 07:11

CyberJunkie