2

I've seen some variations of this question around, but I've as of yet been unable to tweak them into what I'm looking for.

In a Wordpress post, if an image is uploaded with a caption the image will be output wrapped in a div (with class wp-caption). Perfect. However, if there is no caption the image is wrapped in a paragraph tag. I'd like to replace this with a div. So if an image is uploaded without a caption, it is wrapped in a div as well — something like class="wp-nocaption".

My first try was to modify the media.php file. I changed this section:

if ( 1 > (int) $width || empty($caption) )
  return $content;
if ( $id ) $id = 'id="' . esc_attr($id) . '" ';
  return '<div ' . $id . 'class="wp-caption ' . esc_attr($align) 
  . '" style="width: ' . (10 + (int) $width) . 'px">'
  . do_shortcode( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>';

to this:

if ( 1 > (int) $width || empty($caption) )
  return '<div ' . $id . 'class="wp-nocaption ' . esc_attr($align) 
  . '" style="width: ' . ($width) . 'px">'
  . do_shortcode( $content ) . '</div>';

if ( $id ) $id = 'id="' . esc_attr($id) . '" ';
  return '<div ' . $id . 'class="wp-caption ' . esc_attr($align) 
  . '" style="width: ' . ($width) . 'px">'
  . do_shortcode( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>';

Which I hoped would do the same thing for a non-captioned image as a captioned one, except the div would have a different class.

But that didn't work. Does anyone have any idea why?

I also found some articles suggesting using a preg_replace function.

http://css-tricks.com/snippets/wordpress/remove-paragraph-tags-from-around-images/

https://wordpress.stackexchange.com/questions/7090/stop-wordpress-wrapping-images-in-a-p-tag

I tweaked their functions, attempting to replace paragraph tags that wrap an image wrapped in a link with div tags.

function filter_ptags_on_images($content) { 
  return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', 
  '/<div class="wp-nocaption">\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/div>/iU', 
  $content); 
}
add_filter('the_content', 'filter_ptags_on_images');

But this doesn't work. I've been reading a lot but still can't wrap my head around the php concept of "backreference". I know the replace section of my function is wrong, but I'm not sure how to fix it.

If you have any suggestions as to what I'm doing wrong on either way would be very much appreciated!

Thank you so much!!

Community
  • 1
  • 1
Graham
  • 41
  • 1
  • 6
  • 1
    For one thing, you're using Regex for a job that Regex is ill-equipped to handle. You should really use a [DOM Parser](http://php.net/manual/en/class.domdocument.php) for this. – maiorano84 Nov 19 '13 at 03:12
  • Thanks for the hint, maiorano84! But I don't really understand. I shouldn't try to change the wordpress function for images? – Graham Nov 21 '13 at 20:44
  • No, you can. Hooking into the content filter is the correct way to do it, especially if you need to wrap certain tags when certain conditions are met. What you shouldn't be doing is using Regex to parse HTML. What if the HTML is malformed? What if you have commented images? What if there's a space between the carat and img tag like so: `< img`? Using the correct tool for this job - in this case, PHP's built-in DOM Parser - will take all these things into account and future-proof your code. – maiorano84 Nov 21 '13 at 20:52
  • On a sidenote, the Regex-HTML issue [once caused an SO user to have a public meltdown](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#1732454) – maiorano84 Nov 21 '13 at 20:55
  • Hi, thanks again. I hate to ask, but could you show me what that would look like using PHP DOM? I've spent the last two days trying to learn the two but I still can't wrap my head around it. – Graham Nov 24 '13 at 21:57

0 Answers0