If you're an advanced developer or just want the TL;DR version of this, skip to the code.

The majority of the time that I’m working on a contract project, there’s a need to programmatically create several parts of the website that occur during theme setup. Often times, this includes creating posts, users, and/or setting templates.

Ultimately, the goal is to make the user’s experience as nice as possible: They install the theme and the site, to a degree, has bootstrapped itself.

As with the aforementioned parts of a site, it’s also common to need to create a category, or categories, during theme setup. WordPress provides two ways of doing so, one of which often results in a PHP fatal error.

Here’s how to programmatically create categories in WordPress and do so without generating any errors.

On Inserting Categories

A quick Google search will likely lead you to the Codex article for wp_insert_category. At first glance, this looks to be exactly what’s needed to programmatically create categories.

Using this particular API function looks something like this:

function example_insert_category() {
	wp_insert_category(
		array(
		  'cat_name' 				=> 'Example Category',
		  'category_description'	=> 'This is an example category created with wp_insert_category.',
		  'category_nicename' 		=> 'example-category',
		  'taxonomy' 				=> 'category'
		)
	);
}
add_action( 'after_setup_theme', 'example_insert_category' );

Clear enough, right? The function accepts an array of arguments that are used to create the category.

If you define this function in your theme (or somewhere in a plugin), then load it up in a browser, you’re likely to see the following screen:

Programmatically Create Categories in WordPress - The Wrong Way

Oops!

Clearly, that isn’t what we wanted. Moar Chasen provided a good explanation as to why this happens in his comment.

That said, there is a second function that WordPress offers: wp_insert_term.

This particular function doesn’t result in the aforementioned error and I actually prefer it because it’s more flexible with what we’re looking to create.

Programmatically Create Categories in WordPress

Simply put, WordPress taxonomies are ways of classifying data. This means that Categories and Tags are both taxonomies despite the different ways that they are used.

Additionally, if you end up creating your own custom post types and want to create a set of custom taxonomies specifically for said post type, then the WordPress API allows you to do this.

To that end, using the wp_insert_term function allows us to programmatically create categories, tags, and other custom taxonomies.

For this reason, I’m a fan of using this particular function to create categories rather than anything else that WordPress offers.

To create a category based on the code defined earlier in this post, we’d make the following API call:

function example_insert_category() {
	wp_insert_term(
		'Example Category',
		'category',
		array(
		  'description'	=> 'This is an example category created with wp_insert_term.',
		  'slug' 		=> 'example-category'
		)
	);
}
add_action( 'after_setup_theme', 'example_insert_category' );

Refreshing the page will then yield the following results:

Programmatically Create Categories in WordPress

Ah, there we go.

There are a couple of nuances to using this function. Particularly:

Error handling is assigned for the nonexistance of the $taxonomy and $term parameters before inserting. If both the term id and taxonomy exist previously, then an array will be returned that contains the term id and the contents of what is returned. The keys of the array are ‘term_id’ and ‘term_taxonomy_id’ containing numeric values.

It is assumed that the term does not yet exist or the above will apply.

The rest can be reviewed in the Codex article.

At any rate, I’ve found that using wp_insert_term to be much more flexible and clearer when programmatically creating categories (and other taxonomies, obviously) in many of my projects.

Category:
Articles
Tags:

Join the conversation! 39 Comments

  1. Great writeupThe reason wp_insert_category() was not working in that example is because the it is defined in wp-admin/includes/taxonomy.php, and you were probably testing the code on the front-end. Anyways, wp_insert_category() is using wp_insert_term() to insert the term into the database, the only difference is that wp_insert_category() does some additional checks, for instance to make sure the term we’re about to insert does not already exist in the database (using term_exists()). Still, I am more of a fan of wp_insert_term() as it gives you some more more control.
    A great post as usual, Tom! :)

  2. The Important part of the programing to creat Create categories in WordPress and also wp_insert_term function allows us to programmatically create categories, tags, and other custom taxonomies.

  3. Is there any way to prevent user from deleting category?

    • There is and perhaps I’ll doa post on this soon, but it generally consists of having to check to see if a category that should exist, no longer exists.

      The problem is that if you get into this, you’re overriding what the user expects to happen which is what actually happens but results in a really bad user experience.

      I can only think of some very narrow ways to implement this so it doesn’t result in that.

  4. Nice tips, but call the function only once is enought with : after_switch_theme

    add_action( 'after_switch_theme' , myfunction_after_switch_theme' );

    Thanks

  5. who i can, pass param on this function =>

    add_action( ‘after_setup_theme’, array(&$this, ‘example_insert_category’ ) );

    i need call this function in other times, changing the name of category

    • Without more info, it’s hard to know how to answer the question, but you can define the function, allow it to accept parameters, and then call it within the context of other hooked functions.

      For example:

      function example_manually_insert_category() {
         example_insert_category(
            // Your arguments here
         );
      }
      add_action( 'after_theme_setup', 'example_manually_insert_category' );
      
      function example_insert_category( $args ) {
         // Code to create and insert the category
      }
      

      Hope this makes sense!

  6. Hey Tom, thanks for this post, it really helped me create some functionality that I needed for this big project I’m working on. I will repost what I did here because it might help someone in the future.

    Basically, the client will have a bunch of projects and on each project page there will be a custom WP_Query loop that shows blog posts ONLY pertaining to that project.

    So to make it seamless for the client I decided to use wp_insert_term to automatically send a category with the title of the project to my blog post custom post type taxonomy. Check it out.

    <?php
    //generate a category in Blog Posts for each project when it's published 
    function generate_category_from_title($post_ID) {
    	$title = get_the_title();
    	wp_insert_term(
    		$title,
    		'custom_cat_blogposts',
    		array(
    		  'description'	=&gt; 'This is the '.$title.' category',
    		  'slug' 		=&gt; $title
    		)
    	);
    }
    
    add_action( 'publish_projects', 'generate_category_from_title' );
    
  7. Hey Tom,
    Good tip! Thank you.
    Do you know a good way of re-naming already existing categories and custom taxonomy terms programmatically? I need to rename lots of categories and custom taxonomies on dev, staging and live site.. That’s why I wanted to find a way to do it programmatically: test it on dev and run it on staging and live sites.
    Any tips on that? I thought you might know or have done this before.

    Many thanks,
    Dasha

  8. Can any one know how to allow user to create sub account under them

    E.g.
    Family members account.

    In this account one main family member can create or add account for all family members..

  9. Question: what if one wants the terms to be translatable without changing their slug?
    By inserting terms using wp_insert_term() one could use gettext for the name label string __( 'Term name', 'textdomain' ) , however since the function registering all the terms is passed upon theme activation, that won’t do anything. I tried WPML, but WPML forces you to use different slugs for each language. Any clues on how to register/create terms and make them fully translatable without messing with the slugs?

    • Personally, I’m not sure – this is a use case that I haven’t encountered. At least not yet.

      If I end up encountering it, I’ll let you know; otherwise, that’s all I have to offer up right now :I.

  10. Heya,

    Perhaps you can help me out here.

    What I want it to do:
    install some default categories when I initialize my theme (and only then)

    What it does:
    installs the default themes all the time, even after the theme is activated. Result: if I have a default categorie “book” and I rename it to “books”, I have instantly two categories: “book” and “books”.


    function my_setup() {
    $catz = array("test1", "test foto\'s", "test / testing");
    foreach ( $catz as $cat ) {
    wp_insert_term(
    $cat,
    'category'
    );
    }
    }
    add_action( 'after_setup_theme', 'my_setup' );

    What goes wrong, and how can I get it right to only run the my_setup function once.

    • It sounds like you have two questions here:

      1. If you have a default category and you’re renaming it, then you need to first check that if a category exists.
      2. Based on your comment, it sounds like this is firing each time the theme is setup, correct? If that’s the case, that’s the correct behavior. What you’ll want to do is save an option in the database, after the initial creation, that all categories have been created. If the option returns true, skip the loop; otherwise, perform the loop.
  11. Hi, nice tip, thanks, but something stays a bit unclear for me yet…
    If I need to create let’s say, 170 categories, I’d include the wp_insert_term within a loop. Cool, but it sounds not right, it sounds like too many queries and in too short period of time to me…, is there a better way?
    thanks and keep going!! :)

    • There aren’t too many queries in a short period of time because everything in sequential in a loop.

      Another alternative is to do raw SQL to do that with a semi-long query; however, I highly recommend sticking with the native API as it will communicate with the core application and the database in ways that you may miss when constructing the query yourself.

  12. Hey it’s a good tutorial.
    But can you explain how to add sub categories into categories using the wp_insert_terms.
    This is a really challenging task.

  13. This is what I needed today, but I’m having trouble and I can’t figure out why.

    If I use your code as is, it works perfect and adds the Example Category to the Categories… but I want to add a term to a custom taxonomy I’ve created called Position. All I did was change line 4 from:
    ‘category’,
    to
    ‘position’,

    But it’s not working, and I’m perplexed. It’s probably something simple, but I’m missing it. Here is the code I’m using to register the taxonomy and insert the term, wondering if you can take a quick peek and tell me what I’m missing?

    function create_staffposition_tax() {
    register_taxonomy(
    ‘Position’,
    ‘staff’,
    array(
    ‘label’ => __( ‘Position’ ),
    ‘rewrite’ => array( ‘slug’ => ‘position’ ),
    ‘hierarchical’ => true,
    )
    );
    register_taxonomy_for_object_type( ‘position’, ‘staff’ );
    }

    add_action( ‘init’, ‘create_staffposition_tax’ );

    function example_insert_category() {
    wp_insert_term(
    ‘Example Category’,
    ‘position’,
    array(
    ‘description’ => ‘This is an example category created with wp_insert_term.’,
    ‘slug’ => ‘example-category’
    )
    );
    }
    add_action( ‘after_setup_theme’, ‘example_insert_category’ );

    Any help is appreciated!

    • Solved my own problem, just took a little finagling…
      I was missing a capital ‘P’ on position and then I fired them on the same hook with priority specified, and it worked. I never could get it to work on the after_theme_switch hook, it would list the taxonomy in the CPT, but when I tried to go to it, it would tell me it was invalid, so for now they are firing on init and it works.

  14. Very nice man! But, for a child terms?

  15. This does not seem to work for me. Is it because I am using AVADA framework?

    I tried it in a blank PHP with wp-load included and it doesnt either return an error or a result. Just nothing.

    • I don’t use Avada and I don’t know if it’s done something add to the add_setup_theme hook, but programmatically creating a category can be done in just about any hook permitting enough of WordPress has been loaded.

      The best option I can recommend is editing functions.php and trying it out with the hook as demonstrated in the code in this post. If that doesn’t work, then try using a different hook.

  16. Tom this is just great, and simple. I’ve been trying to unsuccessfully do this with wp_insert_category for about 3 hours, and went through the whole wordpress.Stackoverflow, and then I found this, which solved my problem. I would uprate this solution if I could :) Many thanks!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.