List posts based on first letter of posts

WordPress Development Asked by Shahinul Islam on September 13, 2020

I want add a pagination

How can I do this on both loop.php and search.php. I want show alphabetic index to search only posts with starting letter = [E] for example. Right now, if I search with E it search for any match, title+content+part of title.

[A] [B] [C] [D] [E] [F] [G] [H] [I] [J] [K] [L] [M] [N] [O] [P] …….[Z]

Easy Post Title – By Admin on 2013

post content….bla bla bla…

Example Post – Another Test – By Admin on 2013

post content….bla bla bla…

[A] [B] [C] [D] [E] [F] [G] [H] [I] [J] [K] [L] [M] [N] [O] [P] …….[Z]

2 Answers

This is a nuts-and-bolts way of getting at this problem. This modifies the SQL query itself, but it's pretty much a 1 liner. I'm sure there are other ways, but this method is not very invasive to the query building process as it only mods the SQL at the end. Note I realize this method could be usurped by the syntax of a query builder at some point.

First hook into the filter:

add_filter('posts_request', 'YP_company_name_where', 10, 2);

Then let's modify the exact portion of the SQL request, note that we're looking for the condition where the search / filter being run is for a First Letter and in our particular case, it is if the $input contains 'short-company-name'. Tune your conditional to your liking.

function YP_company_name_where($input,  &$wp_query) {

    if (stripos($input, 'short-company-name') !== FALSE) {

        $x = preg_replace("/wp_postmeta.meta_keys=s'short-company-name'sANDsCAST(wp_postmeta.meta_valuesASsCHAR)sLIKEs'%/",
                          "wp_postmeta.meta_key = 'short-company-name' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '", $input, 1);
        return $x;

    return $input;

Note that if this is not exactly like your particular query, just dump out the $input, find the errant one, and tune the SQL at this stage so that your query is looking for "... LIKE [letter]%" against the column you need. All the "replace" is really doing is exactly locating the particular query and removing the "LIKE %[letter]%" and replacing it with "LIKE [letter]%".

I did it this way because I was using a front end plugin for filtering / querying posts already and could not easily use a stand-alone SQL query to just find a first letter. I was dealing with a multi-parameter, user driven, and / or logic filtering query situation and it was easier to modify the end result for this one case.

Answered by BVRoc on September 13, 2020

This is the code I get from here, but I don't remember the exact page, and this is my working page of letter B on my website (using the same code as you see below)

Template Name: Locali per lettera

A WordPress template to list page titles by first letter.

You should modify the CSS to suit your theme and place it in its proper file.
Be sure to set the $posts_per_row and $posts_per_page variables.

$posts_per_row = 3;
$posts_per_page = -1;
$pageURL = 'http';
$post_type = 'post';

if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
} else {

$letters = $wpdb->get_col(
"SELECT DISTINCT LEFT(post_title,1) AS first_letter FROM $wpdb->posts
WHERE post_type = '$post_type' AND post_status = 'publish'
ORDER BY first_letter ASC"

$first_letter = ($_GET['first_letter']) ? $_GET['first_letter'] : $letters[0];

<?php get_header(); ?>

 <style type="text/css">
 .letter-group { width: 100%; border-top: 1px solid #444; }
  .navigation { text-align: center; padding:5px; margin: 0 10px;} 
 .letter { display:inline; color:#DDD;text-align: center; padding: 2px; border-top: 1px solid #48465B; border-left: 1px solid #48465B; background: #18181C; margin: 0 1px;} 
 .letter a{ color:#DDD;} 
 .letter-cell { width: 5%; color:red; font-weight:bold; height: 2em; text-align: center; padding-top: 8px; margin-bottom: 8px; border-top: 1px solid #48465B; background: #18181C; float: left; }
 .row-cells { width: 94%; float: right;  }
 .title-cell { width: 33%;  float: left; overflow: hidden; margin-bottom: 8px; }
.alignleft {
    float: left;
    margin-left: 25px;
.alignright {
    float: right;
    margin-right: 25px;
 .clear { clear: both; }
 div#a-z .padder {
    border-right: none;
    margin-right: none;
    padding: 20px 40px;

<div id="main-background">

   <div id="main-column">
    <br />
      <h2><?php the_title(); ?></h2>

      <div class="margin-top"></div>

      <div id="a-z">

         $mam_global_where = " AND LEFT(post_title,1) = '$first_letter' ";
         $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
         $args = array (
            'posts_per_page' => $posts_per_page,
            'post_type' => $post_type,
            'orderby' => 'title',
            'order' => 'ASC',
            'paged' => $paged,
            'caller_get_posts' => 1
         $mam_global_where = '';  // Turn off filter
         if ( have_posts() ) {
            $in_this_row = 0;
            while ( have_posts() ) {
               $first_letter = strtoupper(substr(apply_filters('the_title',$post->post_title),0,1));
               if ($first_letter != $curr_letter) {
                  if (++$post_count > 1) {
                  $curr_letter = $first_letter;
               if (++$in_this_row > $posts_per_row) {
                  ++$in_this_row;  // Account for this first post
               } ?>
               <div class="title-cell"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"> <?php the_title(); ?></a></div>
            <?php }
            <div class="navigation">
            foreach ($letters as $letter) {
               $url = add_query_arg('first_letter',$letter,$pageURL);
               echo "<div class='letter'>";
               echo "<a href='$url' title='Starting letter $letter' > $letter </a>";
               echo "</div>";

         <?php } else {
            echo "<h2>Sorry, no posts were found!</h2>";

      </div><!-- End id='a-z' -->
   </div><!-- End class='margin-top --> 
</div><!-- End id='rightcolumn' -->

function end_prev_letter() {
   echo "</div><!-- End of letter-group -->n";
   echo "<div class='clear'></div>n";
function start_new_letter($letter) {
   echo "<div class='letter-group'>n";
   echo "t<div class='letter-cell'>$letter</div>n";
function end_prev_row() {
   echo "t</div><!-- End row-cells -->n";
function start_new_row() {
   global $in_this_row;
   $in_this_row = 0;
   echo "t<div class='row-cells'>n";


Answered by Daniel Foltynek on September 13, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP