Pregunta

I have this loop:

<?php
$categories = get_terms('my_category');
foreach ( $categories as $category ) :
?>

I want to split the posts into 4 separate div columns so that post titles will be alphabetical vertically like:

a | d | g | j
b | e | h | k
c | f | i | l

How do you get the total post count and divide evenly into fourths?

Edit: Here is the whole loop I'm working with

<?php
$categories = get_terms('archive_category');
foreach ( $categories as $category ) :
?>
<div>
<a data-toggle="collapse" href="#<?php echo $category->slug; ?>"><h3><?php echo $count; ?><?php echo $category->name; ?></h3></a>
<div class="collapse" id="<?php echo $category->slug; ?>">
<?php
$posts = get_posts(array(
'post_type'  => array('custom_post', 'custom_post', 'custom_post'),
'taxonomy' => $category->taxonomy,
'term'  => $category->slug,
'numberposts' => -1,
'orderby'=>'title',
'order'=>'ASC'
));

foreach($posts as $post) :
setup_postdata($post); 
?>

<a href="<?php the_permalink(); ?>"><?php echo get_the_title( $p->ID ); ?></a>

<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
¿Fue útil?

Solución

I had a similar problem couple years ago. Here's a gist I've published, which shows the basic idea how I solved the problem,https://gist.github.com/koskinenaa/4d8461116885c0e64d5ca167ae53434d

Applying the gist to your situation I think the solution could be something like this. I didn't test this so it might require some tweaking, but it should at least point you to the right direction. Of course you need to add relevant css for the ul elements to position them next to each other.

In my example I moved the term and post queries to their own helper functions, but this is just a matter of preference.

function archive_categories( string $tax ) {
  $categories = get_terms($tax);
  return ( $categories && is_array($categories) ) ? $categories: array();
}

function archive_category_posts_query( string $tax, string $term ) {
  $args = array(
    'post_type'   => array('custom_post', 'custom_post', 'custom_post'),
    'numberposts' => -1,
    'orderby'     => 'title',
    'order'       => 'ASC'
    'tax_query' => array(
      array(
          'taxonomy' => $tax,
          'field'    => 'slug',
          'terms'    => $term,
      ),
    ),
  );
  return new WP_Query($args);
}

$categories = archive_categories('archive_category');
$col_count = 4;

foreach ($categories as $category) :
  $category_posts_query = archive_category_posts_query($category->taxonomy, $category->slug);
  $post_count = $category_posts_query->found_posts;
  $posts_per_col = ceil( $post_count / $col_count );
  $i = 0;
  ?>
  <div>
    <a data-toggle="collapse" href="#<?php echo $category->slug; ?>">
      <h3><?php echo $count; ?><?php echo $category->name; ?></h3>
    </a>
    <div class="collapse" id="<?php echo $category->slug; ?>">
      <ul>
        <?php foreach ( $category_posts_query->posts as $category_post ) : 
          if ( $posts_per_col === $i ) {
            $i = 0; 
            echo '</ul><ul>';
          }
        ?>
          <li>
            <a href="<?php esc_url( get_the_permalink( $category_post->ID ) ); ?>"><?php echo esc_html( $category_post->post_title ); ?></a>
          </li>
        <?php $i++; endforeach; ?>
      </ul>
    </div> <!-- collapse -->
  </div> <!-- collapse wrapper -->
<?php endforeach;

EDIT 5.2.2020

Categories into columns? You mean something like this?

$categories = archive_categories('archive_category');
$category_count = count( $categories );
$col_count = 3;
$categories_per_col = $category_count > $col_count ? ceil( $category_count / $col_count ) : 1;
$column_index = 1;

echo '<div class="row">';
foreach ($categories as $category) :
  $category_posts_query = archive_category_posts_query($category->taxonomy, $category->slug);
  if ( $column_index > $col_count ) {
    $column_index = 1;
    echo '</div><div class="row">';
  }
  $classes = array(
    'column_1_of_' . $col_count,
    'column-' . $column_index,
  );
  ?>
  <div class="<?php echo implode( ' ', $classes ); ?>">
    <a data-toggle="collapse" href="#<?php echo $category->slug; ?>">
      <h3><?php echo $category->count . ' ' . $category->name; ?></h3>
    </a>
    <div class="collapse" id="<?php echo $category->slug; ?>">
      <ul>
        <?php foreach ( $category_posts_query->posts as $category_post ) : ?>
          <li>
            <a href="<?php esc_url( get_the_permalink( $category_post->ID ) ); ?>"><?php echo esc_html( $category_post->post_title ); ?></a>
          </li>
        <?php endforeach; ?>
      </ul>
    </div> <!-- collapse -->
  </div> <!-- collapse wrapper -->
<?php $column_index++; endforeach;
echo '</div>';

Otros consejos

The answer is CSS and you've got a couple options!

<?php $categories = get_terms('my_category'); ?>

<ul>
    <?php foreach ( $categories as $index => $category ): ?>
        <li>
            <a href="<?php the_permalink(); ?>"><?php echo get_the_title( $p->ID ); ?></a>
        </li>
    <?php endforeach; ?>
</ul>

You can use Flexbox...

ul {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 306px;
  width: 200px;
}
li {
  width: 100px;
  height: 100px;
}

OR, you can use Text Columns

ul {
  column-count: 2;
  column-gap: 0;
}
li {
  display: inline-block;
}

Here's a great resource with further details and codepens.

Licenciado bajo: CC-BY-SA con atribución
scroll top