Posted on

Adding Custom Fields To The WordPress Category Interface

Adding custom field s to the WordPress Category interface can be tricky.  Not because the concept is overly difficult, but the documentation on the related filters and actions that are built into WordPress is hard to come by.    To make it even more challenging, some of the action names are built dynamically.     Thus I’ve created this post as my personal cheat-sheet guide to help jog my memory.

The notes here are based on my findings in WordPress 3.5.1.

There are 2 parts to the process, rendering the form fields and saving the data.

In the examples below, Replace {taxonomy} with the taxonomy ID.  If you are not sure what this is, hover over the “categories” link in the sidebar menu and look for the ?taxonomy={taxonomy} parameter in the URL after the edit-tags.php call.   For example, my Store Pages taxonomy is simply called ‘stores’ so my actions are create_stores and created_stores.

Rendering The Fields

There are two actions built into WordPress to manage the category interface, one for adding and one for editing a category.   Your function or method simply needs to output HTML for your new fields.  The actions are:

    • {taxonomy}_add_form_fields
    • {taxonomy}_edit_form

Saving The Data


The main “Categories” interface typically shows an “add category” form on the left side with a list of categories on the right.    This add category form uses AJAX to post the form data back to the server and save any new category you enter here.   This is why the page does not refresh.  As such you will have better luck deciphering what is going on with debug statements if you use a browser debug tool such as Firebug on Firefox and watch the console or net tab for the AJAX (AJAJ really) JSON posts and responses going to/from the server.

Action Hooks and Filters

The AJAX call posts back to ./wp-admin/edit-tags.php, which in turn calls the wp_insert_term method in ./wp-includes/taxonomy.php.

wp_insert_term calls the following actions while processing the insert:

If the slug is empty:

    • edit_terms with $term_id as the only param BEFORE the slug is added.
    • edited_terms with $term_id AFTER the slug is added

After the term is inserted into the term_taxonomy table:

    • create_term with $term_id, $tt_id, $taxonomy as params
    • create_{taxonomy} with $term_id, $tt_id as params
    • FILTER: term_id_filter with $term_id and $tt_id as params

The term cache is cleared and then these actions are called:

    • created_term with $term_id, $tt_id, $taxonomy as params
    • created_{taxonomy}  with $term_id and $tt_id as params

Useful Info

Most of the hooks and filters used to add data to the category interface can be implemented in the admin_menu action hook.  Using admin_menu() with a further admin_init() action hook buried within is one of the best ways to ensure all the setup, filters, roles & caps, and other “niceities” are in place before firing off your custom admin-centric hook or filter.

HOWEVER, you cannot attach your custom methods for the create_ or created_ action hooks deep inside admin_menu() or admin_init().  Why?  Because they run through the AJAX action stack and the AJAX action stack does not fire admin_menu().


So there you have it, my cheat sheet.   There are likely to be hiccups when implementing so don’t be afraid to add in some debugging code on your development system and be sure to check the JSON posts via the WordPress AJAX engine.


Posted on

WordPress – plugin does not have a valid header

We’ve run into this one a couple of times when publishing our WordPress plugins. If you look closely at the URL when that error message appears you will often find that you have a duplicate “main” file that launches the plugin. All plugins should have a single php file that “runs the show” and it should be named the same thing as the plugin subdirectory.

If you have a plugin named “Store Locator Plus” and it resided in the plugin directory store-locator-plus, then the main file in that directory should be called store-locator-plus.php. If that file is missing WordPress will try to guess, and often guesses wrong, what the starting file is. That is one source of the invalid header issue.

Another source that we recently ran into was the fact that we had multiple copies of store-locator-plus.php in our subdirectories. Duplicate copies were hidden down in the WPCSL-generic subdirectory. Like the Highlander, there can only be one. All duplicates must be destroyed wherever they live. The trick to getting rid of the “mutants” once you have published to the WordPress svn repository is to make sure you go into your local subversion directories and run the svn del <offending-file> first, then commit that back to the repo with svn ci -m 'There can only be one' command. Now your future updates won’t continue to clone/duplicate the errant file(s).

The other possible source of this problem, symlinks or shortcut directories that create the appearance of duplicate main files.

The bottom line, make sure your plugin subdirectories are clean and that there are no duplicate <my-plugin>.php files anywhere in the subdirectory structure.