I have the following filter, but do not know how to add custom attributes to image field, when attaching media to post.


<img data-ext-link-title="" data-ext-link-url="">


function pp_external_link_edit( $form_fields, $post ) {
    $form_fields['pp-external-link-title'] = array(
        'label' => 'External Link Title',
        'input' => 'text',
        'value' => get_post_meta( $post->ID, 'pp_external_link_title', true ),
        'helps' => 'Link for button at bottom of pretty photo modal',

    $form_fields['pp-external-link-url'] = array(
        'label' => 'External Link URL',
        'input' => 'text',
        'value' => get_post_meta( $post->ID, 'pp_external_link_url', true ),
        'helps' => 'Link for button at bottom of pretty photo modal',

    return $form_fields;

add_filter( 'attachment_fields_to_edit', 'pp_external_link_edit', 10, 2 );

function pp_external_link_save( $post, $attachment ) {
    if( isset( $attachment['pp-external-link-title'] ) )
        update_post_meta( $post['ID'], 'pp_external_link_title', $attachment['pp-external-link-title']);

    if( isset( $attachment['pp-external-link-url'] ) )
        update_post_meta( $post['ID'], 'pp_external_link_url', $attachment['pp-external-link-url']);

    return $post;

add_filter( 'attachment_fields_to_save', 'pp_external_link_save', 10, 2 );
  • You could save yourself a buttload of headache by just installing Advanced Custom Fields wordpress.org/plugins/advanced-custom-fields. Which has an interface to very easily setup fields for anywhere, including media attachments.
    – deflime
    Jan 28, 2015 at 21:52
  • Here's a link to the ACF page for adding and retrieving custom fields on media posts. advancedcustomfields.com/resources/…
    – Slam
    Dec 30, 2017 at 11:58
  • ACF adds custom fields to the attachment details popup in the media library, but it does not add them to the Image details popup when editing the image in the edit post page, which I think is what the OP asked for.
    – kloddant
    Jan 27, 2022 at 16:59

2 Answers 2


I wonder if you want to modify the HTML of the inserted image, with the image_send_to_editor or get_image_tag filters?

If that's the case, then here's one example:

 * Add the data-ext-link-title and data-ext-link-url attributes to inserted images. 

add_filter( 'image_send_to_editor',
    function( $html, $id, $caption, $title, $align, $url, $size, $alt )
        if( $id > 0 )
            $ext_title = get_post_meta( $id, 'pp_external_link_title', true ); 
            $ext_url   = get_post_meta( $id, 'pp_external_link_url',   true ); 
            $data  = sprintf( ' data-ext-link-title="%s" ', esc_attr( $ext_title ) );
            $data .= sprintf( ' data-ext-link-url="%s" ',   esc_url( $ext_url )    );
            $html = str_replace( "<img src", "<img{$data}src", $html );
        return $html;
, 10, 8 );

Here I assume you want empty data-ext-link-title or data-ext-link-url attributes, if the corresponding meta values are empty or missing.

Hopefully you can adjust this to your needs.


I was doing something similar the other day and simply could not get attachment_fields_to_save to work no matter what I tried.

I ended up using the edit_attachment filter instead along with code like the following:

public function action_edit_attachment( $attachment_id ) {
    # Check to make sure we were sent by the side of the media editor, not by the real edit form
    # - if the real edit form was used, action would be editpost instead
    if ( isset($_REQUEST['action']) ) {
        $our_fields = array(
            'pp-external-link-title' => 'text',
            'pp-external-link-url' => 'text'
        foreach ( $our_fields as $field_name => $input_type ) {
            if ( isset( $_REQUEST['attachments'][$attachment_id]["{$field_name}"] ) ) {
                switch ( "{$input_type}" ) {
                    case 'text':
                        $value = stripcslashes($_REQUEST['attachments'][$attachment_id]["{$field_name}"]);
                        update_post_meta( $attachment_id, "{$field_name}", $value );
                        # Not implemented
    return $attachment_id;
add_filter( 'edit_attachment', 'action_edit_attachment' );

If you only want it to save from the media screen, you could change the _REQUEST check

if ( isset($_REQUEST['action']) && 'save-attachment-compat' == "{$_REQUEST['action']}" ) {

Or from the full attachment post editor

if ( isset($_REQUEST['action']) && 'editpost' == "{$_REQUEST['action']}" ) {

Anywise, I had no luck with the older method ... and saw at least a few people had just as much difficulty with it as I did.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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