1

There are a few questions that are similar to this but I have not found anything that works with the latest version of WordPress. I am trying to wrap adjacent images into the one div.

<p>
  <img> />
  <img> />
  <img> />
  Some text.
</p>

into:

<p>
 <div>
  <img> />
  <img> />
  <img> />
 </div>  
Some text.
</p>

I can wrap each image into its own div using:

function wrapImagesInDiv($content) {
   $pattern = '/(<img[^>]*class=\"([^>]*?)\"[^>]*>)/i';
   $replacement = '<div>$1</div>';
   $content = preg_replace($pattern, $replacement, $content);
   return $content;
}
add_filter('the_content', 'wrapImagesInDiv');

and I think it would be possible to edit the regex to wrap multiple img tags using {2,} but have failed to get it to work.

Any ideas?

Edit

Thanks to Beee, this works for my needs but feels very clunky. Any improvements welcome.

add_filter( 'the_content', 'add_image_wrapper', 99, 1 );
function add_image_wrapper( $content ) {
    $content = preg_replace_callback( '/<img[^>]+>|<p>|<br>/im',
        function( $matches ) use (&$inimg) {

        $fulltag   = $matches[0];    
        preg_match('/<(img)[^>]+>|<(p)>|<(br)>/',$fulltag,$tag);  

        $tag = $tag[1];

        if ( $tag === 'img') {
            ( $inimg == true) ? $tag = 1 : $tag = 0;
            ( $inimg == false ) ? $inimg = true : $inimg;
        }                          
        else {
            ( $inimg == true) ? $tag = 2 : $tag = 3;                    
            ( $inimg == true ) ? $inimg = false : $inimg;
        }

        switch ($tag) {
          case 0: //no preceding img tag
              return sprintf( '<div>%s', $fulltag );
              break;
          case 1: //preceding img tag
              return sprintf( '%s', $fulltag );
              break;
          case 2: //last image tag
              return sprintf( '</div>%s', $fulltag );
              break;
          case 3:
              return sprintf( '%s', $fulltag );
              break;
       }
    }, $content );

    return $content;
}
  • /(([| ]{0,}(<img.+?\/>)[\s|\n| ]{0,}){3})/i is about as far as I got, but i give up. worked to find three images, but changing {3} to {0,} just messed everything up. not an answer, but maybe it'll help. – David Sword Mar 1 '18 at 23:59
  • what you want to get is a broken HTML. DIV should not be in a P – Mark Kaplun Mar 2 '18 at 3:48
  • I know the P tag is wrong as a wrapper for a DIV, but it's what WorPress spits out for the post. I know I can manually edit the page to reformat it but my users won't necessarily be confident to do this. My other option is a custom post format. – jonnyfishman Mar 2 '18 at 11:48
  • please post your solution as an answer and accept it. – Mark Kaplun Mar 5 '18 at 5:19
1

This is a function I use to add a wrapper to each image. I know it's not 100% what you want, but I thought this might give you a handle to work from.

function add_image_wrapper( $content ) {
    $content = preg_replace_callback( '/<img[^>]+>/im', function ( $matches ) {
        $image   = $matches[0];
        $classes = array();
        preg_match( '/class="align([^"]+)"/im', $image, $classes );

        $align = ( ! empty( $classes ) ? $classes[1] : null );
        $class = '';
        if ( in_array( $align, array( 'left', 'right' ) ) ) {
            $class = 'media--align-' . $align;
        }

        return sprintf(
            '<div class="media %s">%s</div>',
            $class, $image
        );
    }, $content );

    // Remove unnecessary classes from media-wrappers inside figures
    $content = preg_replace_callback( '/<figure[^>]+>.+<\/figure>/im', function ( $matches ) {
        $figure = $matches[0];

        return preg_replace( '/class="media[^"]+"/im', 'class="media"', $figure );
    }, $content );

    return $content;
}
add_filter( 'the_content', 'add_image_wrapper', 99, 1 );
  • Great idea to use the callback. I have edited original question with a working solution. I'm not a fan of all of the conditionals and I'm sure there are situations where it will break, but I'd be interested to see if anyone can improve it. – jonnyfishman Mar 2 '18 at 11:37
  • Can you use a gallery for this ? Because a gallery already has defined containers/classes. – Beee Mar 2 '18 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.