0

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 :

  1. Empty letters are not displayed.
  2. I can't find a way to wrap my groups inside group_letter div.
double-beep
  • 5,031
  • 17
  • 33
  • 41
mmdwc
  • 1,095
  • 6
  • 27
  • 53

2 Answers2

3

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

Deepti chipdey
  • 1,157
  • 9
  • 19
  • thanks for your reply. so I have to copy first code inside function.php, and the other on my page ? I can't find how to echo the result.. can you help me with that ? – mmdwc Jan 20 '18 at 17:53
  • echo which result, you need to copy 1st code into function and second into your pag – Deepti chipdey Jan 20 '18 at 17:54
  • using your code I get all my posts behind all letters. A: all my posts B: all mys posts C: all my posts... what is "search_prod_title" refering to ? – mmdwc Jan 20 '18 at 18:02
  • search_prod_title is the custom parameter you are passing to the query, please use the edited one, just made the changes to filter part – Deepti chipdey Jan 20 '18 at 18:07
  • now I only get the alphabet, without any reference to post. $title is not defiened, could it be the issue ? – mmdwc Jan 20 '18 at 18:10
  • can you post what result you get – Deepti chipdey Jan 20 '18 at 18:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163553/discussion-between-mmdwc-and-deepti-chipdey). – mmdwc Jan 20 '18 at 18:12
0

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 
}
?>
Khushboo
  • 1,819
  • 1
  • 11
  • 17
  • @Kushboo thanks for your reply. I don't understand which while loop I'm supposed to add inside the code. When using your code, I get the alphabet repeated for each post... – mmdwc Jan 20 '18 at 17:54
  • yes but how can I get $title outside of my while loop ? – mmdwc Jan 20 '18 at 18:04