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.

Does anyone know how to solve this?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 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 🙂

Method 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');

Method 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');


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x