Home > database >  Replace empty alt in wordpress post content with filter
Replace empty alt in wordpress post content with filter

Time:06-30

I need to replace empty image alt in wordpress post content with image file name

I'm working on this function at the moment, please look at the comments:

// replace empty alt
function replace_empty_alt($content){
    if (is_single()) {        
        // searching in content text like src="post_image.jpg" alt="" 
        $newAlt = preg_match_all('/[^\/] (?=\.[^\/.]* alt="")/', $content, $matches);
        // extracting image names
        foreach ( $matches as $match) { 
            $imageNames = implode(',', $matches[0]);
        }
        // convert in array of ImageNames
        $imageNamesNew = explode(',', $urls);

        // foreach ImageName do a replace in content
        foreach ((array) $imageNamesNew as $imageNameNew) {
            $content = str_replace('alt=""', 'alt="'.$imageNameNew.'"', $content );

        }
        return $content;
    }
}

add_filter('the_content', 'replace_empty_alt');

Basically what I need to do is to replace any empty alt in post content with exctrated image name. At the moment it partially works, but I get the same $imageNameNew for any empty alt.

Something like:

<img  src="image-name1.jpg" alt="image-name1" width="799" height="449">

<img  src="image-name2.jpg" alt="image-name1" width="799" height="449">

<img  src="image-name3.jpg" alt="image-name1" width="799" height="449">

While I want to get a correct replace like:

<img  src="image-name1.jpg" alt="image-name1" width="799" height="449">

<img  src="image-name2.jpg" alt="image-name2" width="799" height="449">

<img  src="image-name3.jpg" alt="image-name3" width="799" height="449">

CodePudding user response:

I don't use WordPress and don't know what helper functions it can offer, but you should use a proper DOM parser, not regex.

Using DOMDocument and Xpath makes a very clean, readable, maintainable solution.

The XPath query finds img tags (with an empty alt attribute) on any level in the document. Inside the foreach() trim the file extension from the src value and apply it as the new alt value.

Code: (Demo)

$html = <<<HTML
<body>
<img  src="image-name1.jpg" alt="" width="799" height="449">

<img  src="image-name2.jpg" alt="" width="799" height="449">

<img  src="image-name3.jpg" alt="" width="799" height="449">
</body>
HTML;

$dom = new DOMDocument; 
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//img[@alt=""]') as $img) {
    $img->setAttribute(
        'alt',
        pathinfo(
            $img->getAttribute('src'),
            PATHINFO_FILENAME
        )
    );
}
echo $dom->saveHTML();

CodePudding user response:

Here is the final working code for wp, based on mickmackusa solution:

function dom_empty_alt($content)
{
    // replace only for posts
    if (is_single()) {

        $dom = new DOMDocument();
        // set errors level
        $internalErrors = libxml_use_internal_errors(true);

        $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");

        $dom->loadHTML($content);
        // Restore errors level
        libxml_use_internal_errors($internalErrors);
        $xpath = new DOMXPath($dom);
        foreach ($xpath->query('//img[@alt=""]') as $img) {
            $img->setAttribute('alt', pathinfo($img->getAttribute('src'), PATHINFO_FILENAME));
        }
        return $dom->saveHTML();
    } else {
        return $content;
    }
}

add_filter('the_content', 'dom_empty_alt', 20);
    
  • Related