最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to change src to data-src for iframe inside WP content?

programmeradmin0浏览0评论

I need to change src to data-src for iframes inside Wordpress content and add class lazy. I was trying this:

function iframe_image_lazy_load($the_content) {
    $thecontent = get_the_content();
        if(!empty($thecontent)) {
            libxml_use_internal_errors(true);
            $post = new DOMDocument();
            $post->loadHTML(mb_convert_encoding($the_content, 'HTML-ENTITIES', 'UTF-8'));
            $iframes = $post->getElementsByTagName('iframe');
            foreach( $iframes as $iframe ) {
                if( $iframe->hasAttribute('data-src') ) continue;
                $clone = $iframe->cloneNode();
                $src = $iframe->getAttribute('src');
                $iframe->removeAttribute('src');
                $iframe->setAttribute('data-src', $src);
                $srcset = $iframe->getAttribute('srcset');
                $iframe->removeAttribute('srcset');
                if( ! empty($srcset)) {
                    $iframe->setAttribute('data-srcset', $srcset);
                }
                $iframeClass = $iframe->getAttribute('class');
                $iframe->setAttribute('class', $iframeClass . ' lazy');
            };
            return $post->saveHTML();
        }
    }
add_filter('the_content', 'iframe_image_lazy_load', 15);

It's based on other working snippet, but for images. Should this be working?

I need to change src to data-src for iframes inside Wordpress content and add class lazy. I was trying this:

function iframe_image_lazy_load($the_content) {
    $thecontent = get_the_content();
        if(!empty($thecontent)) {
            libxml_use_internal_errors(true);
            $post = new DOMDocument();
            $post->loadHTML(mb_convert_encoding($the_content, 'HTML-ENTITIES', 'UTF-8'));
            $iframes = $post->getElementsByTagName('iframe');
            foreach( $iframes as $iframe ) {
                if( $iframe->hasAttribute('data-src') ) continue;
                $clone = $iframe->cloneNode();
                $src = $iframe->getAttribute('src');
                $iframe->removeAttribute('src');
                $iframe->setAttribute('data-src', $src);
                $srcset = $iframe->getAttribute('srcset');
                $iframe->removeAttribute('srcset');
                if( ! empty($srcset)) {
                    $iframe->setAttribute('data-srcset', $srcset);
                }
                $iframeClass = $iframe->getAttribute('class');
                $iframe->setAttribute('class', $iframeClass . ' lazy');
            };
            return $post->saveHTML();
        }
    }
add_filter('the_content', 'iframe_image_lazy_load', 15);

It's based on other working snippet, but for images. Should this be working?

Share Improve this question asked Feb 2, 2020 at 16:33 D_PD_P 1531 gold badge3 silver badges12 bronze badges 3
  • Are you trying to modify the iframes in OEmbeds? Or is this coming from somewhere else such as an iframe shortcode? Is this classic editor or something else? I notice you're given the content as a parameter, yet you ignore it and call get_the_content anyway? There's also no return value at the end, filters must always return but this filter only returns if $thecontent is not empty – Tom J Nowell Commented Feb 2, 2020 at 16:53
  • Yes, the iframes in oEmbed, in classic editor. – D_P Commented Feb 2, 2020 at 17:07
  • I see, that it's using the classic editor is of no consequence, but it does rule out you working with iframes generated by more exotic means. OEmbed works the same in both, and has its own sets of filters that can be used. In the meantime, I believe a great deal of insight and help can be sought be looking up how filters and PHP functions work – Tom J Nowell Commented Feb 2, 2020 at 21:08
Add a comment  | 

1 Answer 1

Reset to default 0

The code snippet in your question is a filter, but it isn't built properly:

  • A filter needs a function that takes in the thing to be filtered as the first parameter, and returns the new version
  • Your function ignores the first parameter, breaking any changes that have already been made
  • Your function doesn't always return a value

So, lets start with the function:

function iframe_image_lazy_load($the_content) {
    $thecontent = get_the_content();
        if(!empty($thecontent)) {
            ... do modifications to iframes
            return $post->saveHTML();
        }
    }
add_filter('the_content', 'iframe_image_lazy_load', 15);

First, there are no iframes to modify, those happened on the_content filter, and got passed in as the parameter, but you ignored that and got the original.

As a result, the string you're working with just contains OEmbed URLs, no iframes. Lets fix that:

function iframe_image_lazy_load($content) {
    if(!empty($content)) {
        ... do modifications to iframes
        return $post->saveHTML();
    }
}
add_filter('the_content', 'iframe_image_lazy_load', 15);

Notice I used variable passed to the function, instead of ignoring it and retrieving the original content. I also fixed the indentation levels, bad indentation is a great way to get bugs.

Next, the if statement is unnecessary, lets turn it into a guard and exit early:

function iframe_image_lazy_load($content) {
    if(empty($content)) {
        return $content;
    }
    ... do modifications to iframes
    return $post->saveHTML();
}
add_filter('the_content', 'iframe_image_lazy_load', 15);

OEmbed Filters

Thinking about these things in terms of HTML strings with iframes in them is a limiting and narrow way to view things. These are OEmbeds! So why not filter OEmbeds

发布评论

评论列表(0)

  1. 暂无评论