web-dev-qa-db-fra.com

Insérer des attributs de largeur et de hauteur pour toutes les images affichées sur chaque page

À l'aide de la balise WordPress the_content, j'exécute une fonction personnalisée pour rechercher toutes les images ne possédant pas d'attribut width et height et insérer les dimensions appropriées. Ci-dessous la fonction:

add_filter( 'the_content', 'add_img_dimensions' );

function add_img_dimensions( $image_no_dimensions ) { // Insert width & height to images missing dimensions
    if ( preg_match_all( '/<img [^>]+width=[^>]+height=>/i', $image_no_dimensions, $result ) ) {
        // Do nothing...
    }
    else {
        preg_match_all( '/(alt|title|src)=("[^"]*")/i', $image_no_dimensions, $img );
        list( $width, $height, $type, $attr ) = getimagesize( str_replace( "\"", "" , ( $img[2][0] ) ) );
        $imgname = str_replace( "\"", "" , ( $img[2][0] ) );
    }

    return sprintf( '<img src="%s" width="%dpx" height="%dpx" />', str_replace("\"", "" , ( $img[2][0] ) ), $width, $height );
}

Par exemple, s'il y a une image sur l'une de mes pages qui ressemble à ceci:

<img src="https://link.to/sum/img.jpg" alt="Image Title" />

Il insérera alors les width et height de l'image réelle:

<img width="150" height="50" src="https://link.to/sum/img.jpg" alt="Image Title" />

La fonction fonctionne comme prévu. Cependant, tout le contenu de la page est remplacé par la première image trouvée sans dimensions définies.

Comment puis-je return tout le contenu mais ne changer que les images qui n'ont pas de dimension?

Avant et après enter image description here 

2

Testé et confirmé que cela fonctionne:

add_filter( 'the_content', 'add_image_dimensions' );

function add_image_dimensions( $content ) {

    preg_match_all( '/<img[^>]+>/i', $content, $images);

    if (count($images) < 1)
        return $content;

    foreach ($images[0] as $image) {
        preg_match_all( '/(alt|title|src|width|class|id|height)=("[^"]*")/i', $image, $img );

        if ( !in_array( 'src', $img[1] ) )
            continue;

        if ( !in_array( 'width', $img[1] ) || !in_array( 'height', $img[1] ) ) {
            $src = $img[2][ array_search('src', $img[1]) ];
            $alt = in_array( 'alt', $img[1] ) ? ' alt=' . $img[2][ array_search('alt', $img[1]) ] : '';
            $title = in_array( 'title', $img[1] ) ? ' title=' . $img[2][ array_search('title', $img[1]) ] : '';
            $class = in_array( 'class', $img[1] ) ? ' class=' . $img[2][ array_search('class', $img[1]) ] : '';
            $id = in_array( 'id', $img[1] ) ? ' id=' . $img[2][ array_search('id', $img[1]) ] : '';
            list( $width, $height, $type, $attr ) = getimagesize( str_replace( "\"", "" , $src ) );

            $image_tag = sprintf( '<img src=%s%s%s%s%s width="%d" height="%d" />', $src, $alt, $title, $class, $id, $width, $height );
            $content = str_replace($image, $image_tag, $content);
        }
    }

    return $content;
}
3
Nate Allen

Vous devez toujours renvoyer le contenu complet lorsque vous utilisez le filtre the_content. Quoi qu'il en soit, le code que vous avez ne pourra pas gérer plusieurs images de toute façon ... Une solution comme celle-ci pourrait le faire mieux, en extrayant d'abord toutes les balises d'image, puis en boucle pour éventuellement ajouter la largeur/hauteur à chacune et remplacer la balise d'origine:

add_filter( 'the_content', 'add_img_dimensions' );

function add_img_dimensions( $content ) { 

    preg_match_all( '/<img[^>]+>/i', $content, $images);
    if (count($images) < 1) {return $content;}

    foreach ($images as $image) {
        preg_match_all( '/(alt|title|src|width|height)=("[^"]*")/i', $image[0], $img );
        // Insert width & height to image if no width specified
        if (!isset($img[3])) {
            $imgalt = str_replace( "\"", "" , ( $img[0][0] ) );                                 
            $imgtitle = str_replace( "\"", "" , ( $img[1][0] ) );
            $imgname = str_replace( "\"", "" , ( $img[2][0] ) );                
            list( $width, $height, $type, $attr ) = getimagesize( $imgname );
            $newimagetag = sprintf( '<img src="%s" alt="%s" title="%s" width="%dpx" height="%dpx" />', $imgname, $imgalt, $imgtitle, $width, $height );
            $content = str_replace($image, $newimagetag, $content);
        }
    }

    return $content;
}

Remarque: non testé, je ne suis pas sûr d'avoir les références d'index parfaitement correctes. De même, vous perdrez tous les styles en ligne ou autres attributs (par exemple, les bordures) de cette façon, il serait donc nécessaire de procéder davantage pour les conserver.

0
majick