Reputation: 2170
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
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
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
}
?>
Thanks [Nathan Dawson, Ameer Hamza]
Upvotes: 1
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
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