While writing my Bulk Move WordPress Plugin, I faced a unique bug. I was breaking my head for nearly two days to find out the correct way to retrieve the categories of a blog post in WordPress. I thought of documenting it here so that I know where I can search for it in future, when I need it and also it might help other WordPress developers who are hunted by the same bug.
Let me try to explain what I was trying to do, why it failed and finally how I rectified it.
Well I was trying to retrieve all the blog posts which satisfy a certain condition and then loop through them and assign them to a new category.
I was using the following code to retrieve the blog posts which satisfied a certain condition. Note that that I am using the built-in WordPress API as much as possible and not directly querying the database. This is one of the good coding practices for writing WordPress Plugins.
$my_query = new WP_Query;
$posts = $my_query->query(array('category__in'=>array($cat_id1, $cat_id2), 'post_type'=>'post', 'nopaging'=>'true'));
Now the variable $posts will have an array of post objects. You can loop through them using foreach.
foreach ($posts as $post) {
print_r($post);
}
Will print
Array
(
[ID] => 33
[post_author] => 1
[post_date] => 2009-01-19 08:32:41
[post_date_gmt] => 2009-01-19 08:32:41
[post_content] => Test from Sudar...
[post_title] => Sudar Test
[post_category] => 0
[post_excerpt] =>
[post_status] => publish
[comment_status] => open
[ping_status] => open
[post_password] =>
[post_name] => sudar-test
[to_ping] =>
[pinged] =>
[post_modified] => 2009-02-04 17:54:10
[post_modified_gmt] => 2009-02-04 17:54:10
[post_content_filtered] =>
[post_parent] => 0
[guid] => http://sudarmuthu.com/?p=33
[menu_order] => 0
[post_type] => post
[post_mime_type] =>
[comment_count] => 0
)
If you look into the post object, you will see a column called post_category
. I was trying to retrieve the category/categories of the blog post by reading this variable. But to my horror, I was getting only zero as value in this variable.
After some hours of hair pulling, I posted about this in the WP-hackers mailing list. It was only then I came to know that post_category
is deprecated and we have to use other functions to retrieve the categories to which a blog post belongs to.
So the correct way to retrieve the category/categories is
foreach ($posts as $post) {
$post_cats = wp_get_post_categories($post->ID);
}
$post_cats
will be an array of category ids to which the blog post belongs.
So this is the complete code which you use to retrieve the list of categories to which a blog post belongs.
I didnβt know the fact that the post_category was deprecated and I learned it the hard way π
Even though the post_category
field is deprecated it is not entirely useless. It can be used while updating a blog post.
Letβs say that you want to move a blog post from one category to another. In this case you can set the array containing the category ids to post_category
field and pass it to the wp_update_post ()
function. Code snippet below
foreach ($posts as $post) {
$new_cats = array(5,10);
wp_update_post(array('ID'=>$post->ID,'post_category'=>$new_cats));
}
Whew!! Finally I know how the correct way to retrieve the categories to which a blog post belong to. π
Thanks for the post. Just looking for the same thing – however, wp_update_post didn’t seem to work. Instead, I noticed there is a function called wp_set_post_categories($postId, array(cat1ID, cat2ID, …)), which worked perfectly.
@Matt,
Nice to know that my post was of use to you. I didn’t know about wp_set_post_categories() function. I will try to use it and will update the post about it. Thanks!
Insert OMFG or variant thereof, about twenty times, at two in the morning. I’ve been fighting with WP all day to get it to do what I want, and the WP docs have been useless — maybe it’s just that most folks don’t really get into really doing wacky things like nested loops and whatnot, I suppose. I was about to give up when behold, the power of google dropped your post on my screen and NOW IT WORKS. I feel like a keyboard mash is due, or buying you a virtual drink, or SOMETHING. May have to settle for quietly dancing around the house in glee, given that it is two in the morning when most non-geeky souls are quietly abed. But not me! Must celebrate your awesomeness for helping me finally getting it to work! Thank you!!!
@Kaigou,
Wow!! It was really a nice feeling to know that my post was of soo much help to you. π Your comment has brought a nice big smile on my face and thanks for that π
Nice. The first result from Google searching for:
how to retrieve the category from a wordpress post
Excellent.
The main reason why I posted about this is that, people searching for the same problem could find out the solution. Nice to know that you found it out.
Pfiou you are the man ! thanks for the help π
God bless the web
Nice to know that it was of help to you.
And yeah, “God bless the web” π
Sudar,
Thanks a lot! That post really helps to get 50% of my problem solved. May i ask if you could help with the remaining 50%?
I use a category menu to navigate on my blog. I output this menu using :
wp_list_categories(‘child_of=55&sort_column=menu_order&sort_order=asc&title_li=’);
Now, if i look at one of the posts inside that category, that category is not highlighted in the category menu: the current-cat class is not added.
Am i doing something wrong or is this a bug?
Thanks a lot for your insight!
Alexandre
@Alexandre,
The above code will only output the list of categories. To highlight the current category to which the post belongs, you have to get the category of the current post in your single.php template of your theme and then add the corresponding highlight class to the category.
Hi Sudar,
Thank you very much for this post, this is pretty much what I’m looking for. Actually I’d like to move my wordpress blog to a Joomla platform. I found a plug-in that works only half, it does import the posts and the categories but it does not link the posts to the category.
Do you know how I could achieve this in PHP not using WordPress API.
Do you think I could use your code:
foreach ($posts as $post) {
$new_cats = array(5,10);
wp_update_post(array('ID'=>$post->ID,'post_category'=>$new_cats));
}
To add the category name to the field post_category since it has been deprecated and then with a simple query retrieve his field and assign it to the post’s category into the Joomla database.
Thanks again for this precious post.
Helio
@Helio,
I would recommend that you do it using WordPress API. If you are going to use WordPress API, then the above code will work.
great, i’m also have problem when i have to retrieve category of particular post. Now, i got what i need. thank you very much, especially wp_get_post_categories function is so dependable. I can use it in some early load hook such as pre_get_post…thanks
btw, while you got headache for two days, i got it for a day. hehehe just intermezzo
Love your blog!. I really enjoy reading all of the posts. Keep up the good work! π
I only know this plugin from your site. Thanks buddy for the cool information.
Thanks for the code..
Hi Sudar,
What a tip!
Thanks for your post, it was very helpful to me.
Best wishes from Brazil.
Tiago
Nice to know that it was helpful to you π
I was trying to do, why it failed and finally how I rectified it.
seems wordpress used new version…so, you do it failure ..^^ sr bad eng ..
Thank you for a so nice post,THx.
thanks your code, it’ so useful.
helpful! i don’t use this code on my wordpress. please help me
This post is in fact a nice one it helps new net viewers, who are wishing in favor of blogging.