Auto-populating Image Alt Tags (WordPress Plugin)

Published

Lately it’s been bugging me that WordPress requires users to enter Alt and Title tags each time an Image is used in a Post or Page. Other Content Management Systems I’ve used (i.e. Adobe Experience Manager) allow users to upload their media assets in one central location, and manage all metadata properties in that single authoritative place. Properties set there are then read by all components and meta tags that need them, and the same consistent metadata is used across the entire site.

I searched the Internet for plugins or code snippets where other people had accomplished this paradigm with WordPress. Unfortunately I came up empty handed, and decided to create a quick plugin to do this myself.

The plugin was fun to write, an essentially combs through a post’s raw HTML looking for <img /> tags. When it finds a tag, it will determine the image ID, and use that to look up the image’s Alt and Title values set in the Media Library. The Alt and Title values are them pumped back into the HTML and sent back to the Browser.

Some interesting challenges faced where:

I ended up submitting this plugin to the official plugin directory on WordPress.org and they accepted! For reference, the code snippet and readme file contents are below. Hope this helps someone out there!

Overall Goal

  1. Write a plugin that made it possible to set the Image Alt and Title tags in the WordPress Media Library:
    Using the Media Library to set the Title and Alternative Text for an attachment.
  2. Have the values automatically populated in to the Post HTML wherever those images were used:
    When viewing a post, we can inspect the Image HTML of the images and see their alt and title tags are populated automatically from the values set in the Media Library.

Plugin Source Snippet:

/*
Plugin Name: Auto-populate Image ALT Tags from Media Library
Description: Automatically populates Alt and Title tags for images using the values set in the Media Library. 
Version: 1.0
License: GPLv2
Author: Taylor Callsen
*/

function image_alt_ml_insert_img_tags($content) {
	// only execute filter when viewing page or post
	if (!is_single() && !is_page()) return $content;

	// compile post attachment image paths for use in looking up image id
	$attachmentImages = get_attached_media('image', get_the_ID() );

	$content = preg_replace_callback('/<img[^>]+>/i',function ($matches) use ($attachmentImages) {
		
		// parse image tag into proper xml node object
		$doc = simplexml_import_dom(DOMDocument::loadHTML($matches[0]));
		$imageElem = $doc->xpath("//img")[0];
        
        // pull image src attribute
        $imageAttributes = $imageElem->attributes();
        $imageSrc = $imageAttributes->src;
        
        // look up image id from image source (comparing against list of post attachments)
        //	note: if id lookup fails, will abort script and return base HTML
		$imageID;
		foreach ($attachmentImages as $image) {
			if ($imageSrc == $image->guid) $imageID = $image->ID;
		}
		if (!isset($imageID)) {
			//echo "\n" . 'imageID NOT FOUND: ' . $imageSrc;
			return $matches[0];
		}
		
		// retreive attachment alt and title tags from attachment
		$imageAltTag = get_post_meta($imageID, '_wp_attachment_image_alt', true);
		$imageTitleTag = get_the_title($imageID);

		// add attachment alt and title tags to imgElem if not already present
		//	(i.e. specified in current post where attachment is made)
		if ($imageAltTag != ''){
			if (!isset($imageAttributes->alt)) $imageElem->addAttribute('alt',trim($imageAltTag));
			else if ($imageAttributes->alt == '') $imageAttributes->alt = trim($imageAltTag);
		}
		if ($imageTitleTag != ''){
			if (!isset($imageAttributes->title)) $imageElem->addAttribute('title',trim($imageTitleTag));
			else if ($imageAttributes->title == '') $imageAttributes->title = trim($imageTitleTag);
		}
		
		// render $imageElem back to HTML with new attributes included (must strip out xml header)
		$imageHTML = str_replace("\n", '', $imageElem->asXML());

		// return updated image HTML back into post content
        return $imageHTML;

    },$content); 

	return $content;
}
add_filter('the_content', 'image_alt_ml_insert_img_tags');

Readme Contents:

=== Auto-populate Image ALT Tags from Media Library ===

Tags: image, img, title, alt, attribute, seo, media library

Requires at least: 4.7.5

Stable tag: trunk

License: GPLv2

License URI: http://www.gnu.org/licenses/gpl-2.0.html


Automatically populates Alt and Title tags for images using the values set in the Media Library.


== Description ==


Automatically populates Alt and Title tags for images featured in posts and pages, pulling directly from the values set in the Media Library. This makes it easy to manage your image metadata centrally in one place (the Media Library). Plugin also supports the ability to override the Alt/Title tag Media Library values by placing an Alt/Title tag directly on the attachment in the WordPress WYSIWYG Editor.

Tag population only occurs when viewing the post or page, and does not occur in the WYSIWYG editor.


== Installation ==

This section describes how to install the plugin and get it working.
 
1. Upload the `img-alt-media-library` directory to the plugins directory of your theme (usually `/wp-content/plugins/`).
2. Activate the plugin through the 'Plugins' menu in WordPress.

That's all, you're good to go! Upon viewing your posts and pages, you should now see image Alt and Title tags being pulled automatically from the Media Library.


== Screenshots ==
 
1. [https://taylor.callsen.me/wp-content/uploads/2018/02/set-title-alt-tags-media-li.jpg  Set the Image Alt and Title tags in the Media Library]
2. [https://taylor.callsen.me/wp-content/uploads/2018/02/see-img-alt-title-when-view.jpg  The Alt and Title tags are automatically inserted into the Image HTML when viewing a page or post]

== Frequently Asked Questions ==
 
= How does it work? =
 
This plugin hooks into the the_content filter on page and post render. Essentially right before post_content (in the form of raw HTML) is set to the browser, this plugin will scan the HTML for  tags using a regex matcher. Regex was used instead of parsing the HTML into a Document Object to maximize compatability (parsing the HTML into a Document Object, and then back to an HTML string would likely modify the HTML syntax, drop attributes, etc. which could break other components and post functionality).

Once images are identified in the HTML, the image src URL is used to lookup the attachment ID corresponding to the image. Unfortunately I was not able to find a cleaner way of performing this lookup, as the image ID is not always output onto the page when an attachment is included.

Once the image ID is determined, the plugin retreives the image Alt and Title values for that attachment using the get_post_meta() and get_the_title() WordPress functions. Once these values are returned, they are added to the image unless the image already contains an alt or title tag, in which case this part is skipped.

The modified image HTML is placed back into the post_content HTML string, and returned to the browser.

== Changelog ==
 
= 1.0 =
* Initial release of functional code and readme