使用DOM在具有特定类的IMG之后插入DIV

时间:2012-12-15 11:49:56

标签: php wordpress dom

所以这是针对WordPress的。我想要做的是在我的主题的functions.php文件中创建一个小修改。我想要做的就是获取WordPress图像的ID,然后在图像本身包含类<div>之后在图像本身后面添加dd-star-rating

注意:

  • 图片ID位于“class”属性中。它将类似于wp-image-X(其中X是图像的ID)。我想将它存储在名为$id

  • 的变量中
  • 我希望它在每个具有班级<div>Star Rating ID = $id</div>

  • 的图片之后添加dd-star-rating

下面是$content变量中存储内容的示例:

<p>Nunc et neque risus. Nam a nisl eu magna rutrum euismod ac in lorem. Aenean varius accumsan ligula tincidunt malesuada. In diam lectus, pharetra quis cursus in, egestas vitae tellus. In neque arcu, aliquet ut egestas in, ultrices id ligula. Suspendisse ut dolor ligula, sit amet placerat ligula. Ut viverra nisi id ante facilisis pharetra. Aenean scelerisque, leo eget accumsan condimentum, odio libero ultrices enim, pretium placerat sapien purus nec odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur bibendum viverra pellentesque. Pellentesque eu diam non eros consectetur semper nec sed nisl.</p>

<p style="text-align: center;"><img class="size-full wp-image-44 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept.png" width="720" height="540" /></p>

<p style="text-align: center;"><img class="size-full wp-image-45 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept2.png" width="720" height="540" /></p>

<p>Nulla eros ante, lobortis in convallis eget, dignissim ut quam. Proin nisi nunc, iaculis ac auctor eu, tincidunt ac augue. Nunc purus nisi, sollicitudin nec luctus ullamcorper, dictum id magna. Sed quis nisi sagittis sapien placerat semper vitae tempus leo. Suspendisse sem diam, eleifend in blandit sed, pellentesque ac nisl. Morbi tincidunt adipiscing augue in pharetra. Duis dapibus bibendum egestas. Phasellus dictum dapibus quam id fermentum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>

对于这2张图片,由于它们包含dd-star-rating类,我希望$content变量的值更改为:

<p>Nunc et neque risus. Nam a nisl eu magna rutrum euismod ac in lorem. Aenean varius accumsan ligula tincidunt malesuada. In diam lectus, pharetra quis cursus in, egestas vitae tellus. In neque arcu, aliquet ut egestas in, ultrices id ligula. Suspendisse ut dolor ligula, sit amet placerat ligula. Ut viverra nisi id ante facilisis pharetra. Aenean scelerisque, leo eget accumsan condimentum, odio libero ultrices enim, pretium placerat sapien purus nec odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur bibendum viverra pellentesque. Pellentesque eu diam non eros consectetur semper nec sed nisl.</p>

<p style="text-align: center;"><img class="size-full wp-image-44 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept.png" width="720" height="540" /></p>
<div>Star Rating ID = 44</div>

<p style="text-align: center;"><img class="size-full wp-image-45 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept2.png" width="720" height="540" /></p>
<div>Star Rating ID = 45</div>

<p>Nulla eros ante, lobortis in convallis eget, dignissim ut quam. Proin nisi nunc, iaculis ac auctor eu, tincidunt ac augue. Nunc purus nisi, sollicitudin nec luctus ullamcorper, dictum id magna. Sed quis nisi sagittis sapien placerat semper vitae tempus leo. Suspendisse sem diam, eleifend in blandit sed, pellentesque ac nisl. Morbi tincidunt adipiscing augue in pharetra. Duis dapibus bibendum egestas. Phasellus dictum dapibus quam id fermentum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>

现在这是我的代码到目前为止,在我的主题functions.php文件中:

add_filter( 'the_content' , 'dd_wrap_image' );

function dd_wrap_image ( $content )
{    
    $dom = new DOMDocument;
    $dom->loadHTML($content);
    $imgs = $dom->getElementsByTagName('img');

    foreach($imgs as $img)
    {
        if ($img->hasAttribute('class') && strstr($img->getAttribute('class'), 'dd-star-rating'))
        {                
            // get the "wp-image-X" ID and store into $id variable
            // add "<div>Star Rating ID = $id</div>" after image

            $class_array = explode(' ', $img->getAttribute('class'));

            foreach ($class_array as $k => $v)
            {
                if (strstr($v, 'wp-image'))
                {
                    $id = end(explode('-', $v));
                }
            }

            if (!empty($id))
            {
                $img->appendChild("<div>Star Rating ID = $id</div>");
            }            
        }
    }

    $dom->saveHTML();
    return $content;
}

如您所见,我需要在条件语句中提供一些帮助。正则表达式匹配最适合用preg_match()计算ID吗?在每张图片后添加<div>的最佳方法是什么?使用str_replace()

编辑:

更新了我的代码。但现在收到错误Argument 1 passed to DOMNode::appendChild() must be an instance of DOMNode, string given

再次编辑:

非常感谢hakre!但是,如果我想在每个图像之后添加一些更大的代码,如下所示呢?

让我们说下面的代码存储在一个名为$star_code的变量中,如何使用DOM在图像之后插入它?

<div class="dd-star-poll" id="img-$id">

    <ul class="dd-star-poll-options">
    <li><a href='#' title='1 star out of 5' class='one-star'>1</a></li>
    <li><a href='#' title='2 stars out of 5' class='two-stars'>2</a></li>
    <li><a href='#' title='3 stars out of 5' class='three-stars'>3</a></li>
    <li><a href='#' title='4 stars out of 5' class='four-stars'>4</a></li>
    <li><a href='#' title='5 stars out of 5' class='five-stars'>5</a></li>    
    </ul>

    <div class="dd-star-poll-results">
    Currently 3.5/5 Stars.
    </div>

</div>

1 个答案:

答案 0 :(得分:3)

您遇到的最后一个问题是,您不是按字符串而是按对象添加新的<div>元素。例如:

$class->appendChild(new DOMElement('div', "Star Rating ID = $id"));

但是我也建议你在你的情况下使用XPath。它允许您只选择那些将类作为您正在寻找的字符串的img元素。至少与您在PHP代码中编写的级别相同。所以你可以省下一些代码。

选择所有匹配的属性的示例,然后解析它们(使用正则表达式)以获取ID:

$doc = new DOMDocument;
$doc->loadHTML("<body>$html</body>");

$xp = new DOMXPath($doc);
$images = $xp->query(
    '//img[@class
           and contains(@class, "dd-star-rating") 
           and contains(@class, "wp-image-")
       ]/@class'
);

foreach ($images as $class) {
    $id = preg_match('/(?:^|\s)wp-image-(\d+)(?:$|\s)/', $class->nodeValue, $matches) ? $matches[1] : NULL;
    $class->appendChild(new DOMElement('div', "Star Rating ID = $id"));
}

结果:

<p>Nunc et neque risus. Nam a nisl eu magna rutrum euismod ac in lorem. Aenean varius accumsan ligula tincidunt malesuada. In diam lectus, pharetra quis cursus in, egestas vitae tellus. In neque arcu, aliquet ut egestas in, ultrices id ligula. Suspendisse ut dolor ligula, sit amet placerat ligula. Ut viverra nisi id ante facilisis pharetra. Aenean scelerisque, leo eget accumsan condimentum, odio libero ultrices enim, pretium placerat sapien purus nec odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur bibendum viverra pellentesque. Pellentesque eu diam non eros consectetur semper nec sed nisl.</p>

<p style="text-align: center;"><img class="size-full wp-image-44 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept.png" width="720" height="540"></p>
<div>Star Rating ID = 44</div>

<p style="text-align: center;"><img class="size-full wp-image-45 aligncenter concept dd-star-rating" alt="concept" src="http://www.mysite.com/wp-content/uploads/2012/12/concept2.png" width="720" height="540"></p>
<div>Star Rating ID = 45</div>

<p>Nulla eros ante, lobortis in convallis eget, dignissim ut quam. Proin nisi nunc, iaculis ac auctor eu, tincidunt ac augue. Nunc purus nisi, sollicitudin nec luctus ullamcorper, dictum id magna. Sed quis nisi sagittis sapien placerat semper vitae tempus leo. Suspendisse sem diam, eleifend in blandit sed, pellentesque ac nisl. Morbi tincidunt adipiscing augue in pharetra. Duis dapibus bibendum egestas. Phasellus dictum dapibus quam id fermentum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>

通过使用DOMElelemnt::appendChild的返回值来添加更多元素。例如:

$prefix = 'dd-star-poll';

$divOuter = $node->appendChild(new DOMElement('div'));
$divOuter->setAttribute('class', $prefix);
$divOuter->setAttribute('id', "img-$id");

$ul = $divOuter->appendChild(new DOMElement('ul'));
$ul->setAttribute('class', "$prefix-options");

...

您只需继续添加元素。