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.

  1. geilt

    Appreciate the tidbit. Was able to add this to my current “Database” class to allow for uploading if images as well as other misc text. Took your code and did it all by passing array params into the class and updating the right vars 😉

    Here is a GIST to work with your options in the template.

    https://gist.github.com/geilt/5546181

    • Pippin

      Very nice 😀

  2. Vivek

    Hi great one. But how can i apply sorting on get_terms by using this custom fields?

    like get_terms (‘orderby=”custom_order’);

    • Pippin

      That’s not possible with the API provided by WP, sorry.

    • geilt

      Actually, you could easily write a function that will do this for you.

      You can add “Term Order” as one of your new meta.

      Then just foreach through each one and reorder them into an array based on the Term Order

      Follow?

    • Pippin

      You can do that. I simply meant that there is not a core WP method for doing it already.

  3. Felipe

    Excellent tutorial!
    How do I get the custom field value on template? I’ve tried $term->custom_term_meta but it wasn’t work.

    Thanks

    • Pippin

      You will use get_option(), just like is showed in the save_taxonomy_custom_meta() function.

  4. ufuk

    Thx for tutorial but my little answer,

    how to get post list category term value ?

  5. shovan sargunam

    Awesome, would you include this option in the future Content Type Plugin? Would be great.
    I am going to try the manual method you have mentioned.

  6. Cognac

    Thank you so much! Really works:)

  7. Antonio

    Thank you for your excellent explanation!
    It will be very useful for me.

    Greetings from Spain!

  8. Wonderful tutorial. This is exactly what I was looking for. You hit the nail on the head with your first sentence, I had NO IDEA custom fields could be put on taxonomies. I was racking my brain for how I would store data about the taxonomy and then boom, there you are with your so perfect solution! Thanks for writing it up!

  9. Josh

    The best part is when I added the first code snippit to my functions.php and it broke it.
    Awesome tut. Lolz.

    • Pippin

      If you show me the error I’ll be happy to show you how to correct it. Most likely it’s due to a character encoding issue caused by copy and paste.

    • Austin

      Pippin, that’s awfully nice of you to treat a boneheaded remark like that. Just to re-iterate MY original comment, this was an extremely helpful tutorial. Thank you again.

  10. Ryan

    I’m having an issue trying to use my fields in a custom post type. I tried using the get_option(), but could really use an example?

    Follow up question – how would you use the data in the taxonomy “Name, Description, Slug” table?

    Thanks Pippin – great tutorial.

    • Pippin

      Could you show me your complete code?

    • Ryan

      http://pastebin.com/8ySUUQ4Z

      I finally got the code to work on my template – but now I need to display the custom fields in the custom columns.

      Thanks Pippin!!

  11. Rob

    And now what?
    How should I display that custom meta term (php echo) on my website/template?
    Please help!

    • Pippin

      Do you see my example for how to retrieve the value?

  12. Marco

    Will be honest.

    Added it and it broke. Do I need to install the plug in for this to work or not?

    Also a download link, would be superb, where all the code is. Copying this code isn’t nice (or have the button to make it plain text).

    • Pippin

      It probably broke because of a character encoding issue.

      Remember, this tutorial just shows how to do it. It does not provide a complete plugin that can just be used as is.

    • Marco Berrocal

      I had to go with a custom admin panel instead. But this is still a great concept. But the question remains, do I need the plug in or no?

    • Pippin

      This tutorial does not provide a plugin. You can put the code inside of a plugin if you wish, but it also works fine inside of a theme file.

    • Marco Berrocal

      Alrighty then. Thanks a buch pippin, I am going to give it another try come next time.

  13. Gomy

    Nice tut!

    But how can I show the custom term field on the post page?

    Thanks.

    • Pippin
      $t_id = 3; // You will want to retrieve this somehow
      echo get_option( "taxonomy_$t_id" );
    • Gomy

      Let me explain again.

      I have a custom taxonomy “site” associated with custom post “article”.
      Taxonomy “site” have a custom field.
      I want to see the custom field of taxonomy term “site” when I see the page with all articles and when I see the article single page. I know how to show the custom field in taxonomy archive.
      Is there any way to do that?

      Thanks

  14. Patrick Miravalle

    I was looking for a way to add a category tagline field that could be displayed on the archive pages, and this is exactly what I was looking for.

    Thanks man!

  15. Shannon Black

    Thanks for this, but rather than use get_option and update_option which stores in the options table, use the Metadata API. That’s what it’s for. Obviously this means you’ll need to make a new table in your database. named something like wp_taxonomymeta.

    See http://codex.wordpress.org/Metadata_API

    But your examples are the easiest to just be copy and pasted

    • Pippin

      This is much simpler than the meta dat API, since, as you said, an entirely new table would new to be created. If you are storing a lot of meta data, then sure, a new table is fine, but if you only need a few Values, this is probably better.

    • Shannon Black

      Yeah, this is definitely much easier and like I mentioned you can just copy and paste your tutorial and it works. But it’s always good to encourage best practice / standards over ease. So this is a great frontend developer tutorial as it accomplishes teaching some advanced stuff in the easiest form possible to accomplish some limited functionality on the end user. But regarding theme development if you go to /wp-admin/options.php you will now have a lot more data that is specific to objects than what should generally only be used by the Settings API or for storing site wide option meta. So my suggestion for the Metadata API is merely a nudge towards the WordPress standards way.

    • Jordan

      Hey there, I’m currently making a plugin that allows for a custom taxonomy to have a couple of input fields and was going to use your example, but I wanted to ask the drawbacks of using the options table, if any. I intend of having hundreds of tags in the custom taxonomy, each one with custom meta linked to it. I worry about how using the options table may negatively impact the database. Is it worth the effort to make the additional table and use the Metadata API? I’m not too worried about which is “more correct”, but rather which method would function better in a real world application.

      Thanks for sharing this guide, I was knee deep in the WordPress codex and online guides trying to write my own before I found this. Your efforts are much appreciated!

    • Pippin

      I wouldn’t be concerned about that here.

    • Jordan

      Just wanted to come back and drop a line on this topic. I recently wrote a plugin where two custom taxonomies needed to have about a dozen input fields each and I didn’t want to use the options table, even though it gets the job done. If anyone is interested in using a different table in the database to keep organized and be more within WP code standards, check out the article here:
      http://shibashake.com/wordpress-theme/add-term-or-taxonomy-meta-data

      It has the added perk of being able to use built-in WordPress functions such as “update_metadata” and “get_metadata” (which caches results, by the way) and is more inline with WP practices. Makes DB backups and site migrations easier.

  16. Bernardo

    Hi
    Thank you for the code, very useful!

    I am still getting an error when I try to save in the page “Add New Category”.
    I doesn’t refresh the screen after pressing the button “add new category”, if I do a browser refresh myself, the form gets clean and the field gets inside the right window with all the rest of the categories.

    Can help with this problem please?
    By the way I am using WP 3.6.1

    Thanks

    • Pippin

      Sounds like you have a jQuery conflict. Please try deactivating all of your other plugins.

  17. Pedro J. Carbonara

    Hi,
    Great tutorial! I’ve been trying to make this work, but can’t make the form save the data on the term. Please help!?
    Thanks in advance,
    Pedro.

    • Pippin

      Show me your code.

  18. Jennifer

    If I wanted to be able to choose from a custom field that currently exists on my Pages (I have created one called “ads” there using the standard WordPress Custom Fields boxes that display, so it must already exist in my database) and then enter a value for that field for my custom taxonomy, how could I link into that?

  19. Pedro J. Carbonara

    http://pastebin.com/DskwqMFu the taxonomy is called “personaje”, thanks for your quick response!
    The field shows up fine, boht in “add” and “edit”, but nothing happens on save, and the field is always blank.

    Thanks a lot!

    • Pippin

      If you change it to the default “post_category”, does it work on categories?

  20. Divyesh Prajapati

    Great Tutorial!!! It work’s really nice, I have used it in woocommerce for products category.

  21. Brian Martin

    Hi there.

    I was able to use the tutorial to create a custom meta field on my “authors” taxonomy. I want it to store contact-info. It works perfectly and I can create new authors or edit existing authors and populate the contact-info information. I only changed the example code so far to alter the display text and associate the custom meta field it with my own taxonomy.

    What I’d like to ask is, in the example, I am not sure what the example code is naming the custom meta field as, so that I can retrieve it later and present it on my taxonomy-authors.php template.If I use get_option I am not sure how to access the correct term ID for the custom meta field. Sorry if this is a stupid question.

    Could you shed light for me?

    Thanks so much, this is really great information and really useful.

    • Pippin

      You have to determine the term ID that the current item (the post) is filed into. You can use the get_the_terms() function to do that.

  22. Brian Martin
    • Tim

      Try adding the stripslashes function to line 9 of the save function:

      $term_meta[$key] = stripslashes($_POST[‘term_meta’][$key]);

    • Pippin

      Is it not working? What’s the error?

  23. Brian Martin

    Thanks Pippin, can I maybe rephrase as I am still not able to do what I want.

    For my custom taxonomy, I have no problem on an archive page to present the standard term information for my queried object (e.g. authors/beatrix-potter)

    I can use echo term_description(); to display the description field for her. I can use echo get_queried_object()->slug to display the slug or whatever other standard field. But I don’t know how to access the custom meta fields that your excellent tutorial helped me create for that particular term ID. I did a var_dump and I don’t see the information I populated for the custom field anywhere.

    • Jonathan

      Same boat here. Although I am able to view the data in an array with wp_load_alloptions(); so I know that the tutorial is working and information is being saved and can be used… somehow. Not quite getting how to output the specific values.

  24. mre

    thanks mate that really helped me

  25. Joe

    Hi Pippin. This technique has been working wonders for me. Thank you. However, I’m at the stage where I’m using far too much metadata to be handled by a Custom Taxonomy. I’m transferring my Custom Taxonomy and associated metadata to a Custom Post Type, where I’ll have more flexibility. I’m trying to write a function to export all metadata from Custom Taxonomy. To do so, I need to access the metadata for each entry in my Custom Taxonomy. This is where I’m stuck! How can I access all the metadata? My start is here: http://pastebin.com/v5LgZzcE

    • Pippin

      Your method should work fine. At what point are you stuck? Are you unsure of how to move it?

    • Joe

      Oh dear. I’m afraid I was quite stupid and started testing my code on a test site where the setup is a bit different, and the metadata doesn’t exist in quite the same way. You’re right, my code does work, so I’ll just mirror my site properly on my test server, and all will be good. Thanks again for your time.

  26. Tai

    Hi Pippen, can you show how to save from a select option list? thx!

    • Pippin

      There’s really no difference. What part of it are you unsure about?

    • Tai

      Ok, I think I got it workin. Does this look good Pippen?

      <option value="”>
      <option value="”>
      <option value="”>
      <option value="”>

    • Jordan

      @Justin – Thanks for the share!

  27. Jason Hoffmann

    Hey Pippin,

    This is awesome. Thank you.

    I’m trying to set something up where I can associate users with categories. Basically I’m outputting a list of user IDs as checkboxes for the metadata, but I can’t figure out how to save that data (as an array preferably). Here’s what I have so far:

    http://pastebin.com/iVHjUGi9

    Anyway you can help with the second part, saving the data with save_taxonomy_custom_meta( $term_id ) ?

    • Pippin

      First a question: have you successfully made the fields shown in this tutorial save and do you know follow how that works?

    • Pippin

      Great!

  28. Nadeem

    Great tutorial, can you tell me how can i show saved value in “archive.php” or “category.php” or “index.php” or “single.php”

    because i search a lot but i can’t find any solution 🙁

    • Pippin

      You will do it exactly the same way that the value is displayed in the edit screen for the term. Do you see and understand how that works?

  29. Kadimi

    I’m wondering if it’s possible to control the position of the new field(s).

    Thank you for this post.

Comments are closed.