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" ".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?
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/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?
Share Improve this question asked Dec 22, 2018 at 20:22 user145078user1450782 Answers
Reset to default 1Parsing 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/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/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;
}
If you are using bootstrap and want a responsive image in the_content()
. You may try this code; works fine in my case img-fluid. You can replace it with your own class.
function add_image_responsive_class($content) {
global $post;
$pattern ="/<img(.*?)class=\"(.*?)\"(.*?)>/i";
$replacement = '<img$1class="$2 img-fluid"$3>';
$content = preg_replace($pattern, $replacement, $content);
return $content;
}
add_filter('the_content', 'add_image_responsive_class');