Adding a Tag Cloud to WordPress Pages
Fixing the “Add Tags and Category to Page” Plugin
We recently had a requirement from a client to add the tag cloud in WordPress to pages. Why is this a problem? You probably know that WordPress considers Pages as a type of content that’s distinct from Posts. What you might not know, however, is that it enables tags only for Posts — if you’re a Page, you get the tagging cold shoulder from WordPress.
But Our Client Wants the Pages Tagged!
What to do?! I found a plugin for WordPress called “Add Tags and Category to Page” — well, THAT sure sounds like what I need! And indeed, installing this plugin does some very nice things: It enables tags and categories for Pages, adds the controls to your Create/Edit Page page, and saves your tags when you save your page. Nice — I definitely did NOT feel like creating or altering the insert or update statements to the database for a page!
You did know there was a gotcha, though, right? Clicking on one of your page tags in the tag cloud doesn’t return any pages! As I needed this feature up and running quickly, I dove in — and here is what I found, and even better, how to fix it.
The Tag Archive Default
Left to its own devices, my theme happily uses tag.php to show tag archives for posts. Why weren’t the tagged pages showing up? It turns out that The Loop in its default query only checks Posts — not Pages. A-ha. NOW what? I don’t want to hack default functionality — that way lies madness! What I eventually decided on (and there may be a better way, so if you’re a WP expert please correct me!) was to keep the default Loop for Posts, and if there were no Posts with our tag THEN check pages. How? We need to make our own custom Loop, which I did in the “Else” case of the initial if(have_posts()) check.
Huh? The default tag.php structure starts with the Loop check for posts that are tagged with our desired tag, and looks kind of like this:
if ( have_posts() ) :
If there are posts with this tag, great! Do a bunch of stuff, and then exit the Loop when you’re done.
It didn’t find tagged posts, so show a message to that effect.
Okay, great. So, how do I get it to check Pages? Well, I stuck an elseif(have_posts() == 0) : in between the if and the else. I know that it will find no posts if I am looking for Pages (if it did, the ‘if’ condition would have fired), so it will always execute this new elseif block — and this is where you make your magic happen by creating your own Loop.
Here We Go, Loop-di-Loo!
WordPress bases its have_posts() test on the results of a query to the database that has certain default arguments, including a check ONLY of Posts. The default query ALSO parses the archive URL to determine what tag you’re searching for. With that knowledge, let’s create an argument array for the query that we will need to check Pages:
$args = array(‘post_type’=>’page’,'tag’=>$wp->query_vars['tag']);
Note that if you have changed the Permalink structure so that ‘tag’ is not in your URL for the tag archive, you’ll have to get the tag name on your own! In my case the default Permalink is what I use, so WordPress can parse that out for me. Lift with your brain, not your back! Now that your argument array is built, let’s use it to get our result set:
That’s it! Once again WordPress does the heavy lifting, and if there are Pages that are tagged with our tag you will be able to use Loop like you normally do — while ( have_posts() ) : the_post(), for example, along with all of the goodness that that brings.
So Long, Farewell
I hope this helps someone out in a pinch — none of it is rocket science, but it did involve a lot checking back and forth of the different functions and parameters in the WordPress Codex. One caveat you should be aware of with my method is that it’s going to show either all tagged Posts (first choice) or all tagged Pages — and never the twain shall meet. A better solution, really, is to not use the default loop at all and have it check Pages AND Posts in one query, which exercise I leave as an exercise for the reader. Enjoy!