0

I want to add one custom field to Add new category (into WP-admin).The purporse of that field would be for icons (e.g user paste font-awesome icon class and it display icon on front-end).

Thank you.

1 Answer 1

0

This is going to be a ton of code and a ton of explanation. Most of which can be copy and paste but I suggest taking the time to understand what's going on and why. First thing to understand is that WordPress does not have Taxonomy Metadata but it may someday. This means that we need to save our data as options. Second thing to understand is that we have to deal with multiple hooks:

Whenever you see {$taxonomy} you would replace it with whatever you taxonomy slug is. In this example I will use the default / built-in Post Categories taxonomy whose slug is category.

The below will not cover adding the fields to Quick Edit or Add New Term Metabox.


Lets start with displaying the textbox to accept classes. Since both pages display their data differently ( and pass separate parameters ) we have to create two separate functions and assign them to {$taxonomy}_add_form_fields and {$taxonomy}_edit_form_fields respectively. Both are commented to point out anything our of the ordinary.

/**
 * Category "Add New" Page - Add Additional Field(s)
 * @param string $taxonomy
 */
function category_fields_new( $taxonomy ) {                             // Function has one field to pass - Taxonomy ( Category in this case )
    wp_nonce_field( 'category_meta_new', 'category_meta_new_nonce' );   // Create a Nonce so that we can verify the integrity of our data
?>
    <div class="form-field">
        <label for="category_fa">Font-Awesome Icon</label>
        <input name="category_icon" id="category_fa" type="text" value="" style="width:100%" />
        <p class="description">Enter a custom font-awesome icon - <a href="http://fontawesome.io/icons/" target="_blank">List of Icons</a></p>
    </div>
<?php
}
add_action( 'category_add_form_fields', 'category_fields_new', 10 );

/**
 * Category "Edit Term" Page - Add Additional Field(s)
 * @param Object $term
 * @param string $taxonomy
 */
function category_fields_edit( $term, $taxonomy ) {                         // Function has one field to pass - Term ( term object) and Taxonomy ( Category in this case )
    wp_nonce_field( 'category_meta_edit', 'category_meta_edit_nonce' );     // Create a Nonce so that we can verify the integrity of our data
    $category_icon = get_option( "{$taxonomy}_{$term->term_id}_icon" );     // Get the icon if one is set already
?>
    <tr class="form-field">
        <th scope="row" valign="top">
            <label for="category_fa">Font-Awesome Icon</label>
        </th>
        <td>
            <input name="category_icon" id="category_fa" type="text" value="<?php echo ( ! empty( $category_icon ) ) ? $category_icon : ''; ?>" style="width:100%;" /> <!-- IF `$category_icon` is not empty, display it. Otherwise display an empty string -->
            <p class="description">Enter a custom Font-Awesome icon - <a href="http://fontawesome.io/icons/" target="_blank">List of Icons</a></p>
        </td> 
    </tr>
<?php
}
add_action( 'category_edit_form_fields', 'category_fields_edit', 10, 2 );

The next step is to save our options. Since category creation and category edit will be handled the same way when saving, we'll use the same function for both. We still need to use the created_{$taxonomy} and edited_{$taxonomy}. As mentioned toward the top, since Taxonomy Metadata does not exist we have to save our data to the options table which needs a unique name. This is why we give our option a unique name of {$taxonomy}_{$term_id}_icon which, in this example, translates to category_1_icon.

/**
 * Save our Additional Taxonomy Fields
 * @param int $term_id
 */
function save_category_fields( $term_id ) {

    /** Verify we're either on the New Category page or Edit Category page using Nonces **/
    /** Verify that a Taxonomy is set **/
    if( isset( $_POST['taxonomy'] ) && isset( $_POST['category_icon'] ) &&
        ( 
          isset( $_POST['category_meta_new_nonce'] ) && wp_verify_nonce( $_POST['category_meta_new_nonce'], 'category_meta_new' ) ||        // Verify our New Term Nonce
          isset( $_POST['category_meta_edit_nonce'] ) && wp_verify_nonce( $_POST['category_meta_edit_nonce'], 'category_meta_edit' )        // Verify our Edited Term Nonce
        )
    ) {
        $taxonomy = $_POST['taxonomy'];
        $category_icon = get_option( "{$taxonomy}_{$term_id}_icon" );   // Grab our icon if one exists

        if( ! empty( $_POST['category_icon'] ) ) {                      // IF the user has entered text, update our field.
            update_option( "{$taxonomy}_{$term_id}_icon", htmlspecialchars( sanitize_text_field( $_POST['category_icon'] ) ) );     // Sanitize our data before adding to the database
        } elseif( ! empty( $category_icon ) ) {                         // Category Icon IS empty but the option is set, they may not want an icon on this category
            delete_option( "{$taxonomy}_{$term_id}_icon" );             // Delete our option
        }

    } // Nonce Conditional
} // End Function
add_action ( 'created_category', 'save_category_fields' );
add_action ( 'edited_category', 'save_category_fields' );

Finally, we need to clean up our options. Postmeta deletes itself when a post is deleted but Options do not. We need to manually delete these so that our options tables does not get bloated with orphaned options.

/**
 * Essential Cleanup of our Options
 * @param int $term_id
 * @param string $taxonomy
 */
function remove_term_options( $term_id, $taxonomy ) {
    delete_option( "{$taxonomy}_{$term_id}_icon" );         // Delete our option
}
add_action( 'pre_delete_term', 'remove_term_options', 10, 2 );

If we want to display each icon that has currently been assigned. Since we're generating a Unique Option Name using the Taxonomy and Term ID we would get the options using that same formula. First let's get our terms, then let's loop through our terms.

$terms = get_terms(            // Returns an array of Term Objects, 
    'category',                 // Pass our Taxonomy
    array(                      // Pass our Arguments
        'hide_empty' => false   // Show ALL Terms
    )
);

if( ! empty( $terms ) ) {           // Make sure we have some terms to loop through
    foreach( $terms as $term ) {    // Loop through each term
        $icon = get_option( "{$term->taxonomy}_{$term->term_id}_icon" );    // Use our formula to grab the Icon - This translate to "category_1_icon"
        echo "Category {$term->name} Icon: {$icon}<br />";                  // Display our Category Icon
    }
}
2
  • Thank you for detailed instructions. Please can you explain what to do with this {$term->term_id}_icon Apr 30, 2015 at 16:10
  • @Belmin - WordPress has an Options API which gets passed a Unique Name and Value that gets added the the database. We "generate" the unique name by combining the Taxonomy Name ( in this case category ) and Term ID ( maybe 1 ) along with a little descriptive label, in this case icon which combined looks like category_1_icon. I'll add an example on how to loop through the terms to get the icon in a few minutes.
    – Howdy_McGee
    Apr 30, 2015 at 16:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.