使用DOMDocument在WordPress中包装图像

时间:2017-03-26 15:08:11

标签: php wordpress domdocument

我正在尝试在我的WordPress博客中为每个图像添加一个div包装器,并尝试使用我的functions.php中的DOMDocment来实现这一点。 不幸的是,只有我的包装器的结束标签被应用于输出。所有图像都缺少开始标记。

我的功能如下:

function lazyload($content){
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML(utf8_decode($content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();


$div = $dom->createElement('div');
$images = $dom->getElementsByTagName('img');

foreach ($images as $image) {
    $div_clone = $div->cloneNode();
    $image->parentNode->replaceChild($div_clone, $image);
    $div_clone->appendChild($image);
}

$html = $dom->saveHTML();
return $html; 
}

仅在包装img时才会发生这种情况。我尝试包装每个段落标记,并且所有这些标记都打开和关闭包装标记。

有人知道如何解决这个问题吗? 我还试过return $html而不是echo $html。在这种情况下,两个标签都被应用,但是标题被回显为短标签而不是解析的html元素。

1 个答案:

答案 0 :(得分:1)

Hello_ friend。

我实现了你正在尝试使用这样的帮助DOMDocument对象:

function lazyload($content) {
    $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML(utf8_decode($content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    libxml_clear_errors();

    // This object will hold the updated content
    $newContent = new DOMDocument();

    $images = $dom->getElementsByTagName('img');

    foreach ($images as $image) {

        $div = $newContent->createElement('div');
        $div->appendChild($newContent->importNode($image));
        $newContent->appendChild($div);

    }

    $html = $newContent->saveHTML();
    return $html;
} 

// Test
$html = '<img alt="image 1"><img alt="image 2"><img alt="image 3"><img alt="image 4"><img alt="image 5"><img alt="image 6"><img alt="image 7"><img alt="image 8">';
echo lazyload($html);

// OUTPUT
<div>
    <img alt="image 1">
</div>
<div>
    <img alt="image 2">
</div>
<div>
    <img alt="image 3">
</div>
<div>
    <img alt="image 4">
</div>
<div>
    <img alt="image 5">
</div>
<div>
    <img alt="image 6">
</div>
<div>
    <img alt="image 7">
</div>
<div>
    <img alt="image 8">
</div>

注意:在您的代码中,我看到您正在使用DOMDocument::createElement,但我从未看到您将此新创建的<div>附加到 DOM 和文件说:

  

public DOMElement DOMDocument :: createElement(string $ name [,string   $ value])

     

此函数创建类DOMElement的新实例。 此节点   除非插入(例如),否则不会出现在文档中   的DOMNode ::的appendChild()。

如果我编辑的功能对您有用,请告诉我。

祝你好运!

修改

你的陈述很好。如果您想在整个 DOM 内容中使用它,您应该采取另一种方法:

function lazyload($content) {
    $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML(utf8_decode($content), LIBXML_HTML_NODEFDTD);
    libxml_clear_errors();

    $images = $dom->getElementsByTagName('img');

    foreach ($images as $image) {

        $div = $dom->createElement('div');
        $div->appendChild($image->cloneNode());

        // optional
        $div->setAttribute('class', 'your-lazy-loading-img-class');

        // replace img with the wrapper that is holding the <img>
        $image->parentNode->replaceChild($div, $image);
    }

    return $dom->saveHTML();
}


// Test
$html = '
    <h1 class="h1">Heading 1</h1>
    <div class="multiple-images-wrapper">
        <div class="inner-wrapper"><img alt="image 1"></div>
        <img alt="image 2">
        <img alt="image 3">
    </div>

    <h2>Heading 2</h2>
    <img alt="image 4">
    <img alt="image 5">';

// htmlspecialchars is only for testing purpose 
echo htmlspecialchars(lazyload($html));
exit;

<强>输出

<html>
    <body>
        <h1 class="h1">Heading 1</h1> 
        <div class="multiple-images-wrapper"> 
            <div class="inner-wrapper">
                <div class="your-lazy-loading-img-class">
                    <img alt="image 1">
                </div>
            </div>
            <div class="your-lazy-loading-img-class">
                <img alt="image 2">
            </div>
            <div class="your-lazy-loading-img-class">
                <img alt="image 3">
            </div>
        </div>
        <h2>Heading 2</h2> 
        <div class="your-lazy-loading-img-class">
            <img alt="image 4">
        </div>
        <div class="your-lazy-loading-img-class">
            <img alt="image 5">
        </div>
        <div class="your-lazy-loading-img-class">
            <img alt="image 6">
        </div>
        <div class="your-lazy-loading-img-class">
            <img alt="image 7">
        </div>
        <div class="your-lazy-loading-img-class">
            <img alt="image 8">
        </div>
    </body>
</html>

注意

看到我省略了LIBXML_HTML_NOIMPLIED,因为有了这个标志似乎DOMDocument没有按预期运行(对我而言)。如果您更改为$dom->loadHTML(utf8_decode($content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);,则会看到如下输出:

<h1 class="h1">Heading 1
    <div class="multiple-images-wrapper"> 
        <div class="inner-wrapper">
            <div class="your-lazy-loading-img-class">
                <img alt="image 1">
            </div>
        </div> 
        <div class="your-lazy-loading-img-class">
            <img alt="image 2">
        </div> 
        <div class="your-lazy-loading-img-class">
            <img alt="image 3">
        </div> 
    </div>
    <h2>Heading 2</h2>
    <div class="your-lazy-loading-img-class">
        <img alt="image 4">
    </div>
    <div class="your-lazy-loading-img-class">
        <img alt="image 5">
    </div>
</h1>

所以根据我的说法,如果你想要一个可靠的HTML避免使用 LIBXML_HTML_NOIMPLIED ,那么如果你不需要<html><body></body></html>只需用一些基本技术从返回的字符串中清除那些标签比如字符串替换或字符串切割到位置。