The WordPress template tags were designed to give novice users the power of the PHP programming language in their page templates, and they work quite well for that.
Once you know a little PHP, however, using the template tags gets tedious for three reasons:
- most of the tags only work within The Loop, which prevents using them in your header, footer, or sidebar files
- most of the tags will only echo their result, which prevents you from capturing the result in a variable for further processing
- there are a lot of tags and it takes time:
- to figure out if there's one that does what you want
- if so, to figure out what all its parameters do and which ones you need
Once you've learned a little PHP, however, there is an interesting alternative. When your template is called, most of the information the template tags return is in the variable $wp_query, and all you have to do is dig out the information you want.
The variable $wp_query contains a PHP object. It takes some experience to get used to working with objects. They're similar to arrays, but because of a critical difference, you have to use a different syntax when you work with objects.
Instead of the $array[$key] syntax you use to get at the information in the cell of an array, with an object you use $object->$key.
And just as $array[$key1][$key2] works with multidimensional arrays, $object->$key1->$key2 works when objects are inside objects. In both cases the complete variable names become a lot like a URL, except that instead of the slashes in a URL, you use [] to offset the "folders" with arrays, and -> with objects.
The critical difference between arrays and objects is that items in an array can be referenced either by their name or by their position in the array. For example, $array[5] returns the item at that position in the array (the first position is at $array[0] and any position can be empty). Items in objects can only be referenced by name - they don't have a position or order.
Among other things inside the $wp_query object, you'll find an array that holds all the information in the database for each post to be displayed. The data for each post is in its own object. So you have a set of objects inside an array, which is inside an object. For example, the syntax to get the number of comments for the first of these posts is $wp_query->posts[0]->comment_count.
You'll also find a copy of one of these post objects at $wp_query->post. If you're inside the loop, this will be the post currently being worked on. Before the loop starts it's the first post in the array and after the loop stops it's the last post in the array.
It's quite helpful to be able to see everything that's in $wp_query. If you have a test site, you can add the following to your footer:
<pre> <?php print_r($wp_query); ?> </pre>
This prints the contents of $wp_query in a nice format at the bottom of each page. If you don't have a test site, change the <pre> tags to the HTML opening and closing comment tags, <!- - and - ->. In this case you'll have to view the page source to see what's in the array. Don't forget to remove this when you're finished looking, as it more than doubles the number of characters in most pages.
Here's an example of what you can do. WordPress always lists posts from newest to oldest. If this feels backwards to you on your monthly archive pages, where it might make more sense to list posts from the beginning of the month to the end of the month, put this at the top of your archive.php template:
<?php
if ($wp_query->is_month) {
usort($wp_query->posts,
create_function('$a, $b',
'return strnatcasecmp($a->post_date,
$b->post_date);'));
}
?>
This little bit of code first checks to see whether a variable in $wp_query named is_month is true. If it is, the archive template is about to display a list of posts from a particular month. This is our cue to sort the posts.
There's no simple PHP command to sort an array of arrays or objects by one of the items inside the arrays/objects to be sorted unless it's the first item, which it's not in this case, but the complicated code shown here works. I'd explain it, but I barely understand it.
I will say that if you wanted to sort an array of arrays rather than an array of objects, you'd have to change $a->post_date and $b->post_date to the format $a['post_date'].
I've also used $wp_query in my header template to set a robots meta tag and a description meta tag.
The robots tag tells search engines to follow the links on archive pages, but not to index them.
On pages that display a single post, I put the post's excerpt in the description tag using strip_tags($wp_query->post->post_excerpt).

[…] An elightning article for those who are still stepping outside the template tags of WordPress and into the more, PHP based coding possible in your templates. Definitely not for the beginner, and I'd love to see more of these type of posts. […]
Designing a WP addon for my wife's small business site, and was getting really frustrated at my inability to get at the guts before it was displayed on the page. New comments first was one bugbear, and your example about archive ordering was another.
This is superb info though, and I'm going to take a coffee and a bit of time to really get to know this aspect! A lot more confidence that I can get it all to work exactly as I want!
Thanks so much for sharing.