Pregunta

I am developing my custom theme and trying to figure out how to modify the default code for WordPress image inserted into the post content, so I could add support for webP format and have it within <picture> element.

I generate .webp images using cwebp library on my server and PHP exec() while image upload to the Media in WordPress Admin.

The code is:

function my_image_webp($meta, $id){

    if(!isset($meta['sizes'])) {
        return $meta['full'];
    }

    $upload_path = wp_upload_dir();
    $path = $upload_path['basedir'];

    // media upload direktorij
    if(isset($path)){
        $file = trailingslashit($upload_path['basedir'].'/').$meta['file'];
    }else{
        $file = trailingslashit($upload_path['path']).$meta['file'];
    }

    list($orig_type) = @getimagesize($file);
    switch ($orig_type) {
            case IMAGETYPE_PNG:
            $png_image = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file);
            exec("cwebp ".$file." -o ".$png_image.".webp");
            break;
            case IMAGETYPE_JPEG:
            $jpg_image = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file);
            exec("cwebp ".$file." -o ".$jpg_image.".webp");
            break;
        }

        // return
        wp_update_attachment_metadata($id, $meta);
        return $meta;

    }
}
add_filter('wp_generate_attachment_metadata','my_image_webp', 10, 2);

Currently, my post content has got <img> element to display the thumbnail within <p> tag, but the <img> tag is a link <a> which points to the full-size image.

Currently I have got this for full-size image in the post content:

<p>
    <a href="http://www.example.com/wp-content/uploads/2018/11/image-full.jpg" itemprop="url" title="Some title">
        <img alt="Alt tag of the image" class="alignnone size-full" src="http://www.example.com/wp-content/uploads/2018/11/image-thumb.jpg" width="940" height="529">
    </a>
</p>

I am trying to modify it to get this as result:

<p>
    <a href="http://www.example.com/wp-content/uploads/2018/11/image-full.jpg" itemprop="url" title="Some title">
        <picture>
            <source srcset="http://www.example.com/wp-content/uploads/2018/11/image-thumb.webp" type="image/webp" />
            <img alt="Alt tag of the image" class="alignnone size-full" src="http://www.example.com/wp-content/uploads/2018/11/image-thumb.jpg" width="940" height="529">
        </picture>
    </a>
</p>

I have one or more images inserted like this. So, would need to check the whole post content and somehow modify/replace this?

Should I use some preg_replace() or WordPress image_send_to_editor() function?

Maybe using some filter?

Do you have any ideas how to change it?

I have found some solutions for <figure> element, but cannot get it working with <picture>.

¿Fue útil?

Solución

You have to loop through all images inside $post the_content() using foreach().

Which gives us, regex for group matching of <img> tag. Put all images into array().

Start counting from -1 since 0 has the 1st image already in array().

Loop through array() with images, find image with "size-full" with group match 3, if yes, get it's src value with group match 7.

After, replace src="value" extenstion - .png, .jpg ..., assign the replaced string to new variable. Use the new variable and add extension ".webp" to the it.

Replace existing <img> tags with <picture> element and call the function on $content.

function webp_picture_fix($content){
    global $post;
    preg_match_all("/<img(.*?)class=('|\")(.*?)('|\")(.*?)src=('|\")(.*?)('|\")(.*?)>/i", $content, $images);

    if(!is_null($images)){
        $i = -1;
        foreach ($images as $key) {
            $i++;
            //echo $key[$i];
            if(strpos($images[3][$i], 'size-full') !== false){
                //echo "hi";
                $slika_ekstenzija = $images[7][$i];
                $sewebp = preg_replace('/\\.[^.\\s]{3,4}$/', '', $slika_ekstenzija);
                $webp_slika_src = $sewebp.".webp";
                $replacement = '<picture><source srcset="'.$webp_slika_src.'" type="image/webp" /><img'.$images[1][$i].'class='.$images[2][$i].$images[3][$i].$images[4][$i].$images[5][$i].'src='.$images[6][$i].$images[7][$i].$images[8][$i].$images[9][$i].'></picture>';
                $content = str_replace($images[0][$i], $replacement, $content);
            }
        }
    }

    return $content;
}
add_filter('the_content', 'webp_picture_fix', 9999);
Licenciado bajo: CC-BY-SA con atribución
scroll top