Using some simple jQuery and PHP, we’ll create a Recent Posts widget that you can filter by category without an annoying page refresh. No need to create extra WordPress pages and templates! We’ll also apply a little jQuery animation so your container height will glide smoothly into place.
NOTE: For a loose example of this tutorial in action, check out the sorter on my legacy portfolio.
1. Create Your Template
First, we need to create a file called querySort.php and place the following code inside of it:
<?php
// load wordpress into template. dont touch me!
$path = $_SERVER['DOCUMENT_ROOT'];
define('WP_USE_THEMES', false);
require($path .'/wp-load.php');
// ah, wordpress is loaded. balance has been restored.
query_posts($_GET["query"]);
?>
<div id="queryContainer">
<?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?>
<!-- place your post template here. -->
<?php endwhile; ?>
<?php endif; ?>
</div>
This is your entire template for the widget’s output. By including wp-load.php, we’re able to avoid the annoying need to declare the file as a WordPress template, create an empty Page, and apply said template to it. The most important part of this file is this line:
query_posts($_GET["query"]);
Upon each load, query_post will grab our query from a variable that jQuery passes to it. This variable contains, by default, options for the number of posts and a default starting category.
Style the loop as necessary. As long as the div “queryContainer” and the loop are maintained, you may style the output any way you’d like.
2. Sprinkle in Some jQuery
Create another file called querySort.js and place the following code inside of it:
jQuery(document).ready(function($) {
// replace these default settings with your own
$.querySort = {
path_to_template: 'http://www.YOURSITE.com/wp-content/themes/YOURTHEME/',
number_of_posts: 5,
default_category: ''
}
// do the initial load.
$("#querySort").load($.querySort.path_to_template + 'querySort.php' + '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + $.querySort.default_category);
//functions for the sorter
$("#queryMenu a").click(function(){
var thecat = $(this).attr("id");
if (thecat == 'reset') {
var query = '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + $.querySort.default_category;
} else {
var query = '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + thecat;
}
$("#querySort").animate({opacity: 0}, function() {
$("#querySort").load($.querySort.path_to_template + 'querySort.php' + query, function() {
height = $("#queryContainer").height() + 'px';
$("#querySort").animate({opacity: 1, height:height});
});
});
return false;
});
});
Let’s break this down to make it easier to understand. Here are the default options provided by querySort:
$.querySort = {
path_to_template: 'http://www.YOURSITE.com/wp-content/themes/YOURTHEME/',
number_of_posts: 5,
default_category: ''
}
You’ll need to add the absolute path to the template you’ll be using this with (dont forget the trailing forward slash). If you’ve installed WordPress in a subdirectory, make sure to update the url to reflect that. Number_of_posts controls precisely the number of visible posts at a time, and default_category is only really necessary if you wish to limit the visible posts to a specific category and its children.
// do the initial load.
$("#querySort").load($.querySort.path_to_template + 'querySort.php' + '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + $.querySort.default_category);
This loads the default, unsorted query as soon as the DOM is ready. Using the .load() function, jQuery loads querySort.php, appending a variable called query, which is then accessed by the wordpress function query_posts(). The contents of the div #querySort are replaced with the results. (if you customize this script in any way to add more filters, be sure your query is urlencoded.)
//functions for the sorter
$("#queryMenu a").click(function(){
var thecat = $(this).attr("id");
if (thecat == 'reset') {
var query = '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + $.querySort.default_category;
} else {
var query = '?query=showposts%3D' + $.querySort.number_of_posts + '%26category_name%3D' + thecat;
}
$("#querySort").animate({opacity: 0}, function() {
$("#querySort").load($.querySort.path_to_template + 'querySort.php' + query, function() {
height = $("#queryContainer").height() + 'px';
$("#querySort").animate({opacity: 1, height:height});
});
});
return false;
});
This is where the magic happens. This function accesses the div holding your sorting options, grabbing the ID of your link and replacing the query’s category name with its contents. Next, it fades out the #querySort div, loads the results of the new query, then fades them back in, fluidly adjusting the height of #querySort to match the new height of your content. This prevents ugly flickers or large gaps beneath the widget.
That’s all there is to it. One more step, and you should have a working widget!
3. Add the Widget to Your Theme
Now, assuming you know where you’re going to place the widget, you have but to place the following markup in your theme and apply your desired CSS styles.
<div id="queryMenu"> <ul> <li><a href="#" id="categoryslug">Category Name</a></li> <li><a href="#" id="reset">All Posts</a></li> </ul> </div> <div id="querySort"> <!-- leave me empty. --> </div>
The #queryMenu div is very simple to set up. Each anchor you create must have to category’s slug as the id. This will be used by jQuery to execute the filter. IMPORTANT: To reset the sorter, create an anchor with ‘reset’ as the id. If, for some unimaginable reason, you have a category called Reset, you may want to change this to something else in your jQuery.
4. Enqueue and enjoy.
Upload your new files to your theme’s directory. Enqueue querySort.js and pat yourself on the back. You should now have a working jQuery sorter!
Mark Fasel said:
Exactly what I was looking for! Great tutorial!
Reply to comment
admin said:
Glad it was helpful! Please let me know if you have any issues. I threw this tutorial together late at night and I’m sure it could be improved upon.
Reply to comment
David Wood said:
This is exactly what I’m looking to do! Unfortunately I’m trying to alter a theme and I’m a bit of an amateur, having trouble implementing it. I’ve put the querySort.php into my theme folder and linked to it in the js file… as well as linking to the js file of course but it’s not working? HELP!
Reply to comment
admin said:
Hello David, if you have a link for me to check out I can try to troubleshoot it for you. Most of the time its a missing or misplaced div here or there! You can email me the link directly if you’d prefer and I’ll get back to you with an answer.
Reply to comment
David Wood said:
Could you link me to the source files? I have emailed you but I doubt you have the time to trawl through code!
Reply to comment
Tim Mon said:
Nice Job! Thanks for sharing this! Gorgeous site too… I like it.
Reply to comment
“The first man to compare the cheeks of a young woman to a rose was obviously a poet; the first to repeat it was possibly an idiot.”
twitter / facebook / rss