I would like to automatically set the alternative text to be the same
as the title of a post when image is uploaded.
The attachment’s image alternative text is stored in the post meta table under the _wp_attachment_image_alt
meta key.
In media_handle_upload()
and media_handle_sideload()
we have:
$id = wp_insert_attachment($attachment, $file, $post_id);
if ( !is_wp_error($id) )
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
The wp_insert_attachment()
is a wrapper for wp_insert_post()
and the add_attachment
is fired after the attachment has been written to the posts table.
Example
Here’s a way to automatically set the alternative text as the attached parent post’s title, during upload, through the add_attachment
hook:
/**
* Set the attachment image alt as the parent post's title, during upload
*/
add_action( 'add_attachment', function( $attachment_id )
{
// Nothing to do if it's not an image
if( ! wp_attachment_is_image( $attachment_id ) )
return;
// Get parent post's ID for the image
$parent_id = wp_get_post_parent_id( $attachment_id );
// Nothing to do if the image isn't attached to a post
if( ! $parent_id )
return;
// Get parent post's title
$parent_title = get_the_title( $parent_id );
// Nothing to do if the attached post has no title
if( empty( $parent_title ) )
return;
// Set the image alt as the parent post's title
update_post_meta( $attachment_id, '_wp_attachment_image_alt', $parent_title );
} );
Notes
Note that we don’t want to add the _wp_attachment_image_alt
key to all attachments, so that’s why we use wp_attachment_is_image()
to only target the images.
We could also hook into wp_update_attachment_metadata
or wp_generate_attachment_metadata
in a similar way, where the attachment’s ID passed on as the second filter input argument.
The wp_read_image_metadata()
is called within wp_generate_attachment_metadata()
to e.g. retrieve the EXIF and IPTC data. This is where OP is currently hooking into.
Also note that when the parent post title is changed, the alternative text goes out of sync. In a somewhat related question, I’ve discussed some options here.