Search code examples
phphtmlwordpressdomdocument

Replace some elements with a custom content using PHP DOMDocument


I need to replace a variable number of consecutive paragraphs in a div section on a Wordpress page, that consists only of this one div section. I would like to do this on the server side. I think this can be done with the the_content() hook and the DomDocument class, but I can't figure out how to do this. The div section structure you can see below. The paragraphs that I need to replace are between the last title and the last paragraph (so the title and the last paragraph remain unchanged). I will appreciate any help.

<div id="text-document">
    <h2>a title</h2>
    <p>some content</p>
    <!-- other paragraphs here -->

    <!-- some other DIVs, titles and paragraphs here -->

    <h2>the last title</h2>

    <!-- some paragraphs here -->

    <p>the last paragraph</p>
</div>

The DomDocument/Wordpress part:

add_filter( 'the_content', function( $content ) {
    $content = mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' );
    $dom = new DOMDocument( '1.0', 'UTF-8' );
    @$dom->loadHTML( $content );

    //the missing part

    $content = $dom->saveHTML( $dom );

    return $content;
} );

Solution

  • If I understand you correctly, something along these lines should get you at least closer to where you want to go:

    $xpath = new DOMXPath($dom);
    
    $targets = $xpath->query('//h2[last()]/following-sibling::p[not(position()=last())]');
    
    foreach($targets as $target){
            $target->parentNode->removeChild($target);}
    
    $destination = $xpath->query('//p[last()]');
    $template = $dom->createDocumentFragment();
    $template->appendXML('<p>I am new here</p>');
    $destination[0]->parentNode->insertBefore($template, $destination[0]);
    echo $dom->saveHTML();