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:

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:

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.
Useful tip, thank you!
Of course – no problem!
Great writeupThe reason
wp_insert_category()
was not working in that example is because the it is defined inwp-admin/includes/taxonomy.php
, and you were probably testing the code on the front-end. Anyways,wp_insert_category()
is usingwp_insert_term()
to insert the term into the database, the only difference is thatwp_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 ofwp_insert_term()
as it gives you some more more control.A great post as usual, Tom! :)
Makes sense – and thanks for this!
Update the post linking to this comment, as well :).
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.
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.
Nice tips, but call the function only once is enought with : after_switch_theme
add_action( 'after_switch_theme' , myfunction_after_switch_theme' );
Thanks
Aha, nice catch. Thanks for this!
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:
Hope this makes sense!
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.Hey James – this is another great option.
Thanks for including the code for this. I really appreciate it – it’ll be good for others who stop by the site with a similar problem. Nice work!
Thanks Tom, I’m glad I could post something useful!
Anyway you could put my code into one of those sexy code boxes like you have throughout your post? It would probably be more useful that way. You can delete this comment either way, just wanted to check.
Cheers!
James~
Done and done! :)
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
Hey Dasha,
This is something I would probably do at the database level with a query against the taxonomy tables rather than doing it programmatically.
If you take a peek at the database, it shouldn’t be terribly difficult to come up with the `UPDATE` query to handle it for you.
Hope this helps!
Ah, genius! I’ve overlooked the SQL.
Thank you! :)
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..
Yep – just pass the ID of the parent category as the second parameter of the call to wp_create_category.
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.
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:
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.
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.
cool trick
thank’s
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.
Thank you very much
Very nice man! But, for a child terms?
Are you asking how to programmatically create child terms? Perhaps I’ll answer that in a future blog post. :)
How to use this code in any plugin to create New category and also relate it to current post
Your question is really outside the scope of this project and might be best asked somewhere like WPSE. The code in this post is also a little dated – it’s not that it doesn’t work, but it’s my approach to doing this would be a bit different now that I’ve more experience since I initially wrote it.
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.I see. So hard coding it with the example parems into functions.php? Thanks. Sounds like a good way to test it. =)
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!