Filtering WordPress Categories Using an Undocumented Hook
In this article, we will briefly cover WordPress hooks and use an undocumented one in order to manipulate category listings.
After some further digging, while it is not listed on the WordPress filter list, it appears that this “undocumented hook” is mentioned on the get_terms() function reference. So, we’ll call this a somewhat undocumented hook.
Anybody who knows me knows that I love WordPress, if perhaps not more than any man should love a collection of code. I believe there are few projects for which it should not at least be considered.
Recently, I have been adapting WordPress to a large project with multiple authors/contributors. Each user would have a set of capabilities and restrictions. The most important of these was limiting users to certain categories. If this were my only need, the very useful Role Scoper plug-in would have worked wonderfully. However, there were a number of other requirements that Role Scoper did not meet, and the use of multiple plug-ins would likely confuse my not quite tech savvy clients. Therefore, I was forced to create my own solution that included the required category restrictions.
WordPress filters
WordPress generally makes it very easy to filter and adjust any data/output before it is sent to the end-user. This is done with Filters. Essentially, you are able to hook in to a number of pre-defined functions and pass the output to your own custom function. The code for achieving this is done so in the following format:
<?php add_filter( $tag, $function_to_add, $priority, $accepted_args ); ?>
Most important here are $tag, the function you want to hook into, and $function_to_add, your custom function that will filter the data provided. The other arguments are optional but more information can be found in the WordPress codex.
This code can be placed in the file for your custom plug-in or in the functions.php for your theme. For example, if you wanted the name of your blog to be red every time it appears in a post you could use the following code.
<?php add_filter('the_content', 'styleBlogName'); function styleBlogName($content) { $blogTitle = get_bloginfo('name'); $content = str_replace($blogTitle, '<span style="color: Red;">' . $blogTitle . '</span>', $content); return $content; } ?>
Here, we’ve added a filter to that will be called every time a theme calls the_content(), which outputs the content of a post. WordPress then passes the current content of the post to our styleBlogName() function. We use str_replace() to replace any instances of our blog title with a new version wrapped in a span we can style. Lastly, you have to remember to return the new value of $content, or WordPress will assume the post is blank. Pretty simple.
Every hook that we can attach to has different arguments. You can find a semi-complete list of these hooks in the codex.
The get_terms hook
WordPress is a huge project with an expansive code base. Unfortunately, there are a number of things that are not yet covered in the available documentation. And some of the things that are covered have been deprecated. During a sleepless night, while doing research on the project I described above, I was digging through the WordPress code and stumbled upon an undocumented filter hook, get_terms.
get_terms hooks into the function that retrieves all information about categories and is called in a large number of places throughout the WordPress code. For example, it is called whenever a theme calls the wp_list_categories() function, when listing the categories in the sidebar of the Edit Post screen in the admin panel, and many other places.
When hooking into this filter, WordPress will pass your callback function an array of objects, each object containing information about an individual category. To get a good idea of the data structure, insert the following code into the functions.php file of your current theme, visit a page of your blog that lists the categories, and view the source code.
add_filter('get_terms', 'restrict_categories'); function restrict_categories($categories) { echo "<!-- \n"; print_r($categories); echo "//-->\n"; return $categories; }
Making it work
Now that we understand the data structure, we can proceed to process it some way. There are limitless possibilities, so I’m going to keep my example simple and leave you to your own imagination. Imagine that you have a WordPress installation with one Admin and multiple Authors. You have a category called “Site News” that you only want the Admin to be able to post to. Therefore you don’t want the Authors to even be able to see it in the category checklist when composing a new post. Here is how you would achieve that by hooking into get_terms.
<?php // add_filter('get_terms', 'restrict_categories'); function restrict_categories($categories) { // If we are in the new/edit post page and not an admin, then restrict the categories $onPostPage = (strpos($_SERVER['PHP_SELF'], 'post.php') || strpos($_SERVER['PHP_SELF'], 'post-new.php')); if (is_admin() && $onPostPage && !current_user_can('level_10')) { $size = count($categories); for ($i = 0; $i < $size; $i++) { if ($categories[$i]->slug != 'site_news') unset($categories[$i]); } } return $categories; } ?>
We begin by checking that we are in the admin panel (so the ‘Site News’ category shows up on the main site), on the Add Post or Edit Post page, and are not an admin. If all these conditions are met, we iterate through the array of objects and check each category slug. If the slug is equal to ‘site_news’, we simply remove the object from the array. Return our new $categories variable and we’re done. You’ve now done something that many WordPress theme and plug-in developers aren’t even aware of. Way to go you.
Final thoughts
WordPress is ridiculously powerful and makes developing websites much simpler than was previously possible. While it has evolved into something far beyond your typical blog software, sometimes you have to get your hands dirty and dig through the code to truly unleash its power. While sites like Adam Brown’s hook reference have attempted to further document all the hooks available to theme/plug-in developers, there is still a lot to discover. Good luck and happy hunting!
19 Comments
Leave a Reply
About
Welcome to the blog of Ryan Marganti, the owner of SoulSizzle Design. I am currently booked until the end of time and not accepting freelance work. Contact me with any questions or comments.
Categories
Recent Posts
-
Create an Ajax Sorter for WordPress Custom Post Types
Create an AJAX sorter for WordPress custom post types
-
Adding Additional Image Sizes to WordPress Themes
Define and implement Wordpress images resolutions beyond the default Large, Medium, and Thumb sizes.
-
Manage a Boatload of WordPress Sidebars With Help From jQuery
Enhance the Wordpress dashboard with jQuery
-
Display a Different Number of Posts in WordPress Searches
Change the number of results shown in a Wordpress search
Just voted @talenthouse for Chris http://t.co/I1qRfAUh #ladyantebellum #
Very cool
Good
Thank you
[...] my article about the action hook’s sibling, the filter hook. Just click the following link: Filtering WordPress Categories Using an Undocumented Hook. Share and [...]
thanks, for the solution. i have not face similar request though. But i think i will need this someday
may i ask you ? this about almost similar situation. how do you delete a category from admin panel (categories.php) and also erase all of its child category / posts ?
cool thanks for posting this
[...] the article here: Filtering WordPress Categories Using an Undocumented Hook « SoulSizzle Design Tags: development, howto, tips, [...]
Thanks for this code. This is exactly what I need for a project I’m working on, where I need to set certain users to always have certain categories selected. I’d been rooting through the source code all day, googling… I’m going to modify your code to fit my needs. Thanks!
Is that what I think it is on that image, Ryan? Trying to be subliminal?
@Tim
Yes, a subliminal hippopotamus. Ha ha. Thanks for forever ruining my image.
[...] Eccolo qui: http://soulsizzle.com/wordpress/filtering-wordpress-categories-using-an-undocumented-hook/ [...]
[...] Good-Tutorials: PHP – Filtering WordPress Categories Using an Undocumented Hook: “A brief introduction to WordPress hooks followed by an example using an undocumented filter [...]
And he in fact bought me breakfast because I discovered it for him.. smile.
I’m not sure where you’re getting your information, but great topic. I needs to spend some time learning more or understanding more. Thanks for excellent info I was looking for this information for my mission.
I think keeping the design simple is much better than designing a complex-looking website on the cost of content.
Enormously revealing cheers, I think your trusty audience could quite possibly want considerably more well written articles along these lines continue the great hard work.
Truly educational cheers, I think your current visitors would possibly want further stories along these lines continue the good effort.
Rather illuminating appreciate it, It is my opinion your current readers will likely want a great deal more articles along these lines carry on the excellent hard work.
hello this is a good information poast I’ve learned something! This is what I was looking for my problem is now resolved thanks
Really educational thanks, I’m sure your current visitors could very well want way more stories of this nature continue the excellent effort.
Thank you very so much. Man You are a genius. Keep helping, Allah will help you.