Set attachment tags from attachment’s custom field data

I currently have a custom field added to my attachment’s form called artist_credit using the hook attachment_fields_to_edit. When a person enters a name into the artist credit field, I want it to (if it hasn’t got the tag already) assign a tag with that name to the attachment’s tags when the attachment is saved.

I have the plugin WordPress Media Tags installed which allows me to have a field on the attachment’s form to attach terms to the media_tag taxonomy. The trouble I’m finding is that when I use the hook attachment_fields_to_save. Saving the meta data for the artist_credit is fine (using update_post_meta), it’s just that when I use wp_set_object_terms to then add the artist_credit to the media_tag taxonomy, it does assign it (tags are assigned when I echo out get_the_terms for the attachment post), but then when I go to the edit form for the attachment again to see the results, the extra credit tag isn’t assigned to the attachment post at all.

Read More

My only theory is that the media_tag taxonomy value is performed AFTER the attachment_fields_to_save action, and that understandably it’s probably run with a false value to not append terms. Interestingly enough, the hook save_post isn’t fired after editing the attachment’s details so I can’t seem to use that hook for adding this artist_credit value to the media_tag taxonomy for this attachment post either. Any suggestions on what I could do?

Here’s how I’m doing it currently:

// Add custom fields to attachments
function example_add_attachment_fields($form_fields, $post) {

    // Create artist_credit custom field
    $form_fields['artist_credit'] = array(
            'label' => 'Artist Credit',
            'input' => 'text',
    );

    return $form_fields;
}
add_filter('attachment_fields_to_edit', 'example_add_attachment_fields', null, 2);

// Save attachment's custom fields' values
function example_save_attachment_fields($post, $attachment) {

    // Save extra attachment fields
    if ( isset($attachment['artist_credit']) ) {
        update_post_meta($post['ID'], 'artist_credit', $attachment['artist_credit']);

        // Add artist_credit as a term to the attachment post
        wp_set_object_terms( $post['ID'], $attachment['artist_credit'], 'media_tag', true );
    }

    return $post;
}
add_filter('attachment_fields_to_save', 'example_save_attachment_fields', null, 2);

Related posts

Leave a Reply

1 comment

  1. I managed to make it work but not fully.

    First, the code you provided is not retrieving an already saved post_meta.

    I based my code in the introductory code of this tutorial:
    http://wpengineer.com/2076/add-custom-field-attachment-in-wordpress/

    And am using the regular post_tag taxonomy instead of a custom one.

    And, lastly, there’s a bug, after you close the Media Upload iframe and hit “Update” the tags are erased (no idea why), but if you simply refresh the browser, the tags are there.

    Anyway, there are one piece that may contribute to a complete answer:
    intval($post['ancestors'][0]) in the function wp_set_post_terms

    add_filter( 'attachment_fields_to_edit', 'fb_attachment_fields_edit', 10, 2);
    add_filter( 'attachment_fields_to_save', 'fb_attachment_fields_save', 10, 2);
    function fb_attachment_fields_edit($form_fields, $post) {
        $form_fields['artist_credit']['label'] = __( 'Example Custom Field', '' );
        $form_fields['artist_credit']['value'] = get_post_meta($post->ID, 'artist_credit', true);
        $form_fields['artist_credit']['helps'] = __( 'A helpful text for this field.', '' );
        return $form_fields;
    }
    // save custom field to post_meta
    function fb_attachment_fields_save($post, $attachment) {
        if ( isset($attachment['artist_credit']) && '' !== $attachment['artist_credit'] ) {
            update_post_meta($post['ID'], 'artist_credit', $attachment['artist_credit']);
            $check = wp_set_post_terms( intval($post['ancestors'][0]), $attachment['artist_credit'], 'post_tag', true );
        }
        return $post;
    }