So I've been at this for quite a while, and the best I got is wrapping the image in a link and with a span after the image tag:
<a href="">
<img src="">
<span></span>
</a>
But wat I want is:
<a href="">
<span></span>
<img src="">
</a>
I tried al kinds of variatons and positions of
$img->parentNode->appendChild($dom->createElement('span'), $img);
and the use of insertBefore() on all kinds of places in my code and I'm completely out of ideas since I'm fairly new to the php DOM stuff. My source:
foreach($dom->getElementsByTagName('img') as $img)
{
$fancyHref = $dom->createElement('a');
$clone = $fancyHref->cloneNode();
$img->parentNode->replaceChild($clone, $img);
$clone->appendChild($img);
$img->parentNode->appendChild($dom->createElement('span'));
};
Update: To clarify my goal: I have an img tag in the html. After it goes through the php dom I want the img tag wrapped in an a tag with a span tag before the image tag:
Before
<img src="" />
After
<a href="">
<span class=""></span>
<img src="" />
</a>
My code at the moment for doing this (without the span)
foreach($dom->getElementsByTagName('img') as $img)
{
$src = $img->getAttribute('src');
$filename = substr(strrchr($src , '/') ,1);
$filename = preg_replace('/^[.]*/', '', $filename);
$filename = explode('.', $filename);
$filename = $filename[0];
if($this->imagesTitles[$this->currentLanguage][$filename] !== '')
{
$img->setAttribute('title', $this->imagesTitles[$this->currentLanguage][$filename]);
$img->setAttribute('alt', $this->imagesTitles[$this->currentLanguage][$filename]);
}
else
{
$img->removeAttribute('title');
$img->removeAttribute('alt');
}
$classes = explode(' ', $img->getAttribute('class'));
if(!in_array('no-enlarge', $classes))
{
$fancyHref = $dom->createElement('a');
$span = $dom->createElement('span');
$span->setAttribute('class', 'magnifier');
$fancyHref->setAttribute('class', 'enlarge');
$fancyHref->setAttribute('rel', 'enlarge');
$fancyHref->setAttribute('href', $img->getAttribute('src'));
if($img->getAttribute('title') !== '')
{
$fancyHref->setAttribute('title', $img->getAttribute('title'));
$fancyHref->setAttribute('alt', $img->getAttribute('title'));
}
$clone = $fancyHref->cloneNode();
$img->parentNode->replaceChild($clone, $img);
$clone->appendChild($img);
$img->parentNode->insertBefore($span, $img);
}
$img->setAttribute('class', trim(str_replace('no-enlarge', '', $img->getAttribute('class'))));
if($img->getAttribute('class') === '')
{
$img->removeAttribute('class');
}
}
You can use the DOMNode->insertBefore()
method (docs). It has the form $parentNode->insertBefore( $nodeToBeInserted, $nodeToInsertBefore )
. Your code would be:
$img->parentNode->insertBefore( $dom->createElement('span'), $img );
DOMNode->appendChild()
(docs) only has 1 argument (the inserted node), and this node will always be inserted after the last childNode.
Edit:
I've now tested my code, and if you would replace $img->parentNode->appendChild($dom->createElement('span'));
with my line in your test case, it would end up with the correct format. You are however manipulating elements in a very confusing way. Besides that, if I test your updated code, I either end up with your desired format, or without a span element at all...
The element you want to replace is the image, because that is the only element that is originally in the document. Therefore, you should clone -that- element. While your current code eliminates the hierarchy error, you are copying all the changed code, instead of just the conflicting element and that is a waste of memory and time. When you copy the conflicting element, it is easy. You append the elements to your a in the order you want them to appear. When you append the image, append the clone instead. Do not manipulate $img
. If you need to manipulate the image, you have to manipulate the clone instead. Then you just replace $img
by the elements you manipulated ($fancyHref
in your case).
$html = '<img src="">';
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach($dom->getElementsByTagName('img') as $img) {
$fancyHref = $dom->createElement('a');
$clone = $img->cloneNode();
$span = $dom->createElement( 'span' );
#... do whatever you need to do to this span, the clone and the a element ...
#... when you are done, you can simply append all elements you have been manipulating ...
$fancyHref->appendChild( $span );
$fancyHref->appendChild( $clone );
$img->parentNode->replaceChild( $fancyHref, $img );
};
echo $dom->saveHTML();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With