I have a list of posts on my website, what I'm trying to do is to wrap them alphabetically from A-Z by title to get a glossary like this:
A.
Apple
B.
Banana
C.
Carotts
D.
E.
F.
G.
Grenada
and so on untill letter z.
I want the letter to be displayed even if there's no post.
and i want to wrap results inside this structure :
<div class="group_letter">
<div class="letter">A</div>
<div class="post">Apple</div>
</div>
<div class="group_letter">
<div class="letter">B</div>
<div class="post">Banana</div>
</div>
here is what I've got so far :
<?php
$letter=' ';
query_posts( array ( 'post_type' => 'auteurs', 'orderby' => 'title', 'order' => 'ASC' ) );
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$title=get_the_title();
$initial=strtoupper(substr($title,0,1));
if($initial!=$letter) {
echo "<div>$initial</div>";
$letter=$initial;
}
echo "<div class='post'>" . $title. "</div>";
?>
<?php endwhile; endif; wp_reset_query(); ?>
here is the result :
<div class='letter'>A</div>
<div class='post'>Apple</div>
<div class='letter'>B</div>
<div class='post'>Banana</div>
<div class='letter'>C</div>
<div class='post'>carotts</div>
<div class='letter'>G</div>
<div class='post'>Grenanda</div>
I have 2 problems :
group_letter
div
.</div>
Sorry, postin TV from phone, so may be not displaying properly
Firstly, you have to create an array of all alphabets.
$alph = array('A', 'B', 'C',.... 'Z');
<
?php
$title=get_the_title();
foreach($alph as $key) {
// add while loop here
initial=strtoupper(substr($title,0,1));
if($initial!=$key) {
echo '<div class="group_letter">';
echo "<div>$key</div>";
}else{
echo "<div class='post'>" . $title. "</div>";
}
echo "</div>";
// end while loop here
}
?>
I would solve this with a filter on WP_Query. One that detects an extra query variable. Add this into your functions.php
add_filter( 'posts_where', 'title_filter', 10, 2 );
function title_filter( $where, &$wp_query )
{
global $wpdb;
if ( $search_term = $wp_query->get( 'search_prod_title' ) ) {
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( $wpdb->esc_like( $search_term ) ) . '%\'';
}
return $where;
}
Once you have filter in place you can use wp_query and array range of alphabet
foreach (range('A', 'Z') as $char) {
echo '<div class="group_letter">';
echo '<div class="letter">'.$char.'</div>';
$args = array(
'post_type' => 'auteurs',
'posts_per_page' => -1,
'search_prod_title' => $char,
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC'
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$title=get_the_title();
$initial=strtoupper(substr($title,0,1));
if($initial==$char) {
echo "<div class='post'>" . $title. "</div>";
}
endwhile;
wp_reset_postdata();
endif;
echo '</div>';
}
remove_filter( 'posts_where', 'title_filter', 10, 2 );
I have not tested this code, I hope it should work. You can get more information about Wp_query https://codex.wordpress.org/Class_Reference/WP_Query