Last active
October 22, 2025 06:41
-
-
Save adamsilverstein/e9c9993d938eae80e559d9eda8c0fdcc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Extract alt meta data from uploaded images. | |
| * | |
| * @wordpress-plugin | |
| * Plugin Name: Extract Alt on Upload | |
| * Description: Extract alt meta data from uploaded images. | |
| * Plugin URI: | |
| * Version: 1.0.0 | |
| * Author: Adam Silverstein. | |
| * License: GNU General Public License v2 (or later) | |
| * License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
| */ | |
| function filter_wp_read_image_metadata( $meta, $file ) { | |
| $jpeg_contents = file_get_contents( $file ); | |
| $value = false; | |
| // Find the start and end positions of the XMP metadata | |
| $xmp_start = strpos( $jpeg_contents, '<x:xmpmeta' ); | |
| $xmp_end = strpos( $jpeg_contents, '</x:xmpmeta>'); | |
| // Extract the XMP metadata from the JPEG contents | |
| $xmp_data = substr( $jpeg_contents, $xmp_start, $xmp_end - $xmp_start + 12 ); | |
| // Parse the XMP metadata using DOMDocument | |
| $doc = new DOMDocument(); | |
| $doc->loadXML( $xmp_data ); | |
| // Instantiate an XPath object, used to extract portions of the XMP. | |
| $xpath = new DOMXPath( $doc ); | |
| // Register the relevant XML namespaces. | |
| $xpath->registerNamespace( 'x', 'adobe:ns:meta/' ); | |
| $xpath->registerNamespace( 'rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' ); | |
| $xpath->registerNamespace( 'Iptc4xmpCore', 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/' ); | |
| $node_list = $xpath->query( '/x:xmpmeta/rdf:RDF/rdf:Description/Iptc4xmpCore:AltTextAccessibility' ); | |
| if ( $node_list && $node_list->count() ) { | |
| // Get the alt text accessibility alternative most appropriate for the site language. | |
| $node = $node_list->item( 0 ); | |
| // Get the site's locale. | |
| $locale = get_locale(); | |
| // There are 3 possibilities: | |
| // | |
| // 1. there is an rdf:li with an exact match on the site locale | |
| // 2. there is an rdf:li with a partial match on the site locale (e.g., site locale is en_US and rdf:li has @xml:lang="en") | |
| // 3. there is an rdf:li with an "x-default" lang. | |
| // | |
| // we evaluate them in that order, stopping when we have a match. | |
| $value = $xpath->evaluate( "string( rdf:Alt/rdf:li[ @xml:lang = '{$locale}' ] )", $node ); | |
| if ( ! $value ) { | |
| $value = $xpath->evaluate( 'string( rdf:Alt/rdf:li[ @xml:lang = "' . substr( $locale, 0, 2 ) . '" ] )', $node ); | |
| if ( ! $value ) { | |
| $value = $xpath->evaluate( 'string( rdf:Alt/rdf:li[ @xml:lang = "x-default" ] )', $node ); | |
| } | |
| } | |
| } | |
| if ( $value ) { | |
| $callback = function( $attachment_id ) use ( &$callback, $value ) { | |
| $attachment = get_post( $attachment_id ); | |
| if ( ! wp_attachment_is_image( $attachment_id ) ) { | |
| return; | |
| } | |
| update_post_meta( $attachment_id, '_wp_attachment_image_alt', $value ); | |
| remove_action( 'add_attachment', $callback ); | |
| }; | |
| add_action( 'add_attachment', $callback ); | |
| } | |
| return $meta; | |
| } | |
| add_filter( 'wp_read_image_metadata', 'filter_wp_read_image_metadata', 10, 2 ); |
Author
Hey @hlsautter - I assume you are talking about https://wordpress.org/plugins/enable-media-replace/? The gist relies on the wp_read_image_metadata so perhaps that plugin removes it or overwrites what the gist does. You could try changing to a later priority:
change the last line to -
add_filter( 'wp_read_image_metadata', 'filter_wp_read_image_metadata', 99, 2 );
I tried this update and got the same results.
- load the original IPTC file and the alt text was available as expected
- edited the alt text value
- uploaded the original file again using “replace” media
- the Alt text was not updated from the file (expected the original alt-text instead of the edited value)
… On Oct 16, 2025, at 1:44 PM, Adam Silverstein ***@***.***> wrote:
@adamsilverstein commented on this gist.
Hey @hlsautter <https://github.com/hlsautter> - I assume you are talking about https://wordpress.org/plugins/enable-media-replace/? The gist relies on the wp_read_image_metadata so perhaps that plugin removes it or overwrites what the gist does. You could try changing to a later priority:
change the last line to -
add_filter( 'wp_read_image_metadata', 'filter_wp_read_image_metadata', 99, 2 );
—
Reply to this email directly, view it on GitHub <https://gist.github.com/adamsilverstein/e9c9993d938eae80e559d9eda8c0fdcc#gistcomment-5808810> or unsubscribe <https://github.com/notifications/unsubscribe-auth/APA3CY7APGPVTS3WKIELF6L3X77S5BFHORZGSZ3HMVZKMY3SMVQXIZNMON2WE2TFMN2F65DZOBS2WR3JON2EG33NNVSW45FGORXXA2LDOOIYFJDUPFYGLJDHNFZXJJLWMFWHKZNJGE2DAOBWGIYTMNFKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLJZSGY3TMMBSGKSG4YLNMWUGCY3UN5ZF62LEQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZQKSXMYLMOVS2IZ3JON2KI3TBNVS2W5DIOJSWCZC7OR4XAZI>.
You are receiving this email because you were mentioned.
Triage notifications on the go with GitHub Mobile for iOS <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> or Android <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
Author
I would need to look at the plugin to see why its not quite compatible with this code. Hopefully this will land in core so you won't need my plugin.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have installed the plugin "Enable Replace Media". Uploading a new image file adds the alt-text correctly. However when I replace the media the alt-text field gets cleared. Would you happen to know how to fix this? Updating the alt-text when replacing an image would be very helpful!