4

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?

7

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 :)

| improve this answer | |
  • 1
    Thank you very much, this solution works great!. Just one thing, you are missing a semicolon after $newHtml = $dom->saveHtml(). Thanks again! – Alvaro Aug 5 '12 at 9:26
  • ahhh! you're right! :)) – pcarvalho Aug 5 '12 at 10:08
  • 1
    Be careful here, if you use this on a fragment of a post it may mess with UTF-8 encoding. – alexleonard Dec 12 '14 at 10:03
7

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');
| improve this answer | |
  • Thanks! I was just about to comment this problem and found your answer. – Alvaro Aug 7 '12 at 15:24
1

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');
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.