Anna Gabrielyan
Anna Gabrielyan

Reputation: 2170

Wordpress posts ordering by alphabetical for each letter

I need to display all posts ordering by post_title ACS, like this:

A
  animal
  angel
  apple
C
  cat
  cinema
  crime
F
  friday
  fire
K
  kill
  king
  .................

and so on

So if there is no posts which titles are starting with G, the G will not be shown or displayed as letter separator like above. Can anybody help?

Upvotes: 1

Views: 7013

Answers (4)

Wilhelm Hjelm
Wilhelm Hjelm

Reputation: 26

For any internationalization, like for me in Swedish with Å, Ä and Ö letters. Change substr() to mb_substr() to avoid getting unwanted characters outputted.

Upvotes: 0

BM RAFIQ
BM RAFIQ

Reputation: 315

It's perfect work for me.

<?php 
$posts = get_posts(
    array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    )
);
$alphas = range('A', 'Z');
$letter_keyed_posts = array();
if ( $posts ) {
    foreach ( $posts as $post ) {
        $first_letter = strtoupper( substr( $post->post_title, 0, 1 ) );

        if ( ! array_key_exists( $first_letter, $letter_keyed_posts ) ) {

            $letter_keyed_posts[ $first_letter ] = array();
        }

         $letter_keyed_posts[ $first_letter ][] = $post;
    }

}
foreach ($letter_keyed_posts as $key => $value) {
    ?>
    <table class="table">
      <caption><h1 class="text-left">List of --> <?php echo $key; ?></h1></caption>
      <thead>
        <tr>
          <th scope="col">#</th>
          <th scope="col">Title</th>
        </tr>
      </thead>
      <tbody>
        <?php foreach ($value as $val) {
            ?>
            <tr>
              <th scope="row"><?php echo $val->ID; ?></th>
              <td><a href="<?php echo get_permalink( $val->ID ); ?>"><?php echo $val->post_title; ?></a></td>
            </tr>
            <?php
        } ?>
      </tbody>
    </table>
    <?php
}
?>

Result: Output

Thanks [Nathan Dawson, Ameer Hamza]

Upvotes: 1

Nathan Dawson
Nathan Dawson

Reputation: 19308

I'd run a query to get all the posts ordered by post title as you usually would using get_posts. I would then loop through these and use substr to get the first letter of each post title. Make it uppercase. Create a new array. Check if the letter exists as a key in the array (array_key_exists). Add the key if needed and put the post inside. Following this process gives you an easy to manage array sorted by letter. Is there an easier way? Probably, but this will work.

Here is the code to achieve it:

<?php

$posts = get_posts(
    array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    )
);

$letter_keyed_posts = array();

if ( $posts ) {
    foreach ( $posts as $post ) {
        $first_letter = strtoupper( substr( $post->post_title, 0, 1 ) );

        if ( ! array_key_exists( $first_letter, $letter_keyed_posts ) ) {
            $letter_keyed_posts[ $first_letter ] = array();
        }

        $letter_keyed_posts[ $first_letter ][] = $post;
    }
}

Use $letter_keyed_posts to output the content in the format you need.

Upvotes: 5

YKKY
YKKY

Reputation: 605

While Nathan Dawson's code looks more accurate than the following snippet, I couldn't force his code to work on my site.

I'm using this code, it is ready to use and works for me:

<?php
$args = array( 'cat' => YOUR_CATEGORY_ID, 'posts_per_page' => -1, 'order'=> 'ASC', 'orderby' => 'title' );
query_posts($args);
if (have_posts()) {
    $current_letter = '';
    while (have_posts()) {
        the_post();
        $title_letter = strtoupper(substr($post->post_title,0,1));
        if ($title_letter != $current_letter) {
            echo "<h3>$title_letter</h3>";
            $current_letter = $title_letter;
        }
?>
<div><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></div>
<?php
    }
}
?>

Upvotes: 2

Related Questions