How to Add Custom Field to WordPress Media
July 2, 2026 Written by Maria
Need to add custom field to WordPress media files? While the default WordPress Media Library includes fields like Title, Caption, Alt Text, and Description, many websites require additional information to organize media more effectively. This is especially useful for businesses managing large image libraries, product catalogs, portfolios, or editorial content.
Custom media fields allow you to store details such as photographer name, copyright information, license type, product SKU, source URL, shoot date, or internal asset IDs. Instead of keeping this information in separate spreadsheets, you can manage everything directly inside the Media Library, making your workflow faster and more organized.
In this guide, you’ll learn how to add custom fields to WordPress media, save the data securely, display it where needed, and follow best practices that keep your website easy to manage as your media library grows.
By the end of this guide, you’ll understand how to add custom field to WordPress media files and manage them efficiently without making your workflow more complicated.
Every file you upload to the WordPress Media Library is stored as an attachment, which is a special type of WordPress post (post_type = attachment). The actual image, PDF, or video is saved inside the wp-content/uploads folder, while WordPress stores important information like the file name, dimensions, MIME type, and any custom media fields in the database.
When you add custom field to WordPress media, the extra information is stored as post meta attached to that media item. Developers typically use these two WordPress functions to work with custom media fields:
php
get_post_meta( $attachment_id, $key, true )
update_post_meta( $attachment_id, $key, $value )
These functions are the foundation of most custom media field solutions and are used throughout the methods covered in this guide.
There isn’t a single “best” way to add custom field to WordPress media. The right approach depends on your website, technical skills, and how your team manages media files.
In many real-world projects, combining these methods works best. Store unique details like a photo credit or SKU as custom fields, while using taxonomies to organize media into searchable categories such as license type or photographer.
If you prefer a clean solution without installing extra plugins, using WordPress hooks is one of the most reliable methods. This approach lets you create custom media fields directly in your theme’s functions.php file or a custom plugin, giving you full control over how the field is added, saved, and displayed.
In this example, we’ll create a Photographer Name field. The same approach can be used for other details such as copyright information, image credits, product SKUs, source URLs, license types, or internal asset IDs.
The following code adds a Photographer field to the Media Library edit screen and the Attachment Details popup.
/**
* Add a custom field to the Media edit screen (and media modal “Attachment Details”).
*/
function mymedia_add_custom_field( $form_fields, $post ) {
$value = get_post_meta( $post->ID, ‘_mymedia_photographer’, true );
// Add a nonce field once per screen load (safe to repeat—WP will de-duplicate by name).
$form_fields[‘mymedia_nonce’] = array(
‘label’ => ”,
‘input’ => ‘html’,
‘html’ => wp_nonce_field( ‘mymedia_save_field_’ . $post->ID, ‘mymedia_nonce’, true, false ),
);
$form_fields[‘mymedia_photographer’] = array(
‘label’ => __( ‘Photographer’, ‘your-textdomain’ ),
‘input’ => ‘text’,
‘value’ => $value,
‘helps’ => __( ‘Enter the photographer or credit line.’, ‘your-textdomain’ ),
);
return $form_fields;
}
add_filter( ‘attachment_fields_to_edit’, ‘mymedia_add_custom_field’, 10, 2 );
After adding the field, the next step is saving the entered value. The following code verifies user permissions, validates the security nonce, sanitizes the input, and stores the value safely as attachment metadata.
/**
* Save our custom field from Media edit screen.
*/
function mymedia_save_custom_field( $post, $attachment ) {
$attachment_id = isset( $post[‘ID’] ) ? (int) $post[‘ID’] : 0;
if ( ! $attachment_id || ! current_user_can( ‘edit_post’, $attachment_id ) ) {
return $post; // Respect capabilities
}
// Nonce check
if ( empty( $_POST[‘mymedia_nonce’] ) || ! wp_verify_nonce( $_POST[‘mymedia_nonce’], ‘mymedia_save_field_’ . $attachment_id ) ) {
return $post;
}
if ( isset( $attachment[‘mymedia_photographer’] ) ) {
$value = sanitize_text_field( $attachment[‘mymedia_photographer’] );
update_post_meta( $attachment_id, ‘_mymedia_photographer’, $value );
}
return $post;
}
add_filter( ‘attachment_fields_to_save’, ‘mymedia_save_custom_field’, 10, 2 );
Once the value is saved, you can retrieve and display it anywhere on your website. In this example, the photographer’s name appears below the featured image, but you can also use the same method inside galleries, custom templates, or image cards.
/**
* Output a credit below a featured image or any attachment.
*/
function mymedia_output_credit( $attachment_id ) {
$credit = get_post_meta( $attachment_id, ‘_mymedia_photographer’, true );
if ( $credit ) {
echo ‘<p class=”photo-credit”>Photo: ‘ . esc_html( $credit ) . ‘</p>’;
}
}
Use mymedia_output_credit( get_post_thumbnail_id() ); in templates, or call it when rendering galleries.
If you want the information to travel with every image, you can automatically attach it as a custom HTML attribute. This is useful for JavaScript functionality, tooltips, lightboxes, or image credit systems without manually editing every template.
wp_get_attachment_image() attributes:
add_filter( ‘wp_get_attachment_image_attributes’, function( $attr, $attachment ) {
$credit = get_post_meta( $attachment->ID, ‘_mymedia_photographer’, true );
if ( $credit ) {
$attr[‘data-photo-credit’] = $credit; // handy for JS or tooltips
}
return $attr;
}, 10, 2 );
When your Media Library contains hundreds or thousands of files, opening each attachment individually becomes time-consuming. Adding a custom column lets editors quickly view information like the photographer or image credit directly from the Media Library screen.
// Register column
add_filter( ‘manage_upload_columns’, function( $cols ) {
$cols[‘mymedia_photographer’] = __( ‘Photographer’, ‘your-textdomain’ );
return $cols;
} );
// Render column
add_action( ‘manage_media_custom_column’, function( $column_name, $attachment_id ) {
if ( ‘mymedia_photographer’ === $column_name ) {
$val = get_post_meta( $attachment_id, ‘_mymedia_photographer’, true );
echo $val ? esc_html( $val ) : ‘—’;
}
}, 10, 2 );
You can also make this column sortable using manage_upload_sortable_columns and pre_get_posts, making it much easier to filter and manage large media libraries. This small improvement can save significant time for teams working with extensive image collections.
If you prefer a visual interface instead of writing code, Advanced Custom Fields (ACF) is one of the easiest ways to add extra information to your media files. It’s ideal for content teams, editors, and website owners who want to create and manage custom fields through the WordPress dashboard.
Getting started only takes a few minutes:
Once published, ACF automatically displays these fields on the Media edit screen and within the Attachment Details panel, making them easy for editors to update.
Use the following functions to display your custom field values anywhere on your website.
$credit = get_field( ‘photographer’, $attachment_id );
$license_url = get_field( ‘license_url’, $attachment_id );
If you’re using Gutenberg, a headless WordPress setup, or custom applications, you can expose these fields through the REST API. Simply enable Show in REST within the field group settings or configure it through ACF’s REST integration.
Pros
Cons
Not every piece of media information needs to be stored as a custom field. If you want to group files into reusable categories, a custom taxonomy is often the better option. This works well for information that is shared across multiple files, such as License Type, Photographer, Department, Campaign, or Usage Rights.
The following example creates a custom Media License taxonomy that can be assigned to media attachments.
/**
* Register a “media_license” taxonomy for attachments.
*/
function mymedia_register_media_taxonomy() {
register_taxonomy(
‘media_license’,
‘attachment’,
array(
‘label’ => __( ‘Media License’, ‘your-textdomain’ ),
‘public’ => false,
‘show_ui’ => true,
‘show_admin_column’ => true,
‘hierarchical’ => false,
‘show_in_rest’ => true, // expose to REST/Gutenberg
)
);
}
add_action( ‘init’, ‘mymedia_register_media_taxonomy’ );
After registering the taxonomy, editors can assign terms such as Editorial Use Only, Commercial Use, or Creative Commons directly from the Media Library. Since these values are reusable, they help maintain consistency across large collections of images and documents.
Using a taxonomy also makes media management more efficient. You can filter attachments by category, build custom media queries, display license badges on the front end, and expose the taxonomy through the REST API for Gutenberg or headless WordPress projects.
If you’re building a headless WordPress website, creating custom Gutenberg blocks, or connecting WordPress with external applications, you’ll want your media metadata to be accessible through the REST API. If you’re not using ACF, you can register your attachment metadata with register_meta(), so WordPress exposes it automatically.
The following example registers the Photographer field and makes it available through the REST API.
/**
* Register attachment meta for REST access.
*/
function mymedia_register_rest_meta() {
register_meta( ‘post’, ‘_mymedia_photographer’, array(
‘object_subtype’ => ‘attachment’,
‘show_in_rest’ => array(
‘schema’ => array(
‘type’ => ‘string’,
‘description’ => ‘Photographer credit’,
),
),
‘single’ => true,
‘type’ => ‘string’,
‘auth_callback’ => function() { return current_user_can( ‘upload_files’ ); },
) );
}
add_action( ‘init’, ‘mymedia_register_rest_meta’ );
After registering the field, it becomes part of the media endpoint, so requests like GET /wp-json/wp/v2/media/<id> will include the custom value. Users with the appropriate permissions can also update the field through POST or PATCH requests, making it easier to integrate media metadata with Gutenberg, mobile apps, or other external systems.
If you’re using the Gutenberg block editor, there are several ways to display custom media information alongside your images. The best method depends on whether you’re building a custom block, using the default Image block, or displaying featured images through your theme.
You can choose from the following approaches:
The example below shows a simple dynamic block render callback that adds a photo credit beneath an image whenever a custom value is available.
function mymedia_block_render( $attributes, $content, $block ) {
if ( empty( $attributes[‘attachmentId’] ) ) {
return $content;
}
$credit = get_post_meta( (int) $attributes[‘attachmentId’], ‘_mymedia_photographer’, true );
if ( ! $credit ) {
return $content;
}
return $content . ‘<figcaption class=”photo-credit”>Photo: ‘ . esc_html( $credit ) . ‘</figcaption>’;
}
If you want editors to display media details without modifying theme files, a shortcode is one of the easiest solutions. It allows you to insert information such as photographer credits or image attribution directly into posts, pages, or custom content areas using a simple shortcode.
The example below creates a [photo_credit] shortcode that retrieves the photographer’s name from the selected media attachment and displays it wherever the shortcode is placed.
/**
* [photo_credit id=”123″]
*/
function mymedia_shortcode_credit( $atts ) {
$atts = shortcode_atts( array( ‘id’ => 0 ), $atts );
$credit = get_post_meta( (int) $atts[‘id’], ‘_mymedia_photographer’, true );
return $credit ? ‘<span class=”photo-credit”>Photo: ‘ . esc_html( $credit ) . ‘</span>’ : ”;
}
add_shortcode( ‘photo_credit’, ‘mymedia_shortcode_credit’ );
Once added, editors can use the shortcode like this:
[photo_credit id=”123″]
Replace 123 with the attachment ID of the image. This approach is ideal for users who want a quick, reusable way to display media information without editing templates or writing additional PHP code.
As your Media Library grows, updating custom media information one file at a time becomes impractical. WordPress provides several ways to speed up bulk management, making it easier to organize, update, and migrate existing media data.
If you’re using a custom taxonomy, WordPress automatically adds a filter dropdown in Media → Library (List View). When working with custom metadata instead, you can create your own filter interface and use pre_get_posts to search media items by specific field values.
For websites with a large number of media files, WP-CLI provides a fast way to update custom fields in bulk. The following example assigns “Unknown” as the photographer name for attachments that don’t already have one.
wp eval ‘
$ids = get_posts([“post_type”=>”attachment”,”posts_per_page”=>-1,”fields”=>”ids”]);
foreach ($ids as $id) {
$v = get_post_meta($id, “_mymedia_photographer”, true);
if (!$v) { update_post_meta($id, “_mymedia_photographer”, “Unknown”); }
}
echo “Done\n”;
‘
If your image information already exists in places like Alt Text or EXIF metadata, you don’t have to enter everything manually. The following script copies existing values into your custom media field, helping you migrate data quickly.
add_action( ‘admin_init’, function() {
if ( ! current_user_can( ‘manage_options’ ) ) return;
if ( isset( $_GET[‘migrate_credit_once’] ) ) {
$ids = get_posts( array( ‘post_type’ => ‘attachment’, ‘posts_per_page’ => -1, ‘fields’ => ‘ids’ ) );
foreach ( $ids as $id ) {
$existing = get_post_meta( $id, ‘_mymedia_photographer’, true );
if ( $existing ) continue;
$alt = get_post_meta( $id, ‘_wp_attachment_image_alt’, true );
if ( $alt ) update_post_meta( $id, ‘_mymedia_photographer’, sanitize_text_field( $alt ) );
}
wp_die( ‘Migration complete.’ );
}
} );
Run the migration once using:
/wp-admin/?migrate_credit_once=1 (then remove the code).
After the migration finishes successfully, remove the temporary code to prevent it from running again. This keeps your website clean and avoids accidental updates in the future.
When adding custom media information, it’s important to follow WordPress security standards. Proper validation and permission checks help protect your website from unauthorized changes while ensuring the stored data remains clean and reliable.
Custom media fields have very little impact on performance when implemented correctly. As your Media Library grows, following a few best practices will help keep your website fast and easy to manage.
If your website runs on WordPress Multisite or supports multiple languages, it’s worth planning how media information will be managed across different sites and translations.
Before using your custom media fields on a live website, take a few minutes to test everything. A quick review helps ensure the fields work correctly for editors and display properly across your website.
If your custom media fields are not working as expected, the problem is usually easy to identify. Use the checklist below to quickly troubleshoot the most common issues.
attachment_fields_to_edit filter is loading correctly and that the code is running in the WordPress admin area without syntax errors.$attachment['your_field_key']) are all configured properly.register_meta() includes show_in_rest => true and the correct object_subtype => 'attachment' so the metadata is exposed correctly.If you don’t want to place custom code inside your theme’s functions.php file, creating a small plugin is a cleaner and more maintainable approach. This keeps your custom media functionality separate from your theme, so it won’t be affected when you switch themes or install updates.
Create a new file at:
wp-content/plugins/mymedia-credit/mymedia-credit.php
Then add the following code:
<?php
/**
* Plugin Name: MyMedia Credit Field
* Description: Adds a Photographer credit field to attachments.
* Version: 1.0.0
* Author: You
*/
if ( ! defined( ‘ABSPATH’ ) ) exit;
add_filter( ‘attachment_fields_to_edit’, function( $form_fields, $post ) {
$val = get_post_meta( $post->ID, ‘_mymedia_photographer’, true );
$form_fields[‘mymedia_nonce’] = array(
‘label’ => ”,
‘input’ => ‘html’,
‘html’ => wp_nonce_field( ‘mymedia_save_field_’ . $post->ID, ‘mymedia_nonce’, true, false ),
);
$form_fields[‘mymedia_photographer’] = array(
‘label’ => __( ‘Photographer’, ‘mymedia’ ),
‘input’ => ‘text’,
‘value’ => $val,
);
return $form_fields;
}, 10, 2 );
add_filter( ‘attachment_fields_to_save’, function( $post, $attachment ) {
$id = (int) $post[‘ID’];
if ( empty( $_POST[‘mymedia_nonce’] ) || ! wp_verify_nonce( $_POST[‘mymedia_nonce’], ‘mymedia_save_field_’ . $id ) ) {
return $post;
}
if ( current_user_can( ‘edit_post’, $id ) && isset( $attachment[‘mymedia_photographer’] ) ) {
update_post_meta( $id, ‘_mymedia_photographer’, sanitize_text_field( $attachment[‘mymedia_photographer’] ) );
}
return $post;
}, 10, 2 );
add_action( ‘init’, function() {
register_meta( ‘post’, ‘_mymedia_photographer’, array(
‘object_subtype’ => ‘attachment’,
‘show_in_rest’ => array(
‘schema’ => array( ‘type’ => ‘string’, ‘description’ => ‘Photographer credit’ ),
),
‘single’ => true,
‘type’ => ‘string’,
‘auth_callback’ => function() { return current_user_can( ‘upload_files’ ); },
) );
} );
After saving the file, go to Plugins → Installed Plugins in your WordPress dashboard and activate MyMedia Credit Field. The custom Photographer field will immediately become available in the Media Library, and because it’s packaged as a plugin, it’s easier to reuse, maintain, or move between WordPress websites in the future.
Not sure which approach fits your project? Use this quick guide to choose the option that matches your workflow.
| If you want to… | Recommended Option |
|---|---|
| Add a simple text field with maximum performance | Pure PHP Hooks |
| Create multiple field types with an easy admin interface | Advanced Custom Fields (ACF) |
| Organize media into reusable groups or categories | Attachment Taxonomies |
| Use media fields in a headless WordPress or custom application | Register fields with the REST API using register_meta() or ACF REST support |
For many websites, combining these methods delivers the best results. For example, you can use custom fields to store unique details like photographer credits, while taxonomies help organize media by license type, department, or campaign.
Adding custom media fields helps you organize your Media Library and keeps important information attached to every file. Whether you’re managing image credits, licensing details, product information, or internal notes, the right setup makes your content workflow more consistent and easier to maintain.
Start with just a few fields that your team uses regularly, then expand as your media library grows. Use PHP hooks if you want maximum performance and control, ACF for a faster no-code setup, or taxonomies when you need reusable categories for organizing media assets.
No matter which method you choose, always follow WordPress best practices by validating user input, checking permissions, and exposing fields through the REST API only when needed. This helps keep your website secure, scalable, and easier to manage over the long term.
If your project requires additional fields such as Photographer, License URL, Usage Notes, Shoot Date, or Editorial Only status, you can easily extend this setup or package it as a reusable plugin with its own settings page for future projects.
Maria is a Content Writer with 7+ years of experience creating content for WordPress, web hosting, and digital marketing. She specializes in taking technical topics and turning them into clear, practical guides that non-technical readers can actually follow. Her work covers everything from beginner WordPress tutorials to hosting comparisons and site optimization tips. She focuses on writing that answers real questions without unnecessary complexity, which is harder to do well than it sounds.
Elevate your WordPress hosting with 30-day money-back guarantee, free migration, and 24/7 support.
Sign Up TodayMay 15, 2026
Maria
May 8, 2026
Nitish
Before You Go… Get 1 Month FREE on Rocon Hosting!
Experience lightning-fast speeds
No downtime or hidden fees
Dedicated 24/7 expert support
Our team will contact you soon.
Leave a Reply