filters – How to stop DOMDocument destroying embeds?


I am making use of PHP’s DOMDocument to carry out two DOM operations on the post content, by filtering the_content:

The trouble is, it seems like DOMDocument is destroying embedded WordPress content like tweets. As seen in this example, the embedded tweet is not rendered as an <iframe> as it should be, it is just rendered using <p>.

Is there a way to stop DOMDocument from doing this?

My code is below.

Wrap element in another element.
Contributed by @XzKto,
function wrap_element($dom, $wrapped_element, $new_element) {
    // Initialise the new wrapper
    $wrapper = $dom->createElement($new_element);
    //Clone our created element
    $wrapper_clone = $wrapper->cloneNode();
    //Replace image with this wrapper div
    //Append the element to wrapper div

add_filter( 'the_content', 'bootstrap_blockquote' );
function bootstrap_blockquote( $content ) {
    // Load DOM of post content
    $dom = new DOMDocument();

    foreach($dom->getElementsByTagName('blockquote') as $blockquote){
        // Add blockquote class
        // Class addition contributed by @Gillu13,
        $class_to_add = 'blockquote';
        $blockquote->setAttribute('class', $class_to_add);
        // Wrap blockquote in <figure>
        wrap_element($dom, $blockquote, 'figure');

    $content = utf8_decode($dom->saveHTML($dom->documentElement)); // formatting correction contributed by @Greeso,
    return $content;


Original contributed by Jack Torris,
add_filter( 'the_content', 'segment_post' );
function segment_post( $content ) {

    $d = new DOMDocument;

    $segments = array(); $card = null;

    foreach ($d->getElementsByTagName('h3') as $h3) {
        // first collect all nodes
        $card_nodes = array($h3);
        // iterate until another h3 or no more siblings
        for ($next = $h3->nextSibling; $next && $next->nodeName != 'h3'; $next = $next->nextSibling) {
            $card_nodes[] = $next;

        // create the wrapper node
        $card = $d->createElement('div');
        $card->setAttribute('class', 'card p-4 mb-3');

        // replace the h3 with the new card
        $h3->parentNode->replaceChild($card, $h3);
        // and move all nodes into the newly created card
        foreach ($card_nodes as $node) {
        // keep title of the original h3
        $segments[] = $h3->nodeValue;

    //  make sure we have segments (card is the last inserted card in the dom)
    if ($segments && $card) {
        $ul = $d->createElement('ul');
        foreach ($segments as $title) {
            $li = $d->createElement('li');

            $a = $d->createElement('a', $title);
            $a->setAttribute('href', '#');


        // add as sibling of last card added

    // TODO: examine

    $content = utf8_decode($d->saveHTML($d->documentElement)); // formatting correction contributed by @Greeso,    
    return $content;

enter image description here
enter image description here

Robert Andrews 10 months 2022-03-25T16:52:37-05:00 0 Answers 0 views 0

Leave an answer