1

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?

  • Do you want a pagination for this page ? – Elex Dec 21 '17 at 6:31
  • no just a simple listing with alphabetical letter as headings and posts as hyperlinks – TravelWhere Dec 21 '17 at 6:37
4

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>';
    }
}
  • There's a problem with that code. It's not grouping all the posts under the alphabet letters but instead it makes a bunch of duplicates of the alphabet letters – TravelWhere Dec 21 '17 at 6:47
  • Wooops ! I make $letter re-declaration in the else instead of if ! I update :) – Elex Dec 21 '17 at 6:59
  • You'll have to close the </ul></div> after the loop – Elex Dec 21 '17 at 7:02
1

Try this function, I use it to create linkable A-Z index

function nstrm_sd_do_az_loop() {

    global $page_slug;

    $paged    = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    $your_query = new WP_Query( array( ... ) );
    $current = '';

    $nav     = '<div class="az-navigation"><ul>';
    $letter  = get_query_var( 'letter' );

    if ( $your_query->have_posts() ):
        while ( $your_query->have_posts() ): $your_query->the_post();
            global $post;

            $firstletter = strtoupper( substr( get_the_title(), 0, 1 ) );

            if ( $firstletter != $current ) {
                if ( $letter == $firstletter ) {
                    $class = ' class="current"';
                } else {
                    $class = '';
                }
                $nav     .= '<li' . $class . '><a href="/' . $page_slug . '/' . $firstletter . '">' . $firstletter . '</a></li>';
                $current = $firstletter;
            }
        endwhile;

    endif;

    echo $nav . '<li><a href="/' . $page_slug . '">' . __( 'All', 'your-text-domain' ) . '</a></li></ul></div>';
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.