Guide

How to Add and Update Images for Categories in WordPress

28 AUG 2022

Categories are a taxonomy type in WordPress. By default, they do not have any image associated with them.

But you can add a custom image field to a category and use it to store and show an image for the same.

You can add an image to a category in two places – first when you are creating the category and next when you are editing the category.

In both cases, you can add a custom image upload button for the image.

Adding an image upload button to the add category screen

Use the action hook category_add_form_fields to add a new custom field to the add new category screen using a callback function.

add_action( 'category_add_form_fields', 'category_add_form_fields_callback' );

The callback function is category_add_form_fields_callback and you can use it to add a custom image upload button.

function category_add_form_fields_callback() {
    $image_id = null;
    ?>

    <div id="category_custom_image"></div>
    <input 
          type="hidden" 
          id="category_custom_image_url"     
          name="category_custom_image_url">
    <div style="margin-bottom: 20px;">
        <span>Category Image </span>
        <a href="#" 
            class="button custom-button-upload" 
            id="custom-button-upload">Upload image</a>
        <a href="#" 
            class="button custom-button-remove" 
            id="custom-button-remove" 
            style="display: none">Remove image</a>
    </div>

<?php 

}

This code will generate a custom image upload field at the bottom of add category form like this –

WordPress has a jQuery based media uploader. Why the default media uploader? Because the media uploader gives us an easy interface to upload media and can be implemented with very few lines of code.

We are going to use that with this upload button.

Create a JavaScript file uploader.js and put the following code in it –

jQuery(function($){
    $('body').on('click', '#custom-button-upload', function(e){
        e.preventDefault();
        obj_uploader = wp.media({
            title: 'Custom image',
            button: {
                text: 'Use this image'
            },
            multiple: false
        }).on('select', function() {
           // your code here
        })
        .open();
    });

    $(".custom-button-remove").click( function() {
       // your code here
    });

});

You will also need to enqueue the file on admin side.

add_action( 'admin_enqueue_scripts', 'admin_enqueue_scripts_callback' );
function admin_enqueue_scripts_callback() {

// WordPress media uploader scripts
    if ( ! did_action( 'wp_enqueue_media' ) ) {
	wp_enqueue_media();
    }
// our uploader.js 
    wp_enqueue_script('uploaderjs', get_stylesheet_directory_uri() . '/uploader.js', array(), "1.0", true);
}

In the callback function admin_enqueue_scripts_callback we are calling wp_enqueue_media which will make the default media uploader available.

Then in wp_enqueue_script we are enqueueing the script uploader.js. Note that get_stylesheet_directory_uri() is used to get the URL of the script because in this case the script is in the theme directory.

You may change the URL as required.

Then in the last parameter the value is true. This is IMPORTANT because the uploader.js script is dependent on jQuery and WordPress default JavaScript object called wp.

If the parameter value is not set to true then the script will appear at top of the page.

Since WordPress admin side JavaScript libraries are loaded at the footer, the jQuery libraries and wp object are not available at the top of the page and the uploader.js script will fail.

Let us complete the script now –

jQuery(function($){
    $('body').on('click', '#custom-button-upload', function(e){
        e.preventDefault();
        obj_uploader = wp.media({
            title: 'Custom image',
            button: {
                text: 'Use this image'
            },
            multiple: false
        }).on('select', function() {
            var attachment = obj_uploader.state().get('selection').first().toJSON();
            $('#category_custom_image').html('');
            $('#category_custom_image').html(
                "<img src=" + attachment.url + " style='width: 100%'>"
            );
            $('#category_custom_image_url').val(attachment.url);
            $("#custom-button-upload").hide();
            $("#custom-button-remove").show();
        })
        .open();
    });

    $(".custom-button-remove").click( function() {
        $('#category_custom_image').html('');
        $('#category_custom_image_url').val('');
        $(this).hide();
        $("#custom-button-upload").show();
    });

});

All that this code does is – opens the image selection window on click of a button with id #custom-button-upload.

On selection of an image, it populates a division with id #category_custom_image with the image.

Then it assigns the image URL to an hidden input with id #category_custom_image_url so that this value can be sent with other category field values for storage in database.

When the upload is complete the current upload button gets hidden and a remove image button is introduced in its place.

If the image is removed then the upload button again shows up and the remove button is erased.

Now we need a way to save the custom field data ( image data ) to database when the add new category is clicked –

There is an action hook create_term that fires immediately after a category is created. This hook can be used to save the custom image data.

add_action( 'create_term', 'custom_create_term_callback' );

function custom_create_term_callback($term_id) {
    // add term meta data
    add_term_meta( 
        $term_id, 
        'term_image',   
        esc_url($_REQUEST['category_custom_image_url'])
    );

}

Here custom_create_term_callback is the callback function for create_term hook. This function is used to add a new term to wp_termmeta table using inbuilt add_term_meta method.

The function takes three parameters – the created term id, the term-taxonomy id and the taxonomy itself. Only the term id is used in this case ( $term_id ), because it is all what we need.

The term_image parameter is an arbitrary value and you can insert any other descriptive name. It is the name of the new meta being added to wp_termmeta table.

The $_REQUEST[‘category_custom_image_url’] parameter gets the value of the image URL from the post data. It is the field that contains the value of the image URL.

When a new category is added, this code will fire and add the image URL as a new meta with the category(term).

This information can later be retrieved and used in category pages or anywhere needed.

Adding an image upload button to the edit category screen

An image upload button can also be added to the edit category page. This will allow us to update an existing category and upload a custom image for the same.

The action hook that can be used for this purpose is category_edit_form_fields.

add_action ( 'category_edit_form_fields', 'category_edit_form_fields_callback', 10, 2 );

The callback function category_edit_form_fields_callback can be used to generate any custom field in the edit category screen.

function category_edit_form_fields_callback($ttObj, $taxonomy) {

    $term_id = $ttObj->term_id;
    $image = '';
    $image = get_term_meta( $term_id, 'term_image', true );

    ?>
    <tr class="form-field term-image-wrap">
      <th scope="row"><label for="image">Image</label></th>
	<td>
        <?php if ( $image ): ?>
        <span id="category_custom_image">
           <img src="<?php echo $image; ?>" style="width: 100%"/>
        </span>
        <input 
           type="hidden" 
           id="category_custom_image_url" 
           name="category_custom_image_url">
                
        <span>
           <a href="#" 
             class="button custom-button-upload" 
             id="custom-button-upload" 
             style="display: none">Upload image</a>
           <a href="#" class="button custom-button-remove">Remove image</a>                    
        </span>
        <?php else: ?>
        <span id="category_custom_image"></span>
        <input 
            type="hidden" 
            id="category_custom_image_url" 
            name="category_custom_image_url">
        <span>
           <a href="#" 
              class="button custom-button-upload" 
              id="custom-button-upload">Upload image</a>
           <a href="#" 
              class="button custom-button-remove" 
              style="display: none">Remove image</a>
        </span>
        <?php endif; ?>
        </td>
    </tr>
        
    <?php
}

The function is passed the current term taxonomy object ( $ttObj )and the taxonomy slug ( $taxonomy ) as parameters.

The $ttObj is used to get the current category id ( $term_id ) which is then used to get the category image URL from wp_termmeta table ( if any ). If the image URL is not present then the upload image button shows up.

Next, we need to save/update the image URL when the category is updated.

The hook that can be used for this purpose is edit_term

add_action( 'edit_term', 'edit_term_callback' );

The callback function edit_term_callback is passed the term id which is used to update the image URL in wp_termmeta table.

function edit_term_callback($term_id) {
    $image = '';
    $image = get_term_meta( $term_id, 'term_image' );

    if ( $image )
    update_term_meta( 
        $term_id, 
        'term_image', 
        esc_url( $_POST['category_custom_image_url']) );

    else
    add_term_meta( 
        $term_id, 
        'term_image', 
        esc_url( $_POST['category_custom_image_url']) );

}

It is important that you use the exact hook for the update because the $_POST data is still available. Other hooks may not retain the post data.

Showing the category image

The category image can be displayed in the category archive page or in a list of categories or anywhere you want.

You need to use get_term_meta to extract the image URL associated with the category and then show it it within an image element.

 $term_image_url = get_term_meta( $term_id, 'term_image', true );

Here $term_id is the category id and term_image is the meta key used to store the category image URL.

Note that some people use WordPress options table also to store the category meta. But I think the most logical place to store the values are in wp_termmeta as this table is for storing meta data associated with the term (category).

Also all this code goes to functions.php file of your theme if you want it to be theme specific or in a plugin file if you want the functionality to be site specific.

Every business deserves a website
हर एक बिजनेस के लिए एक वेबसाइट होना जरूरी है

GET YOUR'S NOW

Address

411 Kalikapur

Ishani Apartments, Kolkata - 99

Contacts

support@webdesignvista.com
Phone: +91 9903490874
Fax: +91 9903490874