Categories
WordPress

How to properly add extra fields to categories

Disclaimer: This will work for tags as well, you just have to replace category with tag.

Recently I had to add additional fields to a category taxonomy. I found a bunch of outdated posts on the Internet and I decided to create a post that will tackle this using modern techniques.

This article is based on WordPress 5.3.x and hopefully will be useful to you. Let’s dive in.

To add new fields to our taxonomy we will be using {$taxonomy}_add_form_fields and {$taxonomy}_edit_form_fields hooks, the first one fires after the Add Term form fields are displayed and the second one does the same but when we edit the taxonomy.

In order to use it with categories we need to replace {$taxonomy} with category.

Above hooks accept a callback function, which will display additional form elements, so let’s code it now.

<?php
add_action('category_add_form_fields', 'add_custom_field');
add_action('category_edit_form_fields', 'add_custom_field');

function add_custom_field($term) { 
    if(current_filter() == 'category_add_form_fields') {?>
        <div class="form-field">
            <label for="custom_title">Custom Title</label>
            <input type="text" value="" id="custom_title" name="custom_title" /><br />
            <p>Provide a custom title</p>
        </div>
    <?php } else if( current_filter() == 'category_edit_form_fields') { 
        $value = get_term_meta($term->term_id, 'custom_title', true);?>
        <tr class="form-field">
			<th valign="top" scope="row">
				<label for="custom_title">Custom Title</label>
			</th>
			<td>
				<input type="text" size="40" value="<?php echo esc_attr($value); ?>" id="custom_title" name="custom_title" /><br />
				<p class="description">Provide a custom title</p>
			</td>
		</tr>
    <?php }
}

We can use the same callback for both hooks, but since the form has a different HTML structure when you add and edit the taxonomy, we need to somehow differentiate between the views. In the code above we use current_filter() function, which retrieves the name of the current filter or action – in our case it will return either category_add_form_fields or category_edit_form_fields.

We are also using get_term_meta() function, which will retrieve the field we added.

Now, we want to save our custom field to the database. We need to use two more hooks in order to achieve that – created_category and edited_category.

Once again, both accept a callback function and once again, we can use the same function, so:

<?php
add_action('created_category', 'save_custom_field');
add_action('edited_category', 'save_custom_field');

function save_custom_field($term_id) {
	if(!isset($_POST['custom_title'])) {
		return;
	}

	update_term_meta($term_id, 'custom_title', sanitize_text_field($_POST['custom_title']));
}

We can easily use update_term_meta for both adding and updating the database, cause if the meta field for the term does not exist, it will be added automatically.

How to use it in your template?

get_term_meta(8, 'custom_title', true);

In the above example 8 is the ID of the taxonomy. For categories you can obtain it using get_queried_object_id() function.

Hope that post was helpful to you!