How to create A-Z index listing for custom post types?

I want to create an A to Z index listing of all posts from a specific custom post type.
This is the code so far:

<?php
/**
 * The Template for displaying archive series.
 *
 * Theme: Default
 */

get_header(); ?>

        <div id="content">

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array('paged' => $paged,'posts_per_page' => -1,'post_type' => 'series_type','post_status' => 'publish','orderby' => 'title','order' => 'asc');
$fruits = new WP_Query($args);
if($fruits->have_posts()){
  $current_first_letter="";
  $t = array();
  $s = array();
  while($fruits->have_posts()){
    $fruits->the_post();
    $title = get_the_title();
    if(is_string($title)){
        $first_letter = strtoupper($title[0]); 
        if($first_letter != $current_first_letter){
            $t[] = $first_letter;
            $current_first_letter = $first_letter;
        }
    }
    $s[$first_letter][] = get_the_title();
  }
}

$t = array_unique($t);
$tc = count($t);
$sc = count($s);
for($i=0; $i<$tc; $i++){
    ?>
    <div>
        <h4><?php echo $t[$i]; ?></h4>
        <ul>
        <?php
        foreach($s as $key => $value){
            if($key == $t[$i]){
                $vc = count($value);
                for($j=0; $j<$vc; $j++){
        ?>
            <li><?php echo $value[$j]; ?></li>
        <?php
                }
            }
        }
        ?>
        </ul>
    </div>
    <?php
}
if($fruits->max_num_pages > 1){ ?>
  <nav class="prev-next-posts">
    <div class="prev-posts-link">
      <?php echo get_next_posts_link( 'Older Entries', $fruits->max_num_pages ); ?>
    </div>
    <div class="next-posts-link">
      <?php echo get_previous_posts_link( 'Newer Entries' ); ?>
    </div>
  </nav>
<?php } ?>
<?php wp_reset_postdata(); ?>



        </div><!-- #content -->

<?php get_footer(); ?>

The problem is I don’t know how to make all of them as hyperlinks instead of raw text. Can anyone help me fix the code?

2 Answers
2

Ok, you just have to make a loop with first letter check. WordPress query will handle the post_title ASC order.

EDIT : I use get_permalink() within the loop to get URL (https://developer.wordpress.org/reference/functions/get_permalink/)

$series = new WP_Query(array(
    'posts_per_page'        => -1,
    'post_type'             => 'series_type',
    'orderby'               => 'title',
    'order'                 => 'asc'
));
if($series->have_posts())
{
    $letter="";
    while($series->have_posts())
    {
        $series->the_post();

        // Check the current letter is the same that the first of the title
        if($letter != strtoupper(get_the_title()[0]))
        {
            echo ($letter != '') ? '</ul></div>' : '';
            $letter = strtoupper(get_the_title()[0]);
            echo '<div><ul><h4>'.strtoupper(get_the_title()[0]).'</h4>';            
        }

        echo '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';
    }
}

Leave a Comment