Usually, in a WordPress blog or website, we do not need to list posts or pages by alphabetical order but with more and more people using the Custom Post Types and adding topics and sections in their website which do need alphabetical listing such as a if you have created Custom Post Type for Movies, Models, Designers, Celebs or Books, showing these by alphabetical order on their separate pages for each letter becomes very attractive and natural requirement.
First of all, we need to create alphabet navigation on top of page for the posts list to display on separate pages for each letter. Add following function in the theme functions.php file:
function get_alphabet_nav($sef=''){
$url_array = explode('/', $_SERVER['REQUEST_URI']);
$folder = $url_array[sizeof($url_array)-2];
$base='http://'.$_SERVER['HTTP_HOST'].'/';
$sef = $sef.'/';
$path= $_SERVER['REQUEST_URI'];
for ($i=65; $i<=90; $i++) {
$x = chr($i);
$nav .= ''.$x.''."\n";
}
return $nav;
}
Now create a new file by copying the page.php file available in your theme folder and name it as page-book.php (assuming your CPT is book) add following code at top of page before the while loop:
echo '
Custom Post Type Alphabetical Listing
‘; //replace listing-page-slug-here with the one you have used for creating page. //such as books-listing or designers-listing
On top of this page-book.php, define the name for the template like:
/* Template Name: Custom Post Type (Books) Listing Page */
In the Books Listing template, find the following loop:
if ( have_posts() ) while ( have_posts() ) : the_post();
Add the following line above the loop:
query_posts(array('post_type'=>'book')); /*replace 'book' with your custom post type*/
The Above code will instruct WordPress to find all posts that have the ‘book’ type and loop through them.
Now you have created your Custom Page Template to list books, but you also need to to create “Books” page that will show listing of book type posts using this template you just created. In order to create Page, log in to the WordPress admin panel, create a new page with the title of “Books Listing by Alphabets”, and then select the “Books Listing Template” for the Template page attribute.
You also need to create sub pages for each letter choosing the Books Listing page as parent so that all letter pages become sub pages and their slugs show it. Make sure that your sub page slug is just the letter and it will look like this /books-listing/a/, /books-listing/b/ and so on. You will need to create sub-pages for all 26 letters. Please note that you choose Books Listing Template from the Page Attributes.
To list the Custom Post types for books starting with any letter, you need to check the url of the page and query the WordPress database using REGEXP like this:
Sorry, no profiles matched your criteria.
css styles for alphaList id:
#alphaList { width:600px; overflow:hidden;
font-size:12px;
clear:both; border-top:1px solid #E3E3E3;
border-bottom:3px solid #000000;
}
#alphaList .first { border:0; }
#alphaList a { display:block; line-height:22px;
width:22px; float:left; text-align:center;
border-left:1px solid #E3E3E3
}
#alphaList a:hover { background:#f1f1f1;
text-decoration:none; color:black
}
Summary of logic and process what you need to do
1. Create a Listing page by copying the page.php in your WordPress theme folder and name it ‘Listing Template’.
2. Create a Page ‘Books Listing by Alphabets’ with a slug ‘/books/’ and select the ‘Listing Template’ you just created from Page Attributes and not the default template.
3. Go on to create few more pages for more letters whose slugs will look like this ‘/books/a/’, ‘/books/b/’ and so on to ‘/books/z/’. Make sure you create all these letter pages as child pages of the Listing page you just created in second step using the same ‘Listing Template’ of step 1. You will have to create sub pages for all 26 letters.
3. Now generate the alphabetical navigation using the function above. That code generates links for each letter page. These links will point to the pages you created in the third step above.
4. Now all you have to do is to catch the letter from the slug and pass it on to the query. I have written all that code already so you just have to copy that code and place inside your template.
5. Just make sure you change the example custom post type ‘book’ to your actual custom post type. I have commented it in the code wherever you need to do this.
6. Also make sure that your custom post type slug is different from your listing page slug, because if you do that, all your CPT records will be considered as sub-pages of the listing page by WordPress. Using above example, if your listing slug is ‘books’, your CPT should be ‘book’ so that WordPress routes those requests to your CPT page.
Hope that helps.
Cheers!
Hi Ali,
I’m a bit confused: in the complete template code you provide, there is no code to display the alphabetical navigation?
Where should I put the “get_alphabet_nav(‘listing-page-slug-here’)” snippet of code ?
Thanks in advance.
Please see these lines at the second para in the article above:
You need to add get_alphabet_nav(‘listing-page-slug-here’) at the top of your template that you will create by copying page.php.
Dear Ali,
I’m really glad you made a post like this to help users who do not have the appropriate development skills.
I’m using this code to show an A-Z list of posts and pages however I need to make a page to display the sub-categories of a specific category (and NOT the posts)
For instance:
In my website I have the Category “TV Shows” which has as sub-categories the name of the shows like “Dexter” or “CSI:Miami”. This categories have other sub-categories the seasons of the shows, like “Season 1”. “Season 2” etc…
What I would like to achieve is the following:
D
Dexter
-Season 1
Deadwood
-Season 1
-Season 2
I would really appreciate if you could help me with this matter as I’m searching the internet for the past week and I cannot find any solution due to my limited knowledge in programming. Please help me bro!
Hi,
Have you tried to implement the above solution for the pages without the category filtering? If you have, then you ar every close to actually filter the results for category/sub-category too.
You basically need to change the post type to page in the above code like this p.post_type = ‘page’.
After that, you just need to add filter for sub category. Once you get all the pages by alphabets, I will help you in adding filter for sub category as well.
I try and try but I can not make it work i want to use this script with a movie star actors
Can you help me
As you can see, this code has been tried and used by many others and it works. Just make sure you use it correctly.
This script not work for me
Why don´t you upload a workin Demo and a sources
Thanks
WP-Pagenavi not working.
To add pagination, Add this at the bottom of your page.
I did follow your summary – but it is not quite clear. 2nd, 3rd, and 4th lines of codes are placed at top. Then after that, paste the whole code. Or I only paste get_alphabet_nav() and the whole code you wrotein a box?
is there a way to display the listing in full according to selected alphabet on the same page while have alphabets at top?
Yes, the above post does exactly that.
The problem – I create page-listing.php and then get_alphabet_nav(‘exhibitor-listings’) and post-type = ‘listing’ – they are in same template. I create parent and subpages using same template. Still cannot see anything except “no match”… I struggled with it for several hours already.
Make sure you follow “Summary of logic and process what you need to do” and complete all 6 steps mentioned above. If you do that correctly, you will see the desired result.
Would it display on the same page when click on any of the alphabets? I mean the alphabets would be at top and the posts will display on the same page as the alphabets when selecting the alphabet?
thanks
I figured out that the following section was causing the problem:
Particularly the last two lines "meta_key & meta_value". How would it order the posts by the meta value ASC? I created a meta key of "last_first" which gives the last name of the classmate first as the last name is what I want to order them by.
Thanks for your help.
Cody
Ali-
Any help with my current issue would be greatly appreciated.
Thanks,
Cody
I had missed your question part, I thought the issue was resolved for you. But in any case, you should echo the query and then run it in phpMyAdmin and fine tune it and get the desired result.
You should echo the above sql statement whatever that turns out to be after variables value,s and then run it in the phpMyAdmin and see the results. Your query looks right. If there’s any error, you will be able to sort it out in phpMyAdmin first and then fix it in the template code.
I don’t think I have the knowledge yet to know fully exactly what I need to do within the phpMyAdmin.
I put this in the query section and got errors.
$postids = $wpdb->get_col(”
SELECT p.ID
FROM $wpdb->posts p
WHERE p.post_title REGEXP ‘^” . $wpdb->escape($alpha) . “‘
AND p.post_status = ‘publish’
AND p.post_type = ‘classmates’
AND p.meta_key = ‘last_first’
ORDER BY p.meta_value ASC”
);
echo $postids;
Any guidance would be appreciated.
the above php code won’t run in the phpMyAdmin. You can only run sql statements there.
Anyway, I think following update in the code will resolve the issue for you.
Thanks!
That did work, however I must have understood the code wrong because it’s still getting all the “A” names by first name rather than last.
I believe it to be the “Where” statement. It’s using Post Title which has is listed as First Name Last Name. I created the special custom field (last_first) which lists the classmate’s name Last Name First Name.
The goal here is to pull the meta value and order the names alphabetically by last name rather than first name.
My question now is how would I call the meta key & meta value before the “where” statement so that I can use the meta value?
Thanks for your help.
Try this, it will get the records by last_name field which will start with the provided alphabet letter.
That worked perfectly! Thank you so much for your help.
I’ve added your code and have setup all the alphabet pages. My CPT is “classmates”.
When I click on a letter (such as “B” from the navigation) I get taken to the last B classmate added, rather than the page listing all the classmates with a last name starting with B.
Here is the beta site I’m working on (http://www.hhsclassof68.com/2012/classmates/), right now we have only gotten A-D added for classmates. This “classmates” page that the link takes you to lists all classmates. When you click on a letter in the navigation though it should list only those classmates with that letter as their starting letter in their name. I created a custom post type (last_first) which I use to order the classmates alphabetically by last name.
Any ideas on how to get it so when I click on a letter in the navigation I get the correct view rather than just the one classmate?
Thanks,
Cody
Hi Cody,
You need to do either or both of the following:
Make sure that your custom post type slug is different from your listing page slug, because if they are same, all your CPT records will be considered as sub-pages of the listing page by WordPress. Using your example, if your listing pages slug is ‘classmates’, your CPT should be ‘classmate’ so that WordPress routes those requests to your CPT page.
e.g. http://www.hhsclassof68.com/2012/classmates/daleen-lewis/ should open at http://www.hhsclassof68.com/2012/classmate/daleen-lewis/
Also make sure that your loops code is working and your CPT is setup properly before the loop like this:
And make sure you refresh the permalinks url structure once (by saving it again going to settings> permalinks) if you change your CPT slugs.
Ali-
Thanks for getting back to me.
I changed the listing page to “yearbook” so now I have a CPT of “classmates” and a listing page of “yearbook”.
The alphabet navigation works, taking you the the letter page, however nothing shows?
If it would be easier for me to email or some how send you the page-yearbook.php let me know.
Thanks,
Cody
Most probably, your posts loop code does not work. First try to echo and debug to check if you are indeed inside the loop code. After that, you should echo the query and then run it inside phpMyAdmin to see if the query is correct and returns any results.
All the information that you need, to make your template work, is available on this post above with clear steps. I can’t really help to fix it by looking at the template alone, I will need to set up DB too. I might find some time if you are willing to pay for this fixing.
One more question… How would I go about modifying the code to include posts that start with numbers and symbols and such? For example, if you go to Dennis’ website, he has # for all his non-alphabetic posts.
Let’s assume we have a page and slug for numerals like this ‘books/numbers/’, we will check and if it finds numerals page, we will change the query, rather than querying the database for those posts starting with a specific alphabet, we will search the numbers range like this:
I have not tested the code but it should work. At least you get the idea what to do here. You are querying the database for the whole range of numbers not just one alphabet.
You might also want to update the the navigation function for this so that numerals link is also generated.
Updated function get_alphabet_nav would become this:
Hope that helps.
Can you shed a little light… Where does all that REGEXP code go? Does it go into the sub pages? I’ve created the template page by itself and the sub page and the only thing that happens is i see my first 5 posts with all details. I click on for example letter g, i’m taken to a singular post with details. There are more posts starting with the letter g. What am I missing? Thank you for your help. Like Dennis mentioned, this is by far the closest i’ve came to creating an alphabetical list with custom post types.
Hi Zerobde,
As I mentioned above in comments, all code goes, including REGEXP, in the same file (except for function) in page-{custom-post-type}.php.
Here’s the logic and process:
1. Create a Listing page by copying the page.php in your WordPress theme folder and name it ‘Listing Template’.
2. Crate a Page ‘Books Listing by Alphabets’ with a slug ‘/books/’ and select the ‘Listing Template’ you just created from Page Attributes and not the default template.
3. Go on to create few more pages for more letters whose slugs will look like this ‘/books/a/’, ‘/books/b/’ and so on to ‘/books/z/’. Make sure you create all these letter pages as child pages of the Listing page you just created in second step using the same ‘Listing Template’ of step 1. You will have to create sub pages for all 26 letters.
3. Now generate the alphabetical navigation using the function above. That code generates links for each letter page. These links will point to the pages you created in the third step above.
4. Now all you have to do is to catch the letter from the slug and pass it on to the query. I have written all that code already so you just have to copy that code and place inside your template.
5. Just make sure you change the example custom post type ‘book’ to your actual custom post type. I have commented it in the code wherever you need to do this.
By the way, your custom post type slug must be different than your listing page slug, because if you do that, all your CPT records will be considered as sub-pages of the listing page by WordPress.
That’s it.
Dean is correct! Once you take out all those “//replace book with your post type” comments, everything will work correctly. I was wracking my brain trying to figure out why it wouldn’t work. I knew I had everything correct. Thank you!
Yes, I should have commented it like this /*replace ‘book’ with your custom post type*/ but I have updated the code now.
Cheers!
In which file does the code with the REGEXP go in? The custom page template we just created? Thanks, by the way.
Nevermind. The “//replace book with your post type” comments were causing my sql queries to fail. I took them out and all’s well.
I’m glad it worked.
All code goes in the same file (except for function) in page-{custom-post-type}.php, assuming your CPT is ‘movie’, then you will create page-movie.php by copying page.php file available in your theme folder.
Hey Ali,
thats the only tutorial i found on the whole internet, to create those alphabetical pagination for custom post types! Thank you very much.
Regards,
Dennis
I’m glad it helped. 🙂
Finally an informative post with a solution.
Was struggling to find a decent method.
Many thanks