Info:
There is a newer version of this post, please use the new code examples: Filter WordPress posts by custom taxonomy term with AJAX and pagination
I this tutorial I will create AJAX filter for posts which will let users filter posts by tag.
1. List all tags
First thing is to get all tags and display them on a page.
I will create a function to handle that:
function tags_filter() { $tax = 'post_tag'; $terms = get_terms( $tax ); $count = count( $terms ); if ( $count > 0 ): ?> <div class="post-tags"> <?php foreach ( $terms as $term ) { $term_link = get_term_link( $term, $tax ); echo '<a href="' . $term_link . '" class="tax-filter" title="' . $term->slug . '">' . $term->name . '</a> '; } ?> </div> <?php endif; }
You should include this function in your functions.php file, and then you can use it in your template in a place where you want tags filter to appear.
This function gets all tags and then echo them with link, and term slug as a title.
Term slug is important part, because we will pass it to WP_Query to retrieve all posts that are tagged with specific tag.
2. Javascript inclusion
Next, I will create javascript file which will be responsible for handling AJAX request.
Create .js file named: ajax-filter-post.js and place it in place where you keep your js files.
We also need to have 2 variables:
1. ‘wp_nonce’ which is used to verify AJAX request
2. ‘AJAX URL’ which is location of ‘admin-ajax.php’ file where we send all our AJAX request which WordPress can then handle
This functions goes to your functions.php file as well:
function ajax_filter_posts_scripts() { // Enqueue script wp_register_script('afp_script', get_template_directory_uri() . '/js-folder/ajax-filter-posts.js', false, null, false); wp_enqueue_script('afp_script'); wp_localize_script( 'afp_script', 'afp_vars', array( 'afp_nonce' => wp_create_nonce( 'afp_nonce' ), // Create nonce which we later will use to verify AJAX request 'afp_ajax_url' => admin_url( 'admin-ajax.php' ), ) ); } add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);
3. Catch tag which users clicked
Next, we need to find out which tag is clicked by the user so we can retrieve posts only for that tag. We will get this using jQuery.
In your .js file use this script:
jQuery(document).ready(function($) { $('.tax-filter').click( function(event) { // Prevent defualt action - opening tag page if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } // Get tag slug from title attirbute var selecetd_taxonomy = $(this).attr('title'); }); });
This script will get title attribute of clicked element. Title element is slug, and we will use that as a parameter so we can get all posts with specific tag.
First of all we want to prevent default action, if we don’t do this user will go to tag page, but since we want to catch posts and display them with AJAX we need to prevent that from happening.
4. Custom WP Query function
By now we have done following:
1. List all tags and display them on a page
2. Get selected tag and save it as variable
Next we will create function that will retrieve all posts by selected tag:
// Script for getting posts function ajax_filter_get_posts( $taxonomy ) { // Verify nonce if( !isset( $_POST['afp_nonce'] ) || !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ) ) die('Permission denied'); $taxonomy = $_POST['taxonomy']; // WP Query $args = array( 'tag' => $taxonomy, 'post_type' => 'post', 'posts_per_page' => 10, ); // If taxonomy is not set, remove key from array and get all posts if( !$taxonomy ) { unset( $args['tag'] ); } $query = new WP_Query( $args ); if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <?php the_excerpt(); ?> <?php endwhile; ?> <?php else: ?> <h2>No posts found</h2> <?php endif; die(); } add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts'); add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');
Function accepts one parameter ‘taxonomy’ which is tag user has clicked and then creates WP_Query to get all posts tagged with selected tag.
Before we do that we should verify nonce, if nonce is invalid function will return error and will not make any queries.
5. Display posts
Last thing would be to send AJAX request, retrieve data and display it on the page.
This is done in .js file
jQuery(document).ready(function($) { $('.tax-filter').click( function(event) { // Prevent default action - opening tag page if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } // Get tag slug from title attirbute var selecetd_taxonomy = $(this).attr('title'); // After user click on tag, fade out list of posts $('.tagged-posts').fadeOut(); data = { action: 'filter_posts', // function to execute afp_nonce: afp_vars.afp_nonce, // wp_nonce taxonomy: selecetd_taxonomy, // selected tag }; $.post( afp_vars.afp_ajax_url, data, function(response) { if( response ) { // Display posts on page $('.tagged-posts').html( response ); // Restore div visibility $('.tagged-posts').fadeIn(); }; }); }); });
You will notice here that response is displayed in div with class ‘tagged-posts’, so in order to display results on your page you need to have div with this class on the page.
Final result
To see this in action check out working example.
I have added fadeOut and fadeIn effect to make this look little bit nicer.
Download
Update
Fixed bug in firefox, thanks to Mike’s comment
Info:
There is a newer version of this post, please use the new code examples: Filter WordPress posts by custom taxonomy term with AJAX and pagination
This is great. Is it possible to only show tags related to a specific category?
Hi Chris,
Yes it is possible, it would be something like:
$terms = get_terms("my_taxonomy");
Check out in WP codex: http://codex.wordpress.org/Function_Reference/get_terms
BR
Vlado
Thanks for this :) How could I manually specify the categories instead of printing out all the tags/categories in step 1? For example, I only want to list “All”, “category 1”, “category 3” (even though I have 10 other categories). Thoughts?
– Lil
Hi Lily,
You should use something like:
$args = (
'include' => '1,2,3,4', // List of ID's you wan't to include
)
get_terms( $taxonomies, $args );
You can also use exclude, if you have less categories you wan’t to exclude.
More refs can be found on WP Codex: http://codex.wordpress.org/Function_Reference/get_terms
BR
It would be very kind of you If you posted the html/php we have to put in our pages so as to make the all thing work.
Thank you for this tutorial
Hi Maxime,
I have updated post, there is now link to download files.
There is .js and .php file inside of .zip folder, just be sure to update path to .js file in enqueue function.
BR
Vlado
What do I have to do to filter by category instead of tags? Thank you!
I am trying to get the same post effect that they achieved here: http://news.harvard.edu/gazette/section/campus-n-community/news/. I want my categories to be filtered by the viewer. On this page – Latest, Editor’s Pick, Audio/Video, Photography, and Popular buttons filter the vertical menu to the left without the page reloading. Everytime you click a new category button the post are able to be filtered by the same horizontal nav. Is this possible with some variation of what you have done above?
Thanks!
Hi,
It is possible, these 5 filters can be custom taxonomy so you filter by that.
Thank you! Really great posts around here. I’ve been searching for a working example on how to filter posts with ajax to use with my cpt.
Hi sir, great one post but at last i don’t know how to add tags to page……..?
Hi,
Follow these steps: http://www.sitepoint.com/wordpress-pages-use-tags/
hI SIR, i got it but my questio is how can i show the tags to page as shown in example so i can also show tags to pages as it shown in the demo
Hi,
Well it would be best for you to download example and check how I did it.
BR
V
Hey! Great tip about filtering with tags.
I just have few questions:
We have a few CPT (books, magazines, etc) and to show them we are using a separately page for each one, what about if we want to use the same function to filter with tags those CPT?
Right now your code works only with post_type = post.
Is there a way we can rewrite the function to allow calling the filter based on the post type?
Hi, thanks.
Sure thing, it works by modifying wp query in step 4, where you have: function
ajax_filter_get_posts( $taxonomy )
.You can modify function and pass post_type param, so you can filter by any post type
ajax_filter_get_posts( $taxonomy, $type )
, eg: http://pastebin.com/eJvH9vcuThank you Bobz!
The $type variable is being send through out the ajax-filter-posts.js, right?
Right now I’ve added an attribute to the link with the name of the post_type, and include that attribute in
data = {
action: ‘filter_posts’,
afp_nonce: afp_vars.afp_nonce,
taxonomy: selected_taxonomy,
type: post_type,
};
Is that the right thing to do?
Thanks again in advance.
yes, that is correct.
Hi Elie,
Sounds like you got it working with a custom post type. Would you be able to post your code into Pastebin or something similar?
Just so I can see what I’m doing wrong… I’d appreciate it a lot.
Many thanks,
S
Thank you for the help.
I did everything like we talked, but I’m getting this warning:
Warning: Missing argument 2 for ajax_filter_get_posts() in…
I think it has to be something with the post_type variable, which is being send properly as we said before :sigh:
What could be wrong?
Check my code over here: http://tny.cz/ea12c747
Hope you can help me figure it out.
Regards
I think you don’t need that second param, because you pass all things in $data array, so just remove it, and everything should be fine.
Yup, That did the trick!
Thank you Bobz, worked just fine :)
no prob.
cheers
Thanks for posting this up. It’s exactly the start I need to create what I’d like to do.
One thing I’m trying to work out. How do I call this into a custom page template?
Do I just call the functions inside the loop?
tags_filter ();
ajax_filter_get_posts ();
Thats what I’m currently trying to do and I get the “Permission Denied” because (I’m guessing) it can’t verify nonce.
I appreciate you’re probably really busy and didn’t really want this to turn into a support Q&A, but any help would be appreciated.
How do I call this feature on a page template?
Thanks,
You just display tags_filter() somewhere on page, and you need div where returned data will be displayed.
Download files and check the code how I did it.
Thanks for your response. I’ve got it working with my own custom post type and taxonomy for that type. The only thing I’m trying to work out now is why, no matter what tag filter I click, the results only show the standard post type (blog posts), not my custom posts…
You can modify function
ajax_filter_get_posts( $taxonomy )
and pass post_type param, so you can filter by any post typeajax_filter_get_posts( $taxonomy, $type )
, eg: http://pastebin.com/eJvH9vcuOh, I’ve done that and have it displaying what I need i.e. my custom post type (cars) and their categories (car manufacturers). Your pastebin code was very helpful. Thank you.
It’s just that when I click a filter (a car manufacturer), the javascript is fading out my posts (cars) in the .tagged-posts div and rather than getting the title of the filter I clicked (let’s say “Subaru”, which I can see from the source code is there) and displaying the “Subaru” category, I get my standard “post” type displayed (currently “Hello World” and another test blog post).
I really can’t see what it is!
Anyway, please don’t feel you have to respond, I’m sure this is the last thing you want to deal with! Thanks so far for your help, it’s really kickstarted learning what I need to do.
Cool.
You need to understand that you ‘talk’ to php over AJAX, and that is in ajax-filter-posts.js file.
So fade effect is in .js file, I have added this effect just to make it little bit visual better, if you click and have to wait 3 second to get data, then if there is no fade in/out, for user would feel like it is broken.
Check out what is done in js file before and after data is received from php.
I think something like this would do the trick in .js file:
var clicked = $(this).text(); // this will get text of tag clicked
$('.title-of-div').html( clicked ); // this will add title to div you want in to a div you want
Thanks again for your reply.
That is not quite what I meant. In your .js file when the user clicks on a tax-filter, the title of that filter link is put into a var called “selecetd_taxonomy”
var selecetd_taxonomy = $(this).attr(‘title’);
The title has come from $term->slug in my custom taxonomy.
I’ve printed console.logs throughout the .js script and I can see that these vars are getting the category title. e.g. “subaru”.
Where I’m lost is that the category (“subaru”) should then be sent back to a PHP function and where all the posts in http://myurl.com/car_manufacturers/suburu/ are collected and then should be displayed.
Thats not happening.
Instead it’s getting the default wordpress post type posts. Not my custom ones. I can’t work out where this is happening in the function.
I’ll continue to try and figure this out, I’m working locally so I can’t share a link at the moment. But thanks for you continued help! :)
I don’t understand what are you trying to say. But anyway, practice makes perfect, so keep up and you will come to a solution
Yes no worries.
It’s all working just returning the wrong category as results and I can’t figure out why.
Hello again,
I’ve put my code into pastebin. If you have a spare minute I’d love it if you could take a look. I’ve put comments to explain a few things. http://pastebin.com/7nYq76wJ
The part of code that is confusing me is the end of the javascript. Would you be able to explain the $.post and response part. I’ve tried looking online but can’t find anything.
Again really sorry to keep bothering you, I’m so close to this but can’t understand why I’m not getting my custom post type returned! Your blog post is the only good tutorial on how to do this, for that I thank you.
One other thing, in the JS you have a line:
action: ‘filter_posts’, // function to execute
Where is this function, I don’t understand what it is calling… :(
It is calling ‘ajax_filter_get_posts’ via
add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts');
add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');
This is how AJAX works in WP.
If you get wrong data back, then something is wrong with you wp_query.
You need to learn how to debug things.
1. First of all check if this post_type you are passing is getting in function.
2. Try to manually add post type you wish and see if it will work
3. print_r your query and args to see what is going on
Got it working! Sorry for spamming your comments…
Couple of things, I needed to to change ‘tag’ to to my taxonomy (I don’t have tags) and I had the PHP looking for the wrong variables from the ajax.
Right, now onto making only pull in the parent categories not all the child ones too.
Thank you.
no prob.
cheers
Awesome tutorial! Quick question though. Would it be an easy modification to use entries from a custom meta box instead of post tags?
Like if that first function were modified to pull all unique entries that exist in a get_post_meta() field?
Thanks!
Thanks.
You can do anything. In function ajax_filter_get_posts is wp_query, so you modify it per your needs, and instead of tags you pass other parameters with ajax.
Hello Bobz, I have a question about this code snippet: http://pastebin.com/rPYwF1TE
Does this snippet have to go inside functions.php? Can this snippet go inside of my custom template?
Hi, I have moved your code snippet to pastebin, it is what you should do next time.
I’m not sure if it would work if you put it in page template but you can try.
Because of order of loading things in WP: http://codex.wordpress.org/Plugin_API/Action_Reference I think this function should be placed somewhere earlier in process then in page template files.
Great tutorial! For some reason, the example isn’t working in Firefox though and I don’t have Javascript turned off. The links just go right to their page. Other popular browsers I tried have it working. Check it out & let me know if you find the same. I tried getting rid of the href attribute in my own example & still nothing happened. Thanks!
Which OS and FF version is this?
Maybe some plugin have conflict, or any errors in console?
I tested on a PC & Mac. PC has the latest version of Firefox. Mac has an older version. I’m not the most experienced with debugging via console, but when I went into the tab, I did not see any errors and again, this is on your example (& my own implementation). Weird. Thanks for the help!
Okay, found an error when I click on a tag. Firebug is highlighting line 5 – “if (event.preventDefault) {“& saying the event is not defined.
So “$(‘.tax-filter’).click( function() {” just needed to be changed to “$(‘.tax-filter’).click( function(event) {” :-)
Hi Mike, yes this is right. I have updated post, thanks!
Funny thing is that I have just hour ago fixed same issue on one other project i’m currently working on.
Exactly the same problem.
haha Gotta love those minute details that can make such a big difference. Glad we figured it out! I don’t want to trouble you anymore with this, but it looks like there might be something wrong with your query now as it keeps showing “no posts found”.
Yes, thanks.
It’s not query problem, thing is I have improved my workflow a little bit and I have rewritten this same script in a better way and now I uploaded wrong file.
Thanks once again, it is working now.
Current script only checks if there is response, but nothing else, which is bad.
You can download updated files from link in post and take a look.
Basically everything is the same, just it is JSON encoded and I return all required data for debug, just uncomment console.log lines and you will have full insight.
I will rewrite the post during the weekend with updated code.
Cheers
Awesome! I’ll check it out now. Thanks for the update!
Okay, I implemented the new method & got it working! There’s only one problem I’m seeing with the new code which is that only the first result from each query loop is returned when a tag is clicked. Not sure why.
It was a bug on line 48 in wp qurey.
It was like
$result['response'] = post data..
, but it should be$result['response'][] = post data..
. You only got last post in loop because it was overwriting everytime. Response index should contain another array of posts, it is fixed now in files.Thank you very much for this tutorial. It’s exactly what I need but although I have no problem in understanding how to change post types and categories and styling, I’m really struggling to work out exactly what goes into the template file. Am I right in thinking that the php file in the downloads gets copied into my function.php? S’s comment above, I believe asks the same question but I’m afraid I can’t figure it out from the download what I need to put in the template file.
I’ll continue to try to figure it out myself – best way to learn :) but would really appreciate if you can set me straight if you have the time to reply.
Cheers!
Me again, sorry, have been on this for 2 days and really disappointed with myself. My background is design rather than code and seems the harder I try, the less I feel I understand…
I have a custom post type ‘a_and_h_cheese’. I’m using tags as the filter like your example . That’s it. What goes in function.php and what goes in my template page please? The best got was an ‘access denied’ message. I looked at various pastebin links in your comments but just can’t figure it out :(
hi. You should include .php file in functions.php and update path to javascript file.
Then in your template file put something like this: http://pastebin.com/TZRtSM2u (this is copy of my demo example).
Thanks for the steer Bobz. Very grateful. Will have another go today.
Thanks again Bobz, have tried again – with the sample template you pasted and just with standard example posts and tags (before I get clever with my cpt and taxonomies and styling up etc)
First I got: Fatal error: Cannot redeclare tags_filter() (previously declared in… (my function.php). I think I get this – it’s because this function is already in the function file and we don’t need it again in the template, just in the template. If I delete one or other the page loads and I’ve got my tag list and I got all my posts, that’s great, but clicking tags results in ‘No posts found’. Similarly a bit confused about the query/loop in the functions.php and again in the template… Where am I going wrong?
Hi, you need to learn how to debug.
1. Open inspector ‘network’ tab
2. Refresh page
3. click on one tag and wait to return something
4. in inspector look for ‘admin-ajax.php’
There you can see what you are sending and what you are receiving as a response.
You can also do print_r in function ‘ajax_filter_get_posts’ which returns posts, instead of echo, do var_dump or print_r, then again refresh page and check inspector.
You will get an error on page, but you will see what is causing error, what kind of query do you send, etc. everything is in there, just need to learn how to read it.
Bobz, this is a fantastic tutorial.
I’m convinced I’ve done everything correctly, but I’m getting the admin-ajax.php (failed) and (canceled) in Inspector > Network when clicking the tag and so it’s skipping the event.preventDefault and bringing me to the tag page… have any wisdom you might impart as to why the admin-ajax.php is acting up?
thanks. I don’t know why would that be.
Check console window for any errors and fix them if there are some
Hey there!
Is there a way to add/include a link to all posts in the tag lists generated?
That way if someone clic a specific tag and want to return to all posts, can do it by just clicking the tag “All”.
Peace
hi, there is but i think you would need to hardcode that as a first li item
True that! But what parameters should I use in the link to call “all posts”?
Can you help me out please?
Hi Elie, I’m trying to accomplish the same thing here. Have you found any solution ? Thanks! :)
Thanks for the tutorial! it has really help me a lot. I do have one question: I want to paginate the results with a “load more posts” button. Can you point me to the right direction or get me starter on how I can approach this problem?
Hi Alonso.
Well hm, you maybe try something like this: http://designaeon.com/2012/05/wordpress-ajax-pagination/
In this case in my query is missing ‘paged’, then when you click on ‘load more’ you need to send to query which page number you want to get.
I think you need hidden field here to store next page number.
I have not tested non of above, but this is what I see as a way to go, hope you get the idea.
Thanks Bobz, the link provided didn’t help, but adding the missing paged pointed me in the right direction and in the end I got it working. :)
Great, cheers
Alonso: I’m actually trying to accomplish the same thing; pagination after clicking on a tag. Would you mind sharing how you were able to get it working? I’d really appreciate it. Thanks!!
Bobz: Thank you for the tutorial! Aside from the pagination issue I’m having, it’s working exactly as it should.
only for expert developer… the best solution is to buy or download a simple free plugin… more easy to install and “developer-fanatic” free
Hi Bobz, great tutorial this serves as a great starting point for integrating ajax into all aspects of wordpress as a beginner.
I am using this code on a site we are developing and will be modifying it to remember the previous tag clicked so it begins filtering down on more and more tags until you reset it.
I have changed the code to work with a custom post type and tax, however it keeps running the loop twice and giving the results twice. I unfortunately can’t share the site with you but is there anything off the top of your head that could be causing this?
Thanks for any response.
Fixed this: It was my own fault.
Two divs were being created on the page with the class tagged-posts, DOH!
Again thanks for the tutorial Bobz, don’t think this will be the last you’ve heard of me though!
Cool, cheers.
Hello Vlado,
regarding the comment of Chris at February 9, 2014, you wrote:
” Hi Chris,
Yes it is possible, it would be something like: $terms = get_terms(“my_taxonomy”);
Check out in WP codex: http://codex.wordpress.org/Function_Reference/get_terms
BR
Vlado ”
Ho can realize this taxonomy? so, i wil get terms of ALL tags used in my posts related ONLY to my category with id 5, or name “category name”. Thanks a lot for your reply. regards Giombattista
Hi Giombattista,
I’m not sure I understand your question. Anyway you should stick to WP Reference and test it out yourself as I’m not sure what are you trying to get.
I want to show only tags that i use in my posts belong to a particular category (example “animals”). So, my question is how can i refine the tags list, so i not show all tags, but only the tags related to posts of a single category?
This cannot be done with get_terms, it would be best to write a custom SQL to retrieve this.
Dear Vlado, i have realized my scope! i used the argument EXCLUDE to exclude the tags that i don’t interest me. So, a custom tassonomy. So, thanks to this new get_terms i got only the tags of my interest. It’s a manual refine, but the result is great. Now, my next step is: i wish i create also a “Show all” in my tags list, also with ajax effect. So, i can refine the list with one tag or click upon “Show all” to see again all the posts, as i see thanks to WP_Query, when i load the page for first time. Do you think i can realize it? could you help me with the code? thanks a lot, Giombattista
Hey,
great work here ;)
i have a question, i have many custom content templates, can i load the template with ajax too?
like get_template_part( ‘content’, get_post_format() );
can’t add it to the $result in the functions.php
hope somebody can help me.
– David
Hi David, I don’t think it is possible to do it like that.
You can get page by ID via AJAX, and then in output include this template to display data in correct format.
Hey Bob, thanks for the fast reply.
Well, it kinda works, the right content, using the right content template is coming.
I can see it in chrome developer tools under response.
Problem is, that the content stands above and the response is:{“response”:[null],”status”:”success”}
so it always shows “no posts found”.
Well, can’t help you much. You should consult inspector, trial and error will help you get to your goal.
Hey,
I’m looking to be able to do this, but with multiple tags.
E.g Tag 1 – English / Maths
Tag 2 – Maths Easy, Maths Hard, English Easy, English Hard
If Tag 1 is Set to English, I want to only show “English Easy, English Hard” as a selection for Tag 2.
Is this possible?
Hy
Well, it is, but you need different approach.
1. You need to list all tags
2.1. On tag click you need to make it ‘active’, add class active (second click on same tag would make it inactive)
2.2. Need to lookup all active tags, store them in array
2.3. Do WP_Query by multiple tags, consult wp codex for correct syntax of wp query
I am still getting “Permission denied” and I can’t get my head to think how? How do you verify nonce in the first page load ?
Something is wrong with nonce name probably.
Check that nonce is passed to function correctly.
‘afp_nonce’ => wp_create_nonce( ‘afp_nonce’ )
and
wp_verify_nonce( $_POST[‘afp_nonce’], ‘afp_nonce’ )
Thanks for the tutorial,
it’ exactly what I’m trying to accomplish.
I am getting “No posts found” all the time though, and no errors in the console. I know the ajax-filter-posts.js is being called though since I modified the “no post found” message to something else and I can see that echoed in my page.
Is there anything I could look into to understand what’s going wrong?
thanks!
Hi, thanks.
Looks like your query returned no posts, so it means it is not an error but you have 0 posts with tag you selected.
Test the WP_Query until you get desired results.
Thanks Bobz,
I do have posts tagged with those tags though, I’m just testing with 4 tags and 4 posts, each post is tagged with couple of them.
I’m not sure what you mean when you say “Test the WP_Query until you get desired results”.
Any indications of things I could try out would be much appreciated. :-)
I actually just ran into the same problem when editing tag.php and trying to pass the tag variable to a WP_Query. I always get ‘Sorry, no posts matched your criteria.’ Except if I manually specify the tag as an argument in the WP_Query. Then I get the posts associated with that tag. It’s really weird but I’m pretty sure this is the same problem I’m getting with the “tag filter”.
Check what are you sending to WP_query then.
Dear Bobz, this is my question: how can i improve delay time of the response when i click on a tag and after i retrieve post list result? i wish i obtain a result that is fastest than possible.. thanks a lot. Regards, giombattista
Well, that depends on your server.
You should put indicator that content is loading so user knows he needs to wait.
1. I wanna get a taxonomy term by another taxonomy term through ajax. How can I do that?
2. I want some taxonomy name to filter with some other names from database with ajax.
Hi, I’m not sure i’m following you, there is no way to assign term to a term.
Anyway, you should try to get desired results with WP_Query first.
Thanks for the tutorial. I’ve got the tag filters working, but when I load the page (which should display all posts), I get a Permission Denied response and I have no idea why. I’ve pasted the code (that I’ve lightly modified) here: http://pastebin.com/AdUWK4NB
Thanks in advance for any help!
Hi Patricia,
There is something wrong with verifying nonce, you don’t post it with ajax or you use different name probably.
Check that and then you will be fine.
Hello, It’s Giombattista. i used and customized your code with success. But now, i have a question for you:
Suppose to have n. 2 Archive page with this tag filter system; for n. 1 page i want to show, for example, Title and Excerpt. For the second one instead i want to show only the thumbnail of filtered posts.
I created n. 2 different div class -> Class “Layout A” and Class “Layout B”, with success. But, actually i cannot create n. 2 different layout because i cannot explain to my code where my taxonomy (in the function ajax_filter_get_posts( $taxonomy )) came from (from first or second archive page?). I think i can insert some if-else inside the function ajax_filter_get_posts( ) function, before the result while. But exactly i don’ know how.
If you have some suggestions for me, it would be fantastic.
Thanks a lot, Waiting for your reply. :-)
I’m not sure I understand your problem, but try to use hidden fields, or data attributes for additional data you need to pass via AJAX:
BR
V
Hi, I want to do what you show here, but with post CATEGORY, not tag(s).
Can you explain how to do this? I assume it’s very similar to this?
Thanks :)
Just update the WP Query.
Is there a way to do this via a shortcode instead of adding it to the template file. I want this to just take up a small portion of one of my pages
Sure, you would need to modify tags_filter() function slightly, check docs: https://codex.wordpress.org/Function_Reference/add_shortcode
Thanks for this tutorial, was wondering how i would go about creating a select filter ? where the user can select the tags to be displayed all from one taxonomy and then display them accordingly ?
Sure, you can. You would need to modify tags_filter() function to output select menu instead, and then fire js function on(‘change’)
Hello,
This script really helps a lot though I have an issue displaying default contents or when page load, I would like to display few posts. Right now it’s only the tags being displayed and only the content will display when any of the tags will be clicked. Can you please help as to how it should be done? or what should I missed?
Thanks a lot.
Rheejee
Hello,
I would do something like:
$(.tax-filter[title=tag-slug]).trigger('click')
.This will trigger a click on a specific tag and populate the content area.
Other than that you can do another wp_query inside of a template.
Cheers
Hi Bobz,
I’ve had a go at using this code to display tags as per your demo and I get the following error.
If you had a spare moment to have a look at my pastebin link and let me know what I am doing wrong that would be great.
http://pastebin.com/AnqtLyeR
Thanks
Paddy
Oh and my error is:
Warning: Missing argument 1 for ajax_filter_get_posts(), called in /home/firstdraftnews/public_html/wp-content/themes/firstdraft/tag.php on line 19 and defined in /home/firstdraftnews/public_html/wp-content/themes/firstdraft/functions.php on line 52
Permission denied
There is something wrong with the nonce, check that part.
Hi,
You are missing ‘Tag filter’ function under #1, you should place that function in your template file.
ajax_filter_get_posts is function you call on ‘click’ of tag which returns posts and displays them in template.
Thanks for this, I have been trying to implement the history api but can’t figure it out. i can get the url to change but not the back and forward buttons. Any chance you could show how to do this. Very much appreciated. H
Hi,
This code doesn’t provide paging functionality.
I will have to write another post since it is a little bit outdated which will include paging.
I’m not sure about history, will that work.
Hi Bobz,
First of all, thanks for sharing this really nice function. I have customised it a little for my needs and it’s working great.
The only thing which I would like to change is when the page is loaded all the posts are displayed first then when the tag filters are clicked it only shows the tagged posts.
Is that possible with this code?
Many thanks.
Rick
It should work like that.
If not, you can make new wp_query that displays all posts in results div.
http://www.bobz.co/tips-tricks/ajax-filter-posts-tag-live-example/ shows just that.
Getting error variable afp.vars not found? what are those vars?
it should be: afp_vars.afp_nonce or afp_var.afp_ajax_url.
Check the ‘Javascript inclusion’ part, and localize_script..
is there a way to do this with post categories instead of tags?
Sure, you can do it with any taxonomy.
i must be too new. I’m not sure what goes where…
you have 5 steps above:
1 list tags: goes in functions
2. include javascript: goes in functions.php
3. Catch tag which users clicked: goes in js file.
4. wp function: where does this go?
5. display posts. in js file.
what do i put in my template file?
I downloaded your zip and there are only 2 files, but they seem to have different slightly codes than those in the steps above. which should i use?
Hi, thank you very much for this great tutorial. I have two questions, if you have the time to answer.
1) I’m trying to work with categories instead of tags. You mentioned that it’s just update the WP Query. I did it, but I can’t make it work. It keeps returning all posts instead of return the post of the clicked category.
2) Also I’m trying to create a link to “show all” but all I can get is a link that refreshes the page… I can’t figure out how to accomplish this.
If you may not answer these questions, thanks anyway for the tutorial.
Hi Gisele,
// WP Query
$args = array(
‘tag’ => $taxonomy,
‘post_type’ => ‘post’,
‘posts_per_page’ => 10,
);
and replace ‘tag’ with ‘category’ following the WP_Query codex.
You can always do print_r($query); to see what’s going on in there.
Regarding the second if the link contains eg: ‘all-posts’, then before making wp_query do check if( $cat = ‘all-posts’ ) { unset( $args[‘cat] ); }
Hi Gisele,
Do you think you could tell me what you did to change the query to category?
i should say, I changed the line in the template flie from ‘$tax = ‘post_tag’ to ‘$tax =’category’. and this changed the filter buttons to my categories, but if i click any of the category buttons it says that no posts were found.
I would also love to know how to implement that “show all” button.
Thank you very much my dear Bobz! It worked perfectly.
You’re awesome!!!
Hi Josh! Sorry, I replied to Bobz but didn’t see your question.
To work with categories, as Bobz explained you should update the WP Query section in his code at ajax-filter-posts.php file. Change “tag” to “category_name” (this is his mention on “…following the WP_Query codex”). I was changing to “category” not “category_name” and this won’t work. Only newbies like me can understand why we do such mistakes and insist on them…
To create a “Show all” I did three things (I don’t know if this is the best method, but it worked):
1) On your template file, create the a variable “$cat = all-posts”.
Obs.: Somehow it works without the var, but I think it’s better to declare. Maybe it works because Bobz created a check when taxonomy is not set (line 39).
2) Then, create the link that passes the “all-posts” value as a category, something like “echo ‘slug . ‘”>Show All ‘;”.
3) Then, similar to what he did on line 39 in ajax-filter-posts.php file, you should declare what happens when the value “all-posts” is passed. Again, as Bobz mentioned:
if( $cat = ‘all-posts’ ) {
unset( $args[‘cat] );
}
If it doesn’t work for you let me know. And if I did something awfully bad in this code, please someone let me know…
Thanks for replying Gisele,
I tried adding :category_name and am getting the same thing. No post avaiable. If i put this code directly in my template file i do get my posts though.
I posted my code here:
http://pastebin.com/6QiUWTnG
Is it similar to yours or am i missing anything? I would love to see your code too, if that’s not too forward. :)
please?
Hi,
I wan to show multi select tag filter , can you please suggest code ??
Thanks
Hi Tina,
I would do a toggleClass(‘active’) on each tag, and on each toggle call function to retrieve posts.
Please not that function in this tutorial is not the one you need to call, but instead you need to modify it to suit your needs.
BR
V
http://creativebeelabs.com/incompanion/filtering/
I have no idea why I cant make this to work. URL above
Hi Branko, from what I can see it is working.
Hi, thank you for this tutorial, i add all functions and script, and in my .tagged-posts in index.php i get the posts in my selected tag, but when i add class tagged-posts only to my loop, i get only title-links, my get-template-parts > content, don’t work, i want to display thumbnails and content, when selecting tag, also, if i select tag-1(used only once) my pagination don’t dissapear, like if i got still >50 posts on page, how can i fix this, to get proper content of post in tag, and fix pagination? Also is it possible to add selected tag to my coockie and add class active to it?
What should put in template file to get like in live example? I put all what you said in functions.php, js folder. If I put only function tags_filter() function, I get only all tags. But how I can get all posts and then filter by click on tag’s link? I got all posts but how to call another function from functions.php and javascript file to generate only selected post by tag?
In template file you should put function
tags_filter()
.If you wan’t to display certain tag posts on page load, quickest way to do it would be using jquery, trigger click on tag which you want to show.
Thanks for the great tutorial.
Have you had any success integrating the pagination tutorial from Designaeon.info, or pagination via another method?
Hi Simon, I didn’t try to integrate pagination.
There are some things about this post that can be improved, will try to sum up everything and rewrite this tutorial.
Thank you for this useful snippets. I will add it to my website 1stwebsite. I want to add it of a customs post type. Will it work for my custom post types “code”
Hello Vlado,
I notice that my code doe not work anymore. I think it’s an ajax problem, maybe due to the continue WP updates.
Can you suggest me how to fix the problem and the code to work properly again? Thanks a lot in advance, Best Regards.
Hi Gidan,
The code should work, it has no impact from core updates.
Are you sure something didn’t happen that broke he code Bobz? When I click the link to the ‘working example’ – there is no content displayed. I know I looked at this post a couple months ago and it worked. I came back to it today to try and study it but it no longer functions on my PC, not in any of the 3 major browsers.
Hi lbob, I’ve moved to digital ocean but the live example obviously didn’t come along :)
I have fixed it now, it works; thanks for comment.
By the way I do have in mind to rewrite this tutorial, should be soon online with more options and customizations.
Hello Bobz,
The tutorial is great. It helped me a lot with what I wanted to do, I just need to paginate the results of each label. I see that another person has asked about the same, but I had already come to that solution. Any more ideas?
Thanks in advance.
It’s not included in this tutorial but I will write a re-post soon with paging example.
Hi Vlado,
Just curious if there was another link to the .zip file available. Am getting a 404 error and would really like to try this out.
Any help is greatly appreciated,
Daniel
Hi Daniel,
Sorry, will check what’s wrong with download, but you can grab it from gist:
PHP: https://gist.github.com/Bobz-zg/5f2f55983000035b5da9263cdb83d8e9
JS: https://gist.github.com/Bobz-zg/16578c3c173abfe2b22daffd67f6f1e0
VIDEO test 2
Idk why all of these links have all the extra \ after I click each tag. Any idea? I have removed everything so it will only display the title and not even an anchor tag or the permalink.
I have figured out what was going on with the links displaying extra \ and /. In combination with other functions it was returning all of that when using the get_the_title();. Dont know if it just me but I can seem to get the $output = ‘‘. the_title().’‘; working, it keeps filtering the html in the functions.php.
Any help would be greatly appreciated, have added a category filter and this is the last hill I have to climb. I am at a loss as to why it is happening.
Hi Daniel,
You cannot do
$output = the_title();
because functionthe_title()
prints out title of post, and instead you need function to return data, and that would be$output = get_the_title();
Even when using get_the_title(); the html to turn it into a link is being filtered or not working within the output variable.
Just had to do it with an echo instead, in case anybody else is having an issue.
echo ''.get_the_title().'';
I apologize if I am bothering you with too many questions.
I am having a bugger of a time getting this to work correctly, dont know the exact way to get this functioning and to filter by region and topic(category,tag).
I feel as though I have made some progress and with a few minor changes it could be working and could be soemthing anybody could use to get those pesky AJAX post filter pages working correctly.
I am working off of your design and know that I still have to add the correct if statements in order to get this to filter by tag and category. I appears to make the ajax call but does not filter the posts.
Link to my code on pastebin
Any help in this would be greatly appreciated.
Please check new article and use examples from gists.
https://www.bobz.co/filter-wordpress-posts-by-custom-taxonomy-term-with-ajax-and-pagination/
Hi i read a lot of tutorials about using ajax in WP, and i read this tutorial after implementing this one:
http://carlofontanos.com/wordpress-front-end-ajax-pagination-with-search-and-sort/
Can i ask you, what will be the best way to change foreach loop to standard if have post, while have post,
so i can use get template-parts with ajax call?
I want to use this tutorial with carlofontanos.com ajax pagination, but using if have post loop.
Is there a better way to get template-parts with ajax without using plugins?
Please check out the new post, it uses output buffer which you can use to achieve that.
Just instead of html part you should be able to use get_template_part to include your markup
Hi Bobz,
Thanks for the tutorial. It’s been a huge help! I have it implemented on my site and it’s working as it should. The tags are ajaxing underneath after clicking.
My website is using the Advanced Custom Fields date time picker to only show posts that are in the future because it lists upcoming film screenings. So I have tailored your code to only ajax in posts that are future posts/screenings and not past posts/screenings.
I would only like the tags that have future posts attached to them to display. For example the ‘animated film festival’ tag on my site does not have future posts and therefore returns zero posts on click. Is there a quick way to remove this kind of tag from the list conditionally?
For your reference:
http://pigcine.pamrosel.com/
It’s not possible to get tags in that way.
One thing that comes to my mind is that you create a cron job with wp_schedule_event.
That cron should:
1. run every day in the morning 1 time
2. get all terms
3. for each term get_posts (posts_per_page=1) that have film screening date today or in the future
3.1 if there are posts then update term meta ‘have_posts’ => have
This way all tags that have posts will have term meta ‘have_posts’ = have.
Then you use get_terms function with meta_query to get only terms that have this meta_tag and value ‘have’.
It’s a lot of queries but you do that once a day with scheduler in the background.
Or the second solution would be to try to write your own SQL query to get terms, but it would be a difficult one
download link is no longer working
Please check new article and use examples from gists.
https://www.bobz.co/filter-wordpress-posts-by-custom-taxonomy-term-with-ajax-and-pagination/
Thanks so much for this tutorial! I got it working with my CPT, by modifying the $args variable like so.
Is it possible to filter posts by year using the same method ?
It would be possible, but you need to alter the script a bit. This is more a showcase how things work, it’s nearly impossible to make ‘one fits all’.
Hi I have a Question:
In your Working Example the created WP-Query gets his own url. When I use this, it does not create or direct to its own url. Can you may tell me why? The website is only tested localy on my Computer with MAMP.
Thx for your Answer.
Excellent article, thank you very much! It helped me a lot!
Great tutorial! It’s the first time I manage make something like this work.
Any idea why, if I substitute “category” for “tag”, it doesn’t work anymore?
I also changed it here:
function tags_filter() {
$tax = ‘category’;
instead of $tax = ‘post_tag’;
and here:
$taxonomy = $_POST[‘taxonomy’];
// WP Query
$args = array(
‘cat’ => $taxonomy, (instead of ‘tag’)
‘post_type’ => ‘post’,
‘posts_per_page’ => 10,
);
I know this is an old post but any help would be greatly appreciated!
Hello Bobz,
I followed the tutorial! Super filtering works well except with the exception, I have only one result when I click on a link tags … while I would like to have all the articles in with the tag.
I modified a little code to put a custom taxonomy, in the demo there is also only one example.
Would you have a solution please?
thank you
Olivier
Hi Olivier, glad you find it helpful.
Are you sure
posts_per_page
in WP_Query is set to return more than 1 post?yes !
$args = array(
'post_type' => 'post',
'category_name' => 'retail',
'posts_per_page' => 100;
'tax_query' => array(
array(
'taxonomy' => 'retailly',
'field' => 'slug',
'terms' => $taxonomy,
),
),
);
Would you mind to try modifying the loop in this:
ob_start();
while( the_query->have_posts() )
...
endwhile;
$html = ob_get_clean();
wp_send_json_success($html);
And you might need to update js part to display data to
response.data
Best is to do
console.log(response)
so you can see exactly what you get returned from WP.Hey Bobz !
I’m changed, i’m used the shortcode and good jobs :)
Thx !!!
Thanks for the tutorial. visit us https://www.nirwanawisata.com/tour/3d2n-orangutan-bukitlawang-tour/
Your welcome
onload first category filter show
i get an ReferenceError: afp_vars is not defined
So that means there is no javascript variable
afp_vars
onwindow
object. Checkwp_localize_script
and verify what’s the name of your variable.And please next time use external service for pasting large parts of code, thanks.
hi vlado,
can’t find any reference for afp_vars in the source code.
my functions.php
function ajax_filter_posts_scripts() {
// Enqueue script
wp_register_script('afp_script', get_stylesheet_directory_uri() . '/javascript/ajax-filter.js', false, null, false);
wp_enqueue_script('afp_script');
wp_localize_script( 'afp_script', 'afp_vars', array(
'afp_nonce' => wp_create_nonce( 'afp_nonce' ), // Create nonce which we later will use to verify AJAX request
'afp_ajax_url' => admin_url( 'admin-ajax.php' ),
)
);
}
add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);
It means that your script is not included then or is not localized.
Btw, there is an updated version of this post here
Hi,
my case.
custom post type: employees
I will filter by category : office vienna, office budapest, …
use example from: https://wordpress.stackexchange.com/questions/213986/ajax-category-filter
i don’t know what i’m doing wrong
here are my files -> https://www.dropbox.com/sh/h2z3c98ejp9adj3/AACgv4-XbDbUfjs7WbMEswo1a?dl=0
Might be that either wp_head() or wp_footer() functions are missing.
hi vlado,
i include the two function and it fix the reference error for afp_vars, but it not working correctly for my case. I fixed my issue with using isotope.js to filter my posts.
hvala
Hello,
Only shows 1 post per category, can’t figure out what causes the issue. Thanks in advance.
Francis
There are few possible options:
– either you have only one post
– you have pre_get_posts filter somewhere active
– you are requesting only one post (inspect network for admin-ajax.php and check vars)
Hi Vlado, thank for this awesome tutorial, outstanding coding.
I wonder if you can help me. I would like to have a current-item class on the tax-filer links. Let say if a click on the taxonomy I would like to add a class to it and this class will be only for the current-item clicked a bit like we have on the wordpress wp_nav_menu links.
Thank you
Hi Nuno,
If you check this example: https://www.bobz.co/blog/demo-filter-wordpress-posts-custom-taxonomy-term-ajax
You will see that this already is highlighting selected item by applying “active” class to parent li element.
Also, please check the newer version of same post
BR
V