It is pretty common knowledge that custom meta fields can be added to posts, pages and custom post types, but did you know that you can add custom meta fields to post tags, categories, and custom taxonomies as well? It’s actually pretty simple, though relatively undocumented. So in this quick tutorial I’m going to walk you through the process of added some custom meta fields to taxonomy. These meta fields can be used for a variety of purposes, but one of my favorites is the Taxonomy Images plugin by Michael Fields.
With WordPress 4.4, there will be a native “terms metadata” table in WordPress, so this is no longer a necessary or valid method of adding customer metadata to terms.
See here for more information: https://make.wordpress.org/core/2015/09/04/taxonomy-term-metadata-proposal/
Adding custom meta fields to a taxonomy requires three separate functions: one to add the field to the Add New page; one to add the field to the Edit Term page; and one to save the values of the custom field from both pages. This first function will add a custom field to the Add New page for the default Category taxonomy.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php // Add term page function pippin_taxonomy_add_new_meta_field() { // this will add the custom meta field to the add new term page ?> <div class="form-field"> <label for="term_meta[custom_term_meta]"><?php _e( 'Example meta field', 'pippin' ); ?></label> <input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value=""> <p class="description"><?php _e( 'Enter a value for this field','pippin' ); ?></p> </div> <?php } add_action( 'category_add_form_fields', 'pippin_taxonomy_add_new_meta_field', 10, 2 ); |
There is nothing special about this function. It’s just an HTML form that uses the same layout as the default WordPress add new term page fields. One thing to note, however, is that I have setup the name of the input to be an array. This is important for our save function. If the field name was not an array, then we’d have to save each field individually in the save function, but as an array, we can simply loop through the fields and save each one automatically.
Also take note of the add_action():
add_action( 'category_add_form_fields', 'pippin_taxonomy_add_new_meta_field', 10, 2 ); |
The first parameter is what determines the taxonomy that this field gets added to. It uses this format: {$taxonomy_name}_add_form_fields. So if you wanted to add the field to your “genres” taxonomy, you would use:
add_action( 'genres_add_form_fields', 'pippin_taxonomy_add_new_meta_field', 10, 2 ); |
You will now have a field that looks like this on the Add New term page:
The second function we need is the one that adds the HTML to our taxonomy Edit Term page. It looks very similar, though the HTML layout is a little different, and we also have to do a check to see if the meta field has any data saved already, so that we can populate the field on load.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php // Edit term page function pippin_taxonomy_edit_meta_field($term) { // put the term ID into a variable $t_id = $term->term_id; // retrieve the existing value(s) for this meta field. This returns an array $term_meta = get_option( "taxonomy_$t_id" ); ?> <tr class="form-field"> <th scope="row" valign="top"><label for="term_meta[custom_term_meta]"><?php _e( 'Example meta field', 'pippin' ); ?></label></th> <td> <input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="<?php echo esc_attr( $term_meta['custom_term_meta'] ) ? esc_attr( $term_meta['custom_term_meta'] ) : ''; ?>"> <p class="description"><?php _e( 'Enter a value for this field','pippin' ); ?></p> </td> </tr> <?php } add_action( 'category_edit_form_fields', 'pippin_taxonomy_edit_meta_field', 10, 2 ); |
First, we have passed the $term parameter to our function. This variable will contain the database object for our term. The only information we need for our function is the term ID, so we put that into a variable to make things easy. We then use the get_option() function to retrieve the value of out term meta. Note, all term meta is stored in an array in the option named “taxonomy_{$term_id}”. So to get the value of our specific meta field, we’d use $term_meta[‘custom_term_meta’];
The results of this function will look like this:
Next is our save function. This will take the value entered in the field and store it in the taxonomy option.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // Save extra taxonomy fields callback function. function save_taxonomy_custom_meta( $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 ); } } add_action( 'edited_category', 'save_taxonomy_custom_meta', 10, 2 ); add_action( 'create_category', 'save_taxonomy_custom_meta', 10, 2 ); |
The function takes the ID of our term as a parameter. A quick check if performed to make sure that data is being sent from our custom field, and if it is, the current value of the field is retrieved from the database. Next, each of our custom fields (remember, we can setup more than one in a single array) is looped through. In the loop, each of the field values is inserted into the $term_meta array. Once the loop is complete, the taxonomy option is updated, storing our field values in the database.
Just like with the first two functions, the save function is tied to our particular taxonomy with an add_action() hook, and, again with the genres example, if you attached your fields to a taxonomy called “genres”, then you would use these hooks:
add_action( 'edited_genres', 'save_taxonomy_custom_meta', 10, 2 ); add_action( 'create_genres', 'save_taxonomy_custom_meta', 10, 2 ); |
That’s it! The process is really pretty simple.
If you’d like to see a real world example of what you can do with these kind of meta fields (I already mentioned a plugin at the top), check out the Fotos theme by my buddy AJ Clarke. He has password protected photo galleries. The password is set via a taxonomy custom field for the gallery categories. I had the pleasure of building the system for him, so I can tell you first hand how well it works. I’d highly encourage you check it out.
This is a great tutorial and something I’ve been searching for. I am very new to wordpress and so am not familiar with the worpress framework. My question is where should I add these functions?
Kim B, you should add this code in your theme’s functions.php file
wordpress is not a framework but a foundation. Zend, Code Igniter , YII are frameworks like .NET is in Microsoft.
Anyone having problems retrieving the values on a custom taxonomy archive page may find the following useful:
$t_id = get_queried_object()->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
echo $term_meta['custom_term_meta'];
Thanks, Pippin.
Thanks, I really need this code.
Thanks so much man, you just save my day!
Can I add single or multiple image field(s) using this function?
Yes, definitely, you will just need to tweak the HTML and the save routine accordingly.
Thanks for the great post!
I understand how to pull the meta data using the get_option function, as you described:
$t_id = 3; // You will want to retrieve this somehow
echo get_option( “taxonomy_$t_id” );
Is there any way to do the reverse? If I know what the meta data value is for a given category, is there a way to get the associated category ID? Thanks!
You could get that by doing a custom select query using the wpdb class. Are you familiar with that?
Not 100%. After doing some reading online, I get the basic idea. But when I do something like:
`$category = $wpdb->get_row(“SELECT * FROM $wpdb->term_taxonomy WHERE TAXONOMY = ‘category'”);
print_r($category);`
I don’t see the custom meta as one of the options. Could you point me in the direction of a good tutorial that might help me pull the information I’m looking for from the database?
Thanks again!
I saw that Edward posted something about actually retrieving the value on a custom taxonomy archive page, but does anyone know how to retrieve it on a single.php page?
You could add something like this within the loop or use what Edward posted.
“`
$terms = get_the_terms( $post->ID, ‘category’ );
$term_meta = get_option( “taxonomy_$terms->term_id” );
echo $term_meta[‘custom_term_meta’];
“`
Thanks Ulrich, it doesn’t seem to be working. Below is what i’m doing:
‘name’,
‘order’ => ‘ASC’,
‘taxonomy’ => ‘locations’,
);
$terms = get_the_terms( $post->ID, ‘category’ );
$term_meta = get_option( “taxonomy_$terms->term_id” );
$categories = get_categories($args);
foreach($categories as $category) {
echo ‘‘ . $category->name . ‘ ‘;
echo ” . $category->description . ”;
echo ” . echo $term_meta[‘custom_term_meta’] . ”;
}
?>
I can’t seem to get it to work. Any help would be great!
Thanks again!
@Joe this should work
‘name’,
‘order’ => ‘ASC’,
‘taxonomy’ => ‘locations’,
);
$categories = get_categories($args);
foreach($categories as $category) {
$term_meta = get_option( “taxonomy_$category->term_id” );
echo ‘‘ . $category->name . ‘ ‘;
echo ” . $category->description . ”;
echo ” . echo $term_meta[‘custom_term_meta’] . ”;
}
?>
Hi!
Great tutorial Pippin!
Unfortunatelly I can’t make the results will be visible on the single.php page.
I tried Edward and Ulrich solutions and they don’t seem to work in my case.
The below code shows only name and description of my custom taxonomy but no custom_term_meta…
$terms = get_the_terms( $post->ID , ‘author’ );
if($terms) {
foreach( $terms as $term ) {
echo $term->description.”;
echo $term->name.”;
$term_meta = get_option( “taxonomy_$terms->term_id” );
echo $term_meta[‘custom_term_meta’];
}
}
Any help?
Try replacing $post->ID with get_the_ID()
Hi,
Thank you very for your code, it’s really great and simple.
Like I’m not a good developer at all, could you give some clue to add a single image using your function ?
Thks !
Hi pippin,
Thank you very much for this tutorial mate. This helped me a lot in a project for one of my customers.
Managed to get to create an image uploader for any taxonomy and display it in the front and backend of the plugin.
Cheers !
Jerome.
Hi Jerome,
Would you please share your snippet to add an image uploader for taxonomies? I am looking to find this solution for one of my projects. Thanks.
Leo
Hi,
how can I change/add priority in admin?
How can I add the wp-editor to custom field (textarea) based on this example?
Thanks
I’m not sure what you mean, could you elaborate?
Hello,
I create custom field for taxonomy product_cat (product category for Woocommerce).
1) How can I change/add priority of this custom field in administration – I mean position of custom field in administration category between other fields (under/above the term-description). For meta fields you can use the priority = normal/high/ … and here?
2) How can I add the wp-editor to this custom filed? I tried add editor (tinymce) using wp-editor ( http://codex.wordpress.org/Function_Reference/wp_editor ) or jQuery but without success.
Thanks
I am slightly confused. Will users will be able to pass a hidden custom value directly to the “category” posts section. This is what I’m trying to accomplish: A user fills out a gravity form. I don’t want them to have to choose the category. I want to choose it for them without going into wordpress and choosing it for them. I want that form to pass it on to the category “specified” section. Can I accomplish this with this function?
Not without further custom development, sorry.
Hey Pippin,
great code! Helped me a lot setting up additional fields for taxonomy terms in the backend.
Returning the additional field for the current term in taxonomy.php works as well.
But I also have a tree-like navigation on single-taxonomy_name.php, archive-taxonomy_name.php and taxonomy.php that displays a hierarchical list of all terms. I also want to show additional fields content here, but can’ t wrap my head around how to do that. Simply returning $term_meta[‘custom_term_meta’] doesn’t seem to do the trick.
Here’s a basic version of my walker. Any ideas?
Thanks very much!
function return_terms() {
$taxonomies = array( ‘taxonomy_name’ );
$args = array(
‘orderby’ => ‘name’,
‘order’ => ‘ASC’,
‘hide_empty’ => false,
‘fields’ => ‘all’,
‘parent’ => 0,
‘hierarchical’ => true,
‘child_of’ => 0,
‘pad_counts’ => false,
‘cache_domain’ => ‘core’
);
$terms = get_terms($taxonomies, $args);
$term_meta = get_option( “taxonomy_$terms->term_id” );
$return .= ”;
foreach ( $terms as $term ) {
$return .= sprintf(
‘%2$s ‘ . $term_meta[‘custom_term_meta’] . ‘%3$s’,
$term->term_id,
$term->name,
$term->description
);
$return .= ”;
}
$return .= ”;
Since this is being actively used, people should know that this method will potentially break with the eventual shared term splitting currently scheduled for WordPress 4.2. Terms in multiple taxonomies sharing the same slug/name will be issued new IDs and the associated meta won’t be retrieved correctly.
Some of the discussion can be found here, for those who are interested:
https://core.trac.wordpress.org/ticket/30335
There’s a small issue with the code that displays the custom fields on the Edit page:
<input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="”>
I think you meant for the esc_attr method that is used in the ternary check to be a call to isset() instead.
Hey Pippin,
thank for the great piece of code.
One question, I need to use this with a multiple-select field, as right now, this code will save only the last option selected.
Is there a way to easily accomplish this? Could you point me in the right direction?
Thanks again for the code
Have a nice sunday
Can you please show us to do the same thing for custom taxonomies?
ohhh my bad… I just saw it.
It works exactly the same way.
Hi Pippin
Can you show the code for how to do this for checkbox where we have to save multiple values.
Hi , its not saving value on update. how to save value on updating the taxonomy? i am working on custom taxonomy.
Could you show me the exact code you’re using?
Hi, very nice tutorial. I have saved my meta text for custom taxonomy. How can I show this meta of that custom taxonomy in a custom post ?
You can do that by using the get_option() function with the same key as you used in update_option().
How would I print the input for this field as a HTML line somewhere?
Could you be a bit more specific about what you’re trying to do?
Hey Pippin,
I’y for question it againt.
I need to use this with a multiple-select field, as right now, this code will save only the last option selected.
Is there a way to easily accomplish this? Could you point me in the right direction?
Thanks again for the code
Have a nice weekend
For a multi-select, add [] to the name attribute.
Thanks
thank’s a lot…is simple custom taxonomies… 😀
How to add upload image field?
I would love to know how to include checkboxes using the above method. I cannot figure out how to save them. Thanks
Check boxes will use the array notation: http://stackoverflow.com/questions/1010941/html-input-arrays
Hi i really really need your help with this.
I am trying to implement the same thing but for tags, i noticed that anytime it gets to this line
$term_meta = get_option( “taxonomy_$t_id” );
it will fail and return NULL. So When i go into editing the tag… the custom field value is not showing. i figured for tags implementation it might be a different name with taxonomy_$t_id…but i have searched and searched, nothing… Would really appreciate an answer asap as i have a deadline. Thank you
If you can show me the complete code you’re using, I can try and identify why it’s failing.
Posted the code, hope you saw it.
Final try… full code is here
http://scripton.net/_files/tag.txt
The only difference is changing the hooks which are different from categories
This:
add_action( ‘category_add_form_fields’, ‘pippin_taxonomy_add_new_meta_field’, 10, 2 );
add_action( ‘category_edit_form_fields’, ‘pippin_taxonomy_edit_meta_field’, 10, 2 );
To:
add_action( ‘add_tag_form_fields’, ‘pippin_taxonomy_add_new_meta_field’, 10, 2 );
add_action( ‘edit_tag_form_fields’, ‘pippin_taxonomy_edit_meta_field’, 10, 2 );
Can i also assume. the Save function will work out of the box? or would i need tweeks there too?
Hello and hope all is well. Were you able to see the code i provided? Please let me know. Thank you!
THANK YOU FOR TRYING TO HELP. I JUST FIGURED IT OUT.
Glad to hear it!
OK so i’m good with these changes:
add_action( ‘add_tag_form_fields’, ‘pippin_taxonomy_add_new_meta_field’, 10, 2 );
add_action( ‘edit_tag_form_fields’, ‘pippin_taxonomy_edit_meta_field’, 10, 2 );
In fact I’d already figured those out based on something I already read someplace else. The issue(s) I have are related to the saving of data. What changes are needed to actually get the data to save?
That’s shown above in the tutorial.
add_action( 'edited_genres', 'save_taxonomy_custom_meta', 10, 2 );
add_action( 'create_genres', 'save_taxonomy_custom_meta', 10, 2 );
Replace “genres” with “post_tag”
how to create boxpost in custom taxonomy
Everyone, I have disabled further comments on this post as the methods described here are largely out of date.
With WordPress 4.4, there will be a native “terms metadata” table in WordPress, so this is no longer a necessary or valid method of adding customer metadata to terms.
See here for more information: https://make.wordpress.org/core/2015/09/04/taxonomy-term-metadata-proposal/
Really interesting article and I see a couple of folks are having some problems. If you put the code into functions.php inside of a custom plugin – that should work for you.