Replace image attributes for lazyload plugin (data-src)

I want to apply jquery lazyload plugin. For this to work I have to create a new attribute which is data-src place there the src value and then replace the src value with a specific value '...nothing.gif'.
I found a solution on wordpress.org support

This is my adapted code –

function add_lazyload($content) 
{
    global $post;
    $search = '/src="([^s]+(?=.(bmp|gif|jpeg|jpg|png)).2)"/';
    $content = replacer($content, $search, '/src/', 'data-original');
    $search = '/img class="/';
    $content = replacer($content, $search, '/class="/', 'class="lazy ');
    $search = '/alt/';
    $content = replacer($content, $search, '/alt/', 'src="'.get_template_directory_uri().'/library/images/nothing.gif"');
    return $content;
}

function replacer($src, $search, $find, $replace)
{
    preg_match_all($search, $src, $result, PREG_OFFSET_CAPTURE);
    foreach($result[0] as $entry)
    {
        $org = $entry[0];
        $rep = preg_replace($find, $replace, $entry[0]);
        $org = "/" .str_replace(array("=",":","/",".","-","_",'"',"'"," "),     array("=",":","/",".","-","_",'"',"'"," "), $org). "/";
        $src = preg_replace($org, $rep, $src);
    }
return $src;
}

add_filter('the_content', 'add_lazyload');

The problem with this code is that it replaces every alt string (for example in a paragraph) with .../library/images/nothing.gif, not just the alt image attribute.

Read More

Does anyone know how to solve this?

Related posts

Leave a Reply

3 comments

  1. instead of replacing the alt tag you could add-an-attribute-to-a-tag

    function add_lazyload($content) {
         $dom = new DOMDocument();
         @$dom->loadHTML($content);
    
    
         foreach ($dom->getElementsByTagName('img') as $node) {  
             $oldsrc = $node->getAttribute('src');
             $node->setAttribute("data-original", $oldsrc );
             $newsrc = ''.get_template_directory_uri().'/library/images/nothing.gif';
             $node->setAttribute("src", $newsrc);
         }
         $newHtml = $dom->saveHtml();
         return $newHtml;
    }
    

    note: i didn’t quite tested this code, so be careful 🙂

  2. I modified peteroak’s excellent solution to convert to utf-8 and stripped the doctype, html, and body from the ouput.

    function add_lazyload($content) {
    
        $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
        $dom = new DOMDocument();
        @$dom->loadHTML($content);
    
        foreach ($dom->getElementsByTagName('img') as $node) {  
            $oldsrc = $node->getAttribute('src');
            $node->setAttribute("data-original", $oldsrc );
            $newsrc = ''.get_template_directory_uri().'/images/nothing.gif';
            $node->setAttribute("src", $newsrc);
        }
        $newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
        return $newHtml;
    }
    add_filter('the_content', 'add_lazyload');
    
  3. I added some features to Shieeets solution:

    • srcset support (changes srcset to data-srcset)
    • noscript fallback (displays original image)
    • video/embed/iframe support (Youtube and co)
    • additional hook to affect thumbnails (in addition to post images)
    • classes “lazy” and “lazy-hidden” are added automatically

    Here is the PHP code:

    // Lazyload Converter
    function add_lazyload($content) {
    
        $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
        $dom = new DOMDocument();
        @$dom->loadHTML($content);
    
        // Convert Images
        $images = [];
    
        foreach ($dom->getElementsByTagName('img') as $node) {  
            $images[] = $node;
        }
    
        foreach ($images as $node) {
            $fallback = $node->cloneNode(true);
    
            $oldsrc = $node->getAttribute('src');
            $node->setAttribute('data-src', $oldsrc );
            $newsrc = get_template_directory_uri() . '/images/placeholder.gif';
            $node->setAttribute('src', $newsrc);
    
            $oldsrcset = $node->getAttribute('srcset');
            $node->setAttribute('data-srcset', $oldsrcset );
            $newsrcset = '';
            $node->setAttribute('srcset', $newsrcset);
    
            $classes = $node->getAttribute('class');
            $newclasses = $classes . ' lazy lazy-hidden';
            $node->setAttribute('class', $newclasses);
    
            $noscript = $dom->createElement('noscript', '');
            $node->parentNode->insertBefore($noscript, $node); 
            $noscript->appendChild($fallback); 
        }
    
    
        // Convert Videos
        $videos = [];
    
        foreach ($dom->getElementsByTagName('iframe') as $node) {
            $videos[] = $node;
        }
    
        foreach ($videos as $node) {  
            $fallback = $node->cloneNode(true);
    
            $oldsrc = $node->getAttribute('src');
            $node->setAttribute('data-src', $oldsrc );
            $newsrc = '';
            $node->setAttribute('src', $newsrc);
    
            $classes = $node->getAttribute('class');
            $newclasses = $classes . ' lazy lazy-hidden';
            $node->setAttribute('class', $newclasses);
    
            $noscript = $dom->createElement('noscript', '');
            $node->parentNode->insertBefore($noscript, $node); 
            $noscript->appendChild($fallback); 
        }
    
        $newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
        return $newHtml;
    }
    add_filter('the_content', 'add_lazyload');
    add_filter('post_thumbnail_html', 'add_lazyload');