9

So recently I moved a client from Blogger to Wordpress.

When the posts imported from blogger, it saved the blogger "labels" as "tags" in Wordpress. Since I'd like to have these as categories instead, I used a plugin to convert all tags to categories.

This worked fine and dandy, but it left Uncategorized on all of my posts. So now I have around 900 posts that all have their correct categories attached, as well as "Uncategorized".

So my goal is to remove "Uncategorized" from all 900 posts, but I'm struggling to find a speedy method to do this.

Does anyone know how I could accomplish this in a bulk method?

  • How does the code which displaying the categories look like? – MinhTri Jul 17 '16 at 5:25
  • There's no code, this is in the admin. – Corey Jul 17 '16 at 5:26
  • I think you just need to delete the Uncategorized category. – MinhTri Jul 17 '16 at 5:28
  • 1
    @Dan9, we can't just delete Uncategorized category it's the default post category assigned to posts when there is none assigned but we can this default by going to Settings-->Writing – bravokeyl Jul 17 '16 at 6:30
  • You need a category by default in WordPress. "Uncategorized" is the default category of WordPress. What i'd suggest, you can either change the default category from "Uncategorized" to one of your own, or you can change the name of the default category. – bagpipper Jul 17 '16 at 9:09
8

With wp-cli installed you can run a bash script like this to remove the 'uncategorized' category from all posts with more than one category

#!/bin/bash

for post in $(wp post list --field=ID)
do
  count=$(wp post term list $post 'category' --fields='name' --format="count")
  if [ "$count" -gt "1" ]
  then
    wp post term remove $post category 'uncategorized'
  fi
done

Save this as something like delete_uncategorized.bash and then run bash delete_uncategorized.bash from the command line.

  • wp cli is a good approach. – JMau Jul 17 '16 at 13:09
  • Does this require SSH access to the server the site is hosted on? I only have SFTP access as far as I know on WP Engine. I know they were beta testing WP CLI in the past but not sure of the status. – Corey Jul 17 '16 at 13:29
  • But basically I could probably just convert this method to a PHP script. – Corey Jul 17 '16 at 13:42
  • You could probably download the database to your local computer and run the script on it there. – Simon Cossar Jul 17 '16 at 14:22
4

Here's a plugin that upon activation, loops through all the posts that are in the uncategorized category. If it's in another category, it removes uncategorized. Further, when a post is saved, it does the same check.

<?php
/**
 * Plugin Name: Remove Uncategorized
 * Description: Removes the uncategorized category if there's another category.
 * Author: Nathan Johnson
 * Licence: GPL2+
 * Licence URI: https://www.gnu.org/licenses/gpl-2.0.en.html
 */

//* Don't access this file directly
defined( 'ABSPATH' ) or die();

register_activation_hook( __FILE__ , 'wpse_106269_activation' );

function wpse_106269_activation() {
  $args = array(
    'posts_per_page'   => -1,
    'offset'           =>  0,
    'category'         => get_option( 'default_category' ),
    'post_status'      => 'any',
    'suppress_filters' => true,
  );
  $posts = get_posts( $args );
  foreach( $posts as $post ) {
    wpse_106269_maybe_remove_uncategorized_category( $post->ID );
  }
}

add_action( 'save_post', 'wpse_106269_save_post', 10, 3 );

function wpse_106269_save_post( $id, $post, $update ) {
  remove_action( 'save_post', 'wpse_106269_save_post', 10, 3 );
  wpse_106269_maybe_remove_uncategorized_category( $id );
  add_action( 'save_post', 'wpse_106269_save_post', 10, 3 );
}

function wpse_106269_maybe_remove_uncategorized_category( $id ) {
  $categories = get_the_category( $id );
  $default = get_cat_name( get_option( 'default_category' ) );
  if( count( $categories ) >= 2 && in_category( $default, $id ) ) {
    wp_remove_object_terms( $id, $default, 'category' );
  }
}
2

A bit late to the party guys, but I just needed to do this myself. A workaround would be via SQL queries in phpmyadmin, something like:

SELECT *
FROM `wp_term_relationships`
WHERE `term_taxonomy_id`
IN ( SELECT `term_taxonomy_id`
FROM `wp_term_taxonomy`
WHERE `taxonomy` = 'category' )
GROUP BY `object_id`
HAVING ( COUNT( `object_id` ) >1 )

(replace wp_ prefix with your prefix) Usually "uncategorized" has a term_taxonomy_id = 1. The above query would group all the post ids where there is more than one category, so naturally "uncategorized" is displayed first in the grouping. So select all those rows that have a term_taxonomy_id = 1 and delete them. And that's about it!

Now all you have to do is edit the count field of "uncategorized" (term_taxonomy_id = 1) in the wp_term_taxonomy table. Count number is how many articles are listed in this category, but the specific field is not updated automatically.

If you go to your wp admin panel, categories section, the old (wrong) count number is still displayed, but if you press that number and go to the posts list of 'uncategorized', wordpress usually recounts the posts that are affiliated with that category. A correct count will be displayed on your top right, so go then into your db, and edit the count field accordingly :)

Edit: Actually, the count does get eventually updated, just not right away, so you may want to skip the manual count update.

0

Based on @TechSmurfy's answer I came up with this:

create temporary table tr_to_delete (object_id INT);
insert into tr_to_delete SELECT object_id FROM wp_term_relationships tr, wp_term_taxonomy tt WHERE tr.term_taxonomy_id=tt.term_taxonomy_id and tt.taxonomy='category' GROUP BY object_id HAVING COUNT(*) >1;
delete from wp_term_relationships where term_taxonomy_id=1 and object_id in (select object_id from tr_to_delete);
drop temporary table tr_to_delete;
0

Well, the easiest way without messing with the database is to create a new category, make that the default, then go into the posts list and sort by the 'uncategorized' category. Edit those posts and remove the 'uncategorized' category tag.

Once that is completed, you can delete the category. A category cannot be deleted if any post uses that category.

0

After messing around and trying all the approaches from above, I found that this sql query is the fastest way to remove posts from Uncategorized that have more than one cat.

Using WP-CLI would be the best option, if it wasn't slow as hell.

In my case I had to delete more than 50 000 term relationships, so it just FAILED.

DELETE FROM wp_term_relationships WHERE term_taxonomy_id=1 AND object_id IN ( SELECT object_id  FROM (
SELECT tr.object_id FROM wp_term_relationships tr, wp_term_taxonomy tt WHERE tr.term_taxonomy_id=tt.term_taxonomy_id and tt.taxonomy='category' GROUP BY tr.object_id HAVING COUNT(*) >1
) as temp_table);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.