Custom taxonomies extra fields

As promised in how to – WordPress Category Extra Fields to explain how to add extra fields to WordPress Custom taxonomies I'm posting this after getting a few requests and question about it.

Some Background

WordPress does NOT have a term (taxonomy) meta data table in its database, and as I'm not a big fan of creating my own tables ( Don't get me wrong, in some cases i know its the smarter better way and you should not be afraid to create your own.) so i save my term meta in the options table - one row per term.
This takes into consideration that my site doesn't have 1000's of terms who need meta data , Only a few categories and few other custom taxonomy terms.

Let’s get started

basically we are are going to do the same thing we did to add extra fields to a category and only change the action Hooks.
So when we added fields to the "edit category" form we used

add_action("edit_category_form_fields" , "callback_function"); 

and and our callback function echoed out the extra fields. When adding extra fields to a custom taxonomy "edit term" form we use:

add_action( 'taxonomyname_edit_form_fields', 'callback_function', 10, 2);

and we replace "taxonomyname_edit_form_fields" with the actual taxonomy name followed by "_edit_form_fields".
For example if my taxonomy name is "skills" then my hook is going to be:

add_action( 'skills_edit_form_fields', 'callback_function', 10, 2);

Moving on to the callback function, In this case its about the same with a few minor changes:

<?php
//add extra fields to custom taxonomy edit form callback function
function extra_tax_fields($tag) {
   //check for existing taxonomy meta for term ID
    $t_id = $tag->term_id;
    $term_meta = get_option( "taxonomy_$t_id");
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="cat_Image_url"><?php _e('Category Image Url'); ?></label></th>
<td>
<input type="text" name="term_meta[img]" id="term_meta[img]" size="3" style="width:60%;" value="<?php echo $term_meta['img'] ? $term_meta['img'] : ''; ?>"><br />
            <span class="description"><?php _e('Image for Term: use full url with http://'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra1"><?php _e('extra field'); ?></label></th>
<td>
<input type="text" name="term_meta[extra1]" id="term_meta[extra1]" size="25" style="width:60%;" value="<?php echo $term_meta['extra1'] ? $term_meta['extra1'] : ''; ?>"><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra2"><?php _e('extra field'); ?></label></th>
<td>
<input type="text" name="term_meta[extra2]" id="term_meta[extra2]" size="25" style="width:60%;" value="<?php echo $term_meta['extra2'] ? $term_meta['extra2'] : ''; ?>"><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra3"><?php _e('extra field'); ?></label></th>
<td>
            <textarea name="term_meta[extra3]" id="term_meta[extra3]" style="width:60%;"><?php echo $term_meta['extra3'] ? $term_meta['extra3'] : ''; ?></textarea><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<?php
}

So our callback function outputs the fields HTML and checks if a value is already saved for this term in that field to display it, As you can see i added 4 new fields and all of them are in an array term_meta[key] because that way we only create on row in the options table to save all of the category’s extra fields instead of a row for each field.

Saving the Extra fields

Now that we can display the extra fields is nice but we still need to make WordPress save them. When we wanted to save the category extra fields we used the hook:

add_action ( 'edited_category', 'save_extra_fields_callback');

and when saving custom taxonomy extra fields we use:

add_action( 'edited_taxonomyname', 'save_extra_fields_callback', 10, 2);

so back to our example if my taxonomy is named "skils" my hook is:

add_action( 'edited_skils', 'save_extra_fields_callback', 10, 2);

Simple!

Moving on to the save_extra_fields_callback function, again its about the same with a few minor changes:

// save extra taxonomy fields callback function
function save_extra_taxonomy_fileds( $term_id ) {
    if ( isset( $_POST['term_meta'] ) ) {
        $t_id = $term_id;
        $term_meta = get_option( "taxonomy_$t_id");
        $cat_keys = array_keys($_POST['term_meta']);
            foreach ($cat_keys as $key){
            if (isset($_POST['term_meta'][$key])){
                $term_meta[$key] = $_POST['term_meta'][$key];
            }
        }
        //save the option array
        update_option( "taxonomy_$t_id", $term_meta );
    }
}

From the code above you can see that all of the extra fields we’ve added are stored in the database’s options table with the name ‘taxonomy_ID’ , where ID is the id of the specific taxonomy term we just edited and that means we can call this data in our plugins or theme files easily using the get_option function.

say for example my taxonomy term id is 25 then my code will look like:

$term_data = get_option('taxonomy_25');

DONE!

Before we finish

The whole code

<?php
//add extra fields to custom taxonomy edit form callback function
function extra_tax_fields($tag) {
   //check for existing taxonomy meta for term ID
    $t_id = $tag->term_id;
    $term_meta = get_option( "taxonomy_$t_id");
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="cat_Image_url"><?php _e('Category Image Url'); ?></label></th>
<td>
<input type="text" name="term_meta[img]" id="term_meta[img]" size="3" style="width:60%;" value="<?php echo $term_meta['img'] ? $term_meta['img'] : ''; ?>"><br />
            <span class="description"><?php _e('Image for Term: use full url with http://'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra1"><?php _e('extra field'); ?></label></th>
<td>
<input type="text" name="term_meta[extra1]" id="term_meta[extra1]" size="25" style="width:60%;" value="<?php echo $term_meta['extra1'] ? $term_meta['extra1'] : ''; ?>"><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra2"><?php _e('extra field'); ?></label></th>
<td>
<input type="text" name="term_meta[extra2]" id="term_meta[extra2]" size="25" style="width:60%;" value="<?php echo $term_meta['extra2'] ? $term_meta['extra2'] : ''; ?>"><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label for="extra3"><?php _e('extra field'); ?></label></th>
<td>
            <textarea name="term_meta[extra3]" id="term_meta[extra3]" style="width:60%;"><?php echo $term_meta['extra3'] ? $term_meta['extra3'] : ''; ?></textarea><br />
            <span class="description"><?php _e('extra field'); ?></span>
        </td>
</tr>
<?php
}

// save extra taxonomy fields callback function
function save_extra_taxonomy_fields( $term_id ) {
    if ( isset( $_POST['term_meta'] ) ) {
        $t_id = $term_id;
        $term_meta = get_option( "taxonomy_$t_id");
        $cat_keys = array_keys($_POST['term_meta']);
            foreach ($cat_keys as $key){
            if (isset($_POST['term_meta'][$key])){
                $term_meta[$key] = $_POST['term_meta'][$key];
            }
        }
        //save the option array
        update_option( "taxonomy_$t_id", $term_meta );
    }
}

After we defined our extra fields display function and extra fields save function we can use it for any taxonomy we want: category, post_tags or any custom taxonomy, all we have to do is add the two action hooks:

add_action( 'taxonomyname_edit_form_fields', 'callback_function', 10, 2);
add_action( 'edited_taxonomyname', 'save_extra_fields_callback', 10, 2);

For each taxonomy we want to add and use the extra fields.

Update

Since posting this How to i keep getting the asked the same question

how can i use this data in my theme?

Now i added a link to the WordPress Category Extra Fields how to at the top but since its some what different i'll post it here.
So to use the data you need just the id of the term so for example the current term if you are on a term archive :

$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ));
//so term ID
$t_ID = $term->term_id;

then once i have the term ID i get the data from the database

$term_data = get_option("taxonomy_$t_ID");

and now $term_data is an array with all of my extra taxonomy fields and i can use them in any way that i want,
for example say i have a field named img and it holds and image url so:

if (isset($term_data['img'])){
    echo '<div class="term_image"><img src="'.$term_data['img'].'"></div>';
}

Hope you get what I'm babbling about.

Update 2

I had a few people contact me by mail or here in the comments and ask about how to add the extra fields to the add new taxonomy term form and not just the edit term form so I'm posting this update.
The solution here is very simple just add this two hooks:

// this adds the fields
add_action('TAXOMONY_NAME_add_form_fields','extra_tax_fields' 10, 2 );	
// this saves the fields
add_action('created_TAXOMONY_NAME','save_extra_taxonomy_fields', 10, 2);

Hope this helps.

Ohad Raz

WordPress Consultant, a WordPress Developer and a WordPress Freelancer With over 10 years experience in architecting web sites and applications. WordPress Development moderator and somethimes Plugin Developer.