1

I have used this function to add a responsive class to all the images in content but this breaks the html structure of the website. This wraps the content with : <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><body> the content goes here (output from the_content();) </body></html>

function add_responsive_class($content)
{
    $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    if (!empty($content)) {
        $document = new DOMDocument();
        libxml_use_internal_errors(true);
        $document->loadHTML(utf8_decode($content));

        $imgs = $document->getElementsByTagName('img');
        foreach ($imgs as $img) {
            $classes = $img->getAttribute('class');
            $img->setAttribute('class', $classes . ' img-fluid');
        }

        $html = $document->saveHTML();
        return $html;
    }
}
add_filter('the_content', 'add_responsive_class');
add_filter('acf_the_content', 'add_responsive_class');

Can i know why? any alternative solution for this?

2

Parsing and modifying HTML properly using the standard PHP library is quite a pain. There are many gotchas. Here's a well documented example that will add the img-fluid class to all images in the content.

To ensure that the doctype and HTML tags are not added to the HTML fragment a solution from this StackOverflow answer is used:

$dom->loadHTML( $content ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );

Note that there are other ways of doing this which are discussed in the SO post I linked to, but this soltion has worked well for me.

The code I've posted below expands on this solution to deal with utf8 characters as well.

/**
 * Adds img-fluid class to images in content.
 * Fire late to affect gallery images.
 */
add_filter( 'the_content',     'add_responsive_class', 9999 );
add_filter( 'acf_the_content', 'add_responsive_class', 9999 );
function add_responsive_class( $content ) {
    // Bail if there is no content to work with.
    if ( ! $content ) {
        return $content;
    }

    // Create an instance of DOMDocument.
    $dom = new \DOMDocument();

    // Supress errors due to malformed HTML.
    // See http://stackoverflow.com/a/17559716/3059883
    $libxml_previous_state = libxml_use_internal_errors( true );

    // Populate $dom with $content, making sure to handle UTF-8, otherwise
    // problems will occur with UTF-8 characters.
    // Also, make sure that the doctype and HTML tags are not added to our HTML fragment. http://stackoverflow.com/a/22490902/3059883
    $dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );

    // Restore previous state of libxml_use_internal_errors() now that we're done.
    libxml_use_internal_errors( $libxml_previous_state );

    // Create an instance of DOMXpath.
    $xpath = new \DOMXpath( $dom );

    // Get images.
    $imgs = $xpath->query( "//img" );

    // Add additional classes to images.
    foreach ( $imgs as $img ) {
        $existing_class = $img->getAttribute( 'class' );
        $img->setAttribute( 'class', "{$existing_class} img-fluid" );
    }

    // Save and return updated HTML.
    $new_content = $dom->saveHTML();
    return $new_content;
}
  • You got it, @LatheeshVMVilla! – Dave Romsey Dec 22 '18 at 21:31
  • hi i am getting a warning with debug on : DOMDocument::loadHTML() expects parameter 2 to be integer, string given -> Any way to fix it ? – Latheesh V M Villa Dec 26 '18 at 13:16
  • 1
    Hi @LatheeshVMVilla, I have not reproduced the warning and have tested (and double tested) this code. Did you copy the code I posted exactly? It sounds like you're having trouble with the line $dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); specifically the bitwise or operation applied to the configuration constants (which should both be integers per the docs) at the end of the line: LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD. – Dave Romsey Dec 26 '18 at 16:29
  • 1
    i came to know why this happended..it's because of php version ..in one hosting the php version was like 5.x some thing and in another one it was 7.x. the code works fine in 7.x – Latheesh V M Villa Dec 26 '18 at 19:19
  • 1
    Hi, I think 5.5: https://stackoverflow.com/questions/40911718/domdocumentloadhtml-expects-parameter-2-to-be-long-string-given-when-trying ---- is it possible to provide a fallback? is it usually done? – Latheesh V M Villa Dec 26 '18 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.