I have this WordPress function working, but it has 1 obvious issue in testing and I’m sure many other formatting issues. I’ve pulled this function together from various pieces but would greatly appreciate feedback on cleaning it up.
Purpose of the function
- Modify ALT attribute of any image in a WordPress gallery
- Get image caption field and add to ALT
- Get ACF relationship field “photographer” if it has a value (URL)
- Add “View Photographer” HTML to end of ALT, only if that image has been assigned to a photographer
- Returns no errors if image has no caption or ACF relationship assigned
Why am I modifying the alt tag with HTML? We currently use Facncybox 2.1.5 and it pulls captions from the alt tag.
Output error I need help with
The function does get the caption and photographer url and add them to each image in a gallery. However, if image A has caption data and photographer data, but image B has a caption but NO photographer assigned, image B still has “View Photographer” link show up in the alt field with the URL being that of image A.
How do I make sure that the function checks each image but then fully ends its check before moving onto the next image so that it doesn’t pull the photographer relationship URL from the previous image to the next image if the next image does not have that ACF relationship assigned?
function wpdocs_replaceALT( $content ) { if ( is_single() && in_the_loop() && is_main_query() ) { libxml_use_internal_errors( true ); $post = new DOMDocument(); $post->loadHTML( $content ); $images = $post->getElementsByTagName( 'img' ); foreach ( $images as $image ) { $src = $image->getAttribute( 'src' ); $image_id = attachment_url_to_postid( $src ); $media = get_post( $image_id ); $caption = $media->post_excerpt; $photographer_relationship = get_field('photographer', $image_id); $photographer = (is_array($photographer_relationship) && !empty($photographer_relationship)) ? array_shift($photographer_relationship) : null; if ( !empty($photographer)) { $link_to_photographer = get_permalink($photographer); } if ($media && !empty($media->post_excerpt)) { $view_photog = '<a class="learn-more-photog-link" target="_blank" href="'.$link_to_photographer.'">View Photographer</a>'; } $link_text = ''.$caption.''.$view_photog.''; if ( empty( $image->getAttribute( 'title' ) ) ) { $image->setAttribute( 'title', $link_text); } } $content = $post->saveHTML(); return $content; } } add_filter( 'the_content', 'wpdocs_replaceALT' );
SOLUTION BELOW based on feedback from Nathan Dawson.
function wpdocs_replaceALT( $content ) { if ( is_single() && in_the_loop() && is_main_query() ) { libxml_use_internal_errors( true ); $post = new DOMDocument(); $post->loadHTML( $content ); $images = $post->getElementsByTagName( 'img' ); foreach ( $images as $image ) { $view_photog = ''; $src = $image->getAttribute( 'src' ); $image_id = attachment_url_to_postid( $src ); $media = get_post( $image_id ); $caption = $media->post_excerpt; $photographer_relationship = get_field( 'photographer', $image_id ); $photographer = ( is_array( $photographer_relationship ) && !empty( $photographer_relationship ) ) ? array_shift( $photographer_relationship ) : null; if ( !empty( $photographer ) ) { $link_to_photographer = get_permalink( $photographer ); $view_photog = '<a class="learn-more-photog-link" target="_blank" href="' . $link_to_photographer . '">View Photographer</a>'; } $link_text = '' . $caption . '' . $view_photog . ''; if ( empty( $image->getAttribute( 'title' ) ) ) { $image->setAttribute( 'title', $link_text ); } } $content = $post->saveHTML(); return $content; } } add_filter( 'the_content', 'wpdocs_replaceALT' );
Advertisement
Answer
When looping through images, the $view_photog
variable is only set if certain conditions are met. You need to reset the variable on each iteration of the loop otherwise when the condition isn’t met, the value will be preserved from the last time that it was.
Example:
foreach ( $images as $image ) { $view_photog = '';