As promised, here is the code to the plugin.

It is a known fact that custom taxonomies and custom post types should go into a plugin, and not in your theme. I have stripped parts from my plugin.


The taxonomy is registered as normal through the plugin. For any info regarding this, you can go and check out register_taxonomy. The part that I needed to highlight and what is relevant to this question, is how to insert new terms.

To insert terms through wp_insert_terms are quick and easy, but this code can also hurt loading time if not used correctly. The idea is to run that function once, and then never again, almost like removing it after the first run.

To accomplish this, you are going to hook your function to register_activation_hook. This hook runs once, that is when the plugin is activated, it will not rerun on page refresh. The only time it will fire again is when the plugin is deactivated and activated again

So you first need to register your taxonomy as you can’t assign terms to a taxonomy that does not exists. Once your taxonomy is registered, you can insert your terms. Remember, this action will only take place once, and that is when the plugin is activated. If you need to add terms, you need to deactivate the plugin and activate it again

You want to also first check if a term exists before trying to create and insert it.

Here is the plugin code

Plugin Name: Create terms
Plugin URI: http://wordpress.stackexchange.com/q/163541/31545
Description: Create terms
Version: 1.0
Author: Pieter Goosen
License: GPLv2 or later
class Test_Terms {

    function __construct() {
        register_activation_hook( __FILE__,array( $this,'activate' ) );
        add_action( 'init', array( $this, 'create_cpts_and_taxonomies' ) );

    function activate() {

    function create_cpts_and_taxonomies() {

        $args = array( 
            'hierarchical'                      => true,  
            'labels' => array(
                'name'                          => _x('Test Tax', 'taxonomy general name' ),
                'singular_name'                 => _x('Test Tax', 'taxonomy singular name'),
                'search_items'                  => __('Search Test Tax'),
                'popular_items'                 => __('Popular Test Tax'),
                'all_items'                     => __('All Test Tax'),
                'edit_item'                     => __('Edit Test Tax'),
                'edit_item'                     => __('Edit Test Tax'),
                'update_item'                   => __('Update Test Tax'),
                'add_new_item'                  => __('Add New Test Tax'),
                'new_item_name'                 => __('New Test Tax Name'),
                'separate_items_with_commas'    => __('Seperate Test Tax with Commas'),
                'add_or_remove_items'           => __('Add or Remove Test Tax'),
                'choose_from_most_used'         => __('Choose from Most Used Test Tax')
            'query_var'                         => true,  
            'rewrite'                           => array('slug' =>'test-tax')        
        register_taxonomy( 'test_tax', array( 'post' ), $args );

    function register_new_terms() {
        $this->taxonomy = 'test_tax';
        $this->terms = array (
            '0' => array (
                'name'          => 'Tester 1',
                'slug'          => 'tester-1',
                'description'   => 'This is a test term one',
            '1' => array (
                'name'          => 'Tester 2',
                'slug'          => 'tester-2',
                'description'   => 'This is a test term two',

        foreach ( $this->terms as $term_key=>$term) {
                        'description'   => $term['description'],
                        'slug'          => $term['slug'],
            unset( $term ); 

$Test_Terms = new Test_Terms();


Your problem with inserting terms is your hook. after_setup_theme runs before init, meaning that you are trying to insert a term to a taxonomy that is not registered yet.

I would suggest that you move your wp_insert_term function to inside your init function, just below register_taxonomy

It is also advisable to first check if a term exists (term_exists) before inserting it


// Register Custom Taxonomy
function custom_taxonomy() {


   if( !term_exists( 'Example Category', 'layout' ) ) {
           'Example Category',
             'description' => 'This is an example category created with wp_insert_term.',
             'slug'        => 'example-category'

// Hook into the 'init' action
add_action( 'init', 'custom_taxonomy', 0 );

Please note, this is untested


Custom taxonomy names (and custom post type names) need to comply to a very specific set of rules, otherwise you will encounter pitfalls that there are no work around for.

Here is a guide line when choosing names for custom taxonomies (and custom post types)

  1. The following are not allowed in custom taxonomy names and custom post type names

    • Capital letters or camelcase

    • Any type of special character, except underscores (_)

    • Spaces

    • More than 32 characters for taxonomies and 20 for post types

    • Any reserved names, and please note, this goes for any custom naming convention, not just taxonomy names.

  2. If there are more than one word in a taxonomy name, they have to be separated by underscores, not hyphens (-). I have been challenged that hyphens are the way to go for SEO in URL’s for taxonomy names. It is true, that is why there are rewrite rules to adjust your URL accordingly. Never change taxonomy names or post type names for URL SEO purposes

Also, you should remove that weird capabilities. It might also create a problem

If this does not solve your issue, please add the code that you use with wp_insert_term


Leave a Reply

Your email address will not be published.