php - Getting an alphabetic post list with two letters onclick on letter

admin2025-06-05  3

I have a website in Wordpress and a page with a list with letters like this:

A B C D E F G H I ...

This shows me all posts with the letter A for instance. That's nice, but I want it to make it easier for my users, so I want to get Ab and all of the posts starting with Ab if I click on A, beneath this list. Another example: I want to get Dc and all of the posts starting with the letters Dc if I click on D. I know that this is possible by making 26 pages containing the letters and the functions, but there must be a simpler way to do this.

Besides, I don't want 26 pages for such a simple thing. It would affect the SEO.

Can someone help me out with this?

I have a website in Wordpress and a page with a list with letters like this:

A B C D E F G H I ...

This shows me all posts with the letter A for instance. That's nice, but I want it to make it easier for my users, so I want to get Ab and all of the posts starting with Ab if I click on A, beneath this list. Another example: I want to get Dc and all of the posts starting with the letters Dc if I click on D. I know that this is possible by making 26 pages containing the letters and the functions, but there must be a simpler way to do this.

Besides, I don't want 26 pages for such a simple thing. It would affect the SEO.

Can someone help me out with this?

Share Improve this question asked Jul 29, 2013 at 21:19 JohanJohan 3091 gold badge10 silver badges20 bronze badges 3
  • It isn't entirely clear how you imagine this to work, but is sounds like you are asking for Javascript to create additional menus. – s_ha_dum Commented Jul 29, 2013 at 21:38
  • Yes, I think I have to use jQuery, which is no problem at all, but I am wondering if there is another way to fetch those results instead of making pages? So the posts, starting with Dc or Ab, should be fetched, which I can by adding pages with my function, but isn't that overhead? Than I have to make 26 pages, which sounds stupid to me... – Johan Commented Jul 29, 2013 at 21:39
  • How does this sound like: giving each post name an ID and then with jQuery, replacing the list I have with those posts and showing them if someone clicks on the specific anchor... I know that jQuery has contains, but can you select the first two letters too? – Johan Commented Jul 29, 2013 at 21:45
Add a comment  | 

1 Answer 1

Reset to default 1

Maybe I've not understand your question, in this case sorry, my english is far from perfect.

I understand that you have a page template that show the letters list and when you click a letter, the same page show a list of posts where 'post_title' start with this letter.

Now you want that when you are showing that list, is possible to filter posts using 2 letters instead of one, where the first letter is the one choosen before.

Is this right? If so, this should works:

<?php
/**
 * Template Name: Capital Template
*/

get_header();

the_post();
$page_link = get_permalink();

$letter = isset($_GET['letter']) ? $_GET['letter'] : null;
// limit the 'letter' param to 2 chars
if ( $letter && strlen($_GET['letter'])>2 ) $letter = substr($letter, 0, 2);
?>

<?php
// PAGE FILTERS PART
$letters = array('A','B','C','D','E','F','G','H','I','J','K','L','M',
                 'N', 'O','P','Q','R','S','T','U','V','W','X','W','Z');
if ( ! $letter ) {
  // adjust the query args to fit your needs
  $args = array('posts_per_page' => 50, 'orderby' => 'post_title', 'order' => 'ASC');
  $posts = get_posts($args);
} else {
  global $wpdb;
  // adjust the query to fit your needs  
  $posts = $wpdb->get_results( $wpdb->prepare(
    "SELECT * FROM $wpdb->posts WHERE
    post_type = 'post' AND post_status = 'publish' AND
    post_title LIKE %s ORDER BY post_title ASC",
    $letter . '%'
  ) );
}
echo '<ul>';
foreach ( $letters as $l) {
  $param = $letter ? $letter.$l : $l;
  printf('<li><a href="%s?letter=%s">%s</a></li>',$page_link, $param, $param);
}
echo '</ul>';
if ($letter) {
  printf('<p id="#filter-remover"><a href="%s?letter=%s">%s</a>',
    $page_link, $letter,
    __('Back to capital letter &quot;' . $letter . '&quot; filter')
  );
  printf(', <a href="%s">%s</a><p>',
    $page_link,
    __('or remove capital letter filter at all.')
  );
}
?>

<?php
// PAGE CONTENT PART
global $post;
if ( ! empty($posts) ) :
  foreach ($posts as $post) {
    setup_postdata($post);
?>

<?php /*  YOUR LOOP CODE HERE */ ?>

<p><?php the_title(); ?></p>

<?php
}
else :
  echo '<p>';
  _e('Sorry, no posts match your criteria.');
  if ( $letter ) {
    printf('<br /><a href="%s">%s</a>',
  $page_link,
  __('Try to remove the capital letter filter.')
);
  }
  echo '</p>';
endif;
wp_reset_postdata();


get_footer();

Edit: jquery trick

One fault of my code above is that the filter shows all capital letter(s), even if there is no posts for that: if the filter 'A' not have post, also 'AB', 'AC' and so on will not have posts so, why show them? Using php you can loop posts and put only filter that have a chance to get some results, but this mean looping 2 times. I think there is a better solution: jQuery.

Note: this works only if you the query shows all posts, or better, all the posts you want to filter out (i.e. no LIMIT clause in sql query)

First of all, in 'FILTER' part, change the foreach loop in this:

echo '<ul class="letter-filters">';
foreach ( $letters as $l) {
  $param = $letter ? $letter.$l : $l;
  printf('<li><a href="%s?letter=%s" class="letter-filter">%s</a></li>',
    $page_link, $param, $param
  );
}
echo '</ul>';

Then in the loop code part, use something like this:

<?php
echo '<div id="posts-container" data-letter="' . $letter. '">';
if ( ! empty($posts) ) :
  foreach ($posts as $post) {
    setup_postdata($post);
   /*  YOUR LOOP CODE */
   $datacapital = $letter ? strtoupper( substr(get_the_title(), 0, strlen($letter)+1 ) ) : '';
?>
  <div class="post" id="post-<?php the_ID()?>" data-capital="<?php echo $datacapital; ?>">
  <p><?php the_title(); ?></p>
 </div>

 ...

 endif;
 echo '</div>';
 wp_reset_postdata();

Finally, the jQuery code:

<script>
// please, do not use jquery like so,
// register and enqueue it like every WP developer should do :)
// this is for semplicity of answer

jQuery().ready(function($) {
  if ( $('#posts-container').data('letter') != '' ) {
    var oldcapital = null;
    $('ul.letter-filters li').hide();
    $('.post').each(function() {
      var capital = $(this).data('capital');
      if ( ! oldcapital || (oldcapital != capital) ) {
        oldcapital = capital;
        $('a.letter-filter').each(function() {
           if ( $(this).text() == capital ) $(this).parent().show(); 
        });
        }
      });
    }
  });
</script>

Please note I'm not a js/jquery developer, maybe there is a more elegant/performant way to to do the same thing...

Of course this is not the full code of the page, just the relevant part.

Hope it helps.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749093776a316310.html

最新回复(0)