web-dev-qa-db-ja.com

コンテンツ内のすべての画像へのレスポンシブクラス

この関数を使ってコンテンツ内のすべての画像にレスポンシブクラスを追加しましたが、これはWebサイトのHTML構造を壊します。これは、内容を次のようにラップします。<!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');

理由をお聞かせいただけますか?これに対する任意の代替解決策?

1

標準のPHPライブラリを使用してHTMLを適切に解析および変更することは非常に面倒です。たくさんの落とし穴があります。これは、コンテンツ内のすべての画像にimg-fluidクラスを追加する、十分に文書化された例です。

DoctypeタグとHTMLタグがHTMLフラグメントに追加されないようにするには、 this StackOverflow answerからの解決策を使用します。

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

私がリンクしたSO記事で議論されているこれを行う他の方法があることに注意してください、しかしこの解決法は私にはうまくいきました。

以下に掲載したコードでは、このソリューションを拡張してUTF-8文字も処理します。

/**
 * 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;
}
2
Dave Romsey