functions - How do I use <picture> element instead of <img> tags in WordPress post content having we

admin2025-06-06  1

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=".jpg" itemprop="url" title="Some title">
        <img alt="Alt tag of the image" class="alignnone size-full" src=".jpg" width="940" height="529">
    </a>
</p>

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

<p>
    <a href=".jpg" itemprop="url" title="Some title">
        <picture>
            <source srcset=".webp" type="image/webp" />
            <img alt="Alt tag of the image" class="alignnone size-full" src=".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>.

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/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/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/wp-content/uploads/2018/11/image-full.jpg" itemprop="url" title="Some title">
        <picture>
            <source srcset="http://www.example/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/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>.

Share Improve this question edited Nov 26, 2018 at 18:44 Kiki FIstrek Novi asked Nov 26, 2018 at 17:47 Kiki FIstrek NoviKiki FIstrek Novi 331 silver badge5 bronze badges 3
  • 1 I think there are several questions to unpack from this, 1) how do I make WP use picture elements instead of img elements. 2) How do I make WP generate webp versions of images on upload, both of which should be separate questions, not the same questions. Case in point, the first question of picture elements is much easier than the second, but you won't get those answers because people will need to answer the whole question ( and it must be a single whole answer ) – Tom J Nowell Commented Nov 26, 2018 at 18:38
  • 1 I'd recommend editing out the webp part of your question, then opening a second new question once you have the answer to "How do I use picture elements instead of img tags" – Tom J Nowell Commented Nov 26, 2018 at 18:38
  • 1 @TomJNowell - Just added the code for .webp image generation on image upload. – Kiki FIstrek Novi Commented Nov 26, 2018 at 18:45
Add a comment  | 

1 Answer 1

Reset to default 3

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);
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749150472a316795.html

最新回复(0)