0
votes

I know this question has been asked before. I checked through multiple answers on this site, for example:

Wordpress loop with different bootstrap columns

https://wordpress.stackexchange.com/questions/222278/how-to-separate-posts-loop-in-to-two-columns/222281

... but I cannot work out how to integrate answers with my code (assuming that is possible).

I want to display a list of Categories and their related posts on a page.

The code I'm using works fine BUT displays the results in a single column down the page:

enter image description here

I want to split the display into 2 columns, like in the image below, if possible:

enter image description here

The code I'm using (currently placed in a new page template) is as follows:

<?php

/*
 * Template Name: Alphabetical List
*/

get_header(); 

// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
foreach ( $categories as $category ) {
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
  'cat' => $category->term_id,
  'order' => 'ASC',
  'orderby' => 'title',
);

// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>

<p><a href="<?php the_permalink();?>"><?php the_title(); ?></a></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
} // End foreach

get_footer(); 
?>

Wondering if anyone can help me to get this code to display loop results in 2 columns.

Many thanks.

UPDATE TO QUESTION

Karl, thanks for your answer. Your script works, but with a small problem:

The Categories/Related Posts display in 2 columns but a 'gap/space' appears in the middle of the display of data (see image below):

enter image description here

I added to your code slightly so I could display a custom field I inserted into each post. I'm not sure if this has caused the problem.

Altered code (changes are immediately after $query->the_post();):

<?php

/*
* Template Name: Alphabetical List
*/
get_header();
?>

<div style="height:100px"></div>

<?php
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
echo "<div class='new-column'>";
$counter = 0;
foreach ( $categories as $category ) {
if($counter % 4 == 0 && $counter !=0){
   echo "<div class='new-column'>";
}
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();

$customfieldvalue = get_post_meta($post->ID, "PDF", true);

?>
<p><a href="<?php echo $customfieldvalue; ?>" target="_blank"><?php 
the_title(); ?></a></p>

<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
$counter++;
if($counter % 4 == 0){
echo "</div>";
}
} // End foreach
if($counter % 4 != 0){
echo "</div>";
}
get_footer(); 
?>
2

2 Answers

1
votes

I've used bootstrap classes (row, col-6). Checked the size of categories array and used 2 variables - one as a counter and the other one to check if the column is first or second.

<?php

/*
 * Template Name: Alphabetical List
*/

get_header(); 

// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');

//get size of category
$catSize = sizeof($categories);
$j = 1;
$n = 1;
// Loop through categories
foreach ( $categories as $category ) {
    if($n == 1){
        echo '<div class="row">';
    }
    echo'<div class="col-6">';
        // Display category name
        echo '<h2 class="post-title">' . $category->name . '</h2>';
        echo '<div class="post-list">';
        // WP_Query arguments
        $args = array(
          'cat' => $category->term_id,
          'order' => 'ASC',
          'orderby' => 'title',
        );

        // The Query
        $query = new WP_Query( $args );
        // The Loop
        if ( $query->have_posts() ) {
            while ( $query->have_posts() ) {
            $query->the_post();
            ?>

            <p><a href="<?php the_permalink();?>"><?php the_title(); ?></a></p>
            <?php
            } // End while
        } // End if
    echo '</div></div>';

        if($n == 1){
            if($j == $catSize){
                echo '<div class="col-6"></div>
                </div>';
            }
            else{
                $n = 2;
            }
        }
        else{
            echo '</div>';
            $n =1;
        }
        $j++;
    }

// Restore original Post Data
wp_reset_postdata();
} // End foreach

get_footer(); 
?>
0
votes

Try this, I used a modulos operator "%" to group loops into 4, it will create new column every 4 loops. MAKE SURE YOU ADD CSS TO class new-column to arrange it like columns.

<?php
/*
* Template Name: Alphabetical List
*/
get_header();
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
echo "<div class='new-column'">;
$counter = 0;
foreach ( $categories as $category ) {
   if($counter % 4 == 0 && $counter !=0){
       echo "<div class='new-column'">;
    }
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
    'cat' => $category->term_id,
    'order' => 'ASC',
    'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><a href="<?php the_permalink();?>"><?php the_title(); ?></a></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
$counter++;
if($counter % 4 == 0){
  echo "</div>";
}
} // End foreach
if($counter % 4 != 0){
 echo "</div>";`enter code here`
}
get_footer(); 
?>