so I need to inject an 'inlineAssetLink' class into an anchor tag that is part of a paragraph, but a class of 'blockAssetLink' into an anchor tag that is inside an otherwise empty paragraph.
Not sure this is even possible with xpath, but the content comes from a WYSIWYG editor in cms and I'd like to do this server-side rather than with javascript.
Already using DOMXPath to manipulate other parts of content so it would be nice to do the same for this.
Here's code that will load this into DOMDocument
and will apply those classes to all anchors, by checking count of children of parent of each.
function addClassesToAnchors($html)
{
$dom = new DOMDocument();
$dom->loadHTML(
"<div class='my-wrapper'>$html</div>",
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
);
// get all anchors
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $anchor) {
$parentNode = $anchor->parentNode;
if ($parentNode->nodeName == 'p') {
$childNodes = $parentNode->childNodes;
// count children, expect 1 for empty p
$count = 0;
foreach ($childNodes as $childNode) {
$count++;
}
if ($count == 1) {
$anchor->setAttribute('class', 'blockAssetLink');
}
if ($count > 1) {
$anchor->setAttribute('class', 'inlineAssetLink');
}
}
}
// Get the content as HTML without the <div> wrapper
$divElement = $dom->documentElement;
$result = '';
foreach ($divElement->childNodes as $node) {
$result .= $dom->saveHTML($node);
}
return $result;
}
$html = "<p><a></a></p> <p>but not</p> <p>sometext<a>link</a>or some text</p>";
echo addClassesToAnchors($html);