How to Add Custom Fields to Attachments

You should be familiar with custom fields in WordPress. We use them on a post or a page to add extra data. In WordPress attachments are also saved as posts, so custom fields are available for them too.

Today we'll see how we can add some custom fields so that attachments can carry more information than just the default data.

What We'll Do

First of all, we are going to create a plugin to handle the attachments custom fields. It will get a set of options, bake them so they become part of the form when we edit an attachment, and save them into the database.

For this, we will use two WordPress hooks:

1. Create the Plugin

I will pass quickly on this part as it's not the main purpose of this tutorial.

Create a new folder in the plugins directory (wp-content/plugins/media-fields/ for example) and put a file (named plugin.php) inside. Let's also put a file called custom_media_fields.php which will hold our options.

This is what your plugin.php file should look like at first:

This is the base we'll populate in the following sections. For now, let's define our set of options.

2. Define Our Options

In the other file, let's add some options to enhance the attachment edit form. We'll consider, for this tutorial, options to improve images. For instance, we'll add copyright, author description, watermark, rating, and image disposition fields.

It is basically an associative array which contains these parameters:

  • label - the field name that will be displayed
  • input - the input type (e.g text, select, radio, ...)
  • helps - information to help the user filling in the field
  • application - which attchment mime type to apply
  • exclusions - which attchment mime type to exclude
  • required - is the field required? (default false)
  • error_text - optional field to describe the error (if required is set to true)
  • options - optional field for radio and select types
  • show_in_modal - whether to show the field in modal or not (default true)
  • show_in_edit - whether to show the field in classic edit view or not (default true)
  • extra_rows - additional rows to display content (within the same "tr" tag)
  • tr - additional rows ("tr" tag)

The highlitghted options represent options we will manually deal with whereas others are default ones WordPress will process automatically.

As we are dealing with images, we set the application parameter to "image". It will actually apply to all kinds of images whose mime type starts with "image" such as image/jpeg, image/png and so on. You could exlude the gif mime type by setting it in the exclusions field for example.

Now our options are set, let's dig into the hooks.

3. The Hooks

As mentionned earlier, we'll deal with two hooks.

We bind our two functions to those hooks in the constructor method.

Now let's see those hooks in detail.


It has two parameters:

  1. $form_fields - An array of fields contained in the attachment edit form
  2. $post - Object which represents the attachment itself

We will use the $form_fields parameter to merge our own fields and check each one of them against attachment requirements (mime type for instance).

At this step, you should have your attachment edit form enhanced with the new fields we've added. But they will look like text inputs. We now have to consider different kinds of inputs (radio, checkbox, etc...).

So let's edit our function to handle this. Replace the $values['input'] = 'text'; with the following code:

Now, we can build common HTML elements. Let's check out our attachment edit form. It should look just like this:

Attachment edit form with custom fields
Attachment edit form with custom fields

The custom fields, depending on whether you set their modal options to true or not, will also appear in the media modal form when you edit a post.

Custom fields in modal
Custom fields in modal

Now our fields are displayed in our attachment edit form, we have to save them in the database. For this, we are going to use the second hook.


This hook also has two parameters:

  1. $post - array which represents the attachment entity
  2. $attachment - contains all fields attached to the attachment post

Now, let's fill the function saveFields we left in the previous section.

Ok, now our custom fields are saved into the database and will be available for the front-end.

  • Please be careful when manipulating the post parameter in both hooks. It is an object in the first one and an array in the second one.
  • Tip: the update_post_meta will create the meta if it doesn't exist.
  • Tip: We prefix the custom field key with an underscore "_" so that they won't be listed in the custom fields metaboxes on post edit pages.

Error Considerations

As of version 3.5, it seems that errors still don't appear on attachment edit forms. I tried to investigate the core code, and despite the fact it should have been fixed (, it seems not.

For the ajax save process, it is certain it's not done yet as mentionned in the ajax-actions.php file:

So right now, errors are not going to work properly, but the code is done so that when those bugs are fixed, it'll work.

Front End

To use those custom fields in your templates, you just have to retrieve post metas the same way you would for regular posts. Don't forget to add the "_" prefix to the custom fields' keys.

For instance, you could do like so:

Show custom fields on front-end
Show custom fields on front-end

Go Further

There are several points of improvements depending on your needs:

  • You could have your settings in the database so it becomes more flexible to add, edit, and remove them
  • You could have a default value that is set for all new attachments when a value is not set
  • You should set some style for the modal form so it displays the custom fields properly


Don't hesitate to share with us your ideas on how to improve this plugin and what you would expect from such functionality.



Related Articles