Filter caption-Shortcode in WordPress

The title may not speak for itself and therefore I will explain a little more on the topic and do not just put a code snippets on this post.

If you use the „Mediauploader“ in WordPress not just to load images, but also for integration in the post or page, then a Shortcode will be created and be insert in the content if you leave a picture title for this picture. The title should be maintained, because it will be used as alt-attribute to the img-Tag.

Not every user is satisfied with this issue and I'll show, how you can change the output.

wp_mediabox

Exists a title to a picture, then the Shortcode will be insert, which will output a div, as you can see in this example:

<div id="attachment_34" class="wp-caption alignnone" style="width: 160px"><img class="size-thumbnail wp-image-34" title="1" src="pfad_zum_bild" alt="Caption, Bildtitel" width="150" height="150" />
	<p class="wp-caption-text">Caption, Bildtitel</p>
</div>

But not all users want to use this Shortcode and adjust the output with it. There are basically three ways to adjust the output.

  1. After inserting manually delete or incorporate your own HTML
  2. Expand CSS and hide the created div
  3. Via Hook intervene and filter the div prior to the output or adapt to your needs

From my point of view, 2 can be excluded immediately, since it only works in connection with CSS, and therefore the markup still remains so inadequately.

The first point is not clean as well, since the risk of forgetting and the overhead in creating articles is not really pleasant.

Therefore let's take a look at point 3 of the selected options and use a little bit PHP. Again there are various approaches, and so I have three quite different ways how to do it but the decision which one to use, I will leave it on you. Depending on the requirements it will be also very different.

Delete while you insert

WordPress asks the filter disable_captions and creates the Shortcode: if ( ! apply_filters( 'disable_captions', '' ) ) {. At this point I will use a function which returns true. Therefore a Shortcode won't be insert when you insert a picture.

add_filter( 'disable_captions', create_function('$a', 'return true;') );

wp_caption_shortcode

The function is put in either a plugin or in the functions.php of the theme.

Filter the output

Now, however, you may not always want the Shortcode to be removed, and in some cases like to use the possibility in your frontend. That means, the Shortcode is allowed to be used in some cases.
Even for that WordPress has a function, which I will use and it won't generate a div in the frontend.

img_caption_shortcode($attr, $content = null)
The Caption shortcode.

Allows a plugin to replace the content that would otherwise be returned. The
filter is 'img_caption_shortcode' and passes an empty string, the attr
parameter and the content parameter values.

The supported attributes for the shortcode are 'id', 'align', 'width', and
'caption'.

The quote comes from the description of the function.

add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );

Also this function is put in the functions.php of the theme or in a Plugin. As of now there is no markup in the frontend generated by the Shortcode.

This filter can be combined with several conditional tags and so the filter will only be active on a specific page. The following example filters only when you are on the homepage of the blog:

if ( is_home() )
	add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );

Deliver your own HTML

If you demand a certain level of quality in your markup, then these functions won't help and you must generate your own markup. As an example, I'll output the title of the image in a definition list. This option is my favorite.

I show a simple solution that is easy to adapt to your needs. The resulting markup is thus freely available and the possible variables are included, so that adjustments are not so hard to do. The result, however, emerged that the markup is quite extensive, but it's only a demo and it shows all the possibilities you can use. Otherwise you should, in my opninion, not use inline style in a definition list.

As a result of the following function, which has to be implemented in your functions.php of your theme or Plugin, it generates the following markup:

<dl id="attachment_34" class="wp-caption alignnone" style="width: 160px">
	<dt><a href="pfad_zum_bild"><img class="size-thumbnail wp-image-34" title="1" src="pfad_zum_bild" alt="Caption, Bildtitel" width="150" height="150" /></a></dt>
	<dd class="wp-caption-text">Caption, Bildtitel</dd>
</dl>
function fb_img_caption_shortcode($attr, $content = null) {

	// Allow plugins/themes to override the default caption template.
	$output = apply_filters('img_caption_shortcode', '', $attr, $content);
	if ( $output != '' )
		return $output;

	extract(shortcode_atts(array(
		'id'	=> '',
		'align'	=> 'alignnone',
		'width'	=> '',
		'caption' => ''
	), $attr));

	if ( 1 > (int) $width || empty($caption) )
		return $content;

	if ( $id ) $id = 'id="' . $id . '" ';

	return '<dl ' . $id . 'class="wp-caption ' . $align . '" style="width: ' . (10 + (int) $width) . 'px"><dt>'
	. do_shortcode( $content ) . '</dt><dd class="wp-caption-text">' . $caption . '</dd></dl>';
}

add_shortcode('wp_caption', 'fb_img_caption_shortcode');
add_shortcode('caption', 'fb_img_caption_shortcode');

I hope that this post will make it easier for some web designers and their daily cursing on this topic will decrease a little bit. :)
Suggestions, criticism and noticed errors are always welcome.

Comments are closed.

11 comments

  1. john

    I added add_filter( 'disable_captions', create_function('$a', 'return true;') ); to my theme's functions.php and I am still getting captions in 2.7.1 on the home page and single post page. Am I missing something in getting captions turned off so I can include alt text again?

  2. Mark

    Great Help. saved me couple of hours of digging through code

  3. Laurent

    I can't get it, I'm sorry...
    I put that code at the end of my functions.php and nothing... It just remove the old shortcodes but no replacement at all... Am I forgetting something ?

    add_filter( 'disable_captions', create_function('$a', 'return true;') );
    add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );
    function fb_img_caption_shortcode($attr, $content = null) {

    // Allow plugins/themes to override the default caption template.
    $output = apply_filters('img_caption_shortcode', '', $attr, $content);
    if ( $output != '' )
    return $output;

    extract(shortcode_atts(array(
    'id' => '',
    'align' => 'alignnone',
    'width' => '',
    'caption' => ''
    ), $attr));

    if ( 1 > (int) $width || empty($caption) )
    return $content;

    if ( $id ) $id = 'id="' . $id . '" ';

    return ''
    . do_shortcode( $content ) . '' . $caption . '';
    }

    add_shortcode('wp_caption', 'fb_img_caption_shortcode');
    add_shortcode('caption', 'fb_img_caption_shortcode');

  4. Alex

    With this function it won't change anything as you recognized, In this case we just put out everything via dl-list, which is a better semantic , If you like to change the output, your have to adjust the syntax of return.

    return '<dl ' . $id . 'class="wp-caption ' . $align . '" style="width: ' . (10 + (int) $width) . 'px"><dt>'
     . do_shortcode( $content ) . '</dt><dd class="wp-caption-text">' . $caption . '</dd></dl>';

  5. Laurent

    I'll give it a try asap, it's a dumb thing, why didn't I think about that ?
    (hit me :))

  6. Arpit Jacob

    Just Perfectly what I needed, You turned up in my google search thankfully otherwise I would have spent hours trying to figure this out.

  7. Alex

    @Arpit, glad to save you some hours :)
    @Laurent, just hit you ;)

  8. rami

    wow, i was looking for solution to this problem. thanks!

  9. Doug

    I just published a gallery plugin that expands its control to include captions thanks to your post. Very helpful!

    I expanded on the shortcode concept a bit and include a new container shortcode for captions (captiongroup) that if you sandwich any captions within, they will be rendered inside a styled container.... sort of a "mini gallery". Excellent for having multiple sets of images dispersed throughout a post for discussion purposes.

    You can see the plugin demonstrated live here:
    http://www.dyerware.com/main/products/gallery-and-caption/gallery-and-caption-plugin-for-wordpress.html

    Again my thanks!

  10. deschamps_24

    Hi
    i am trying to find a solution to put a language filter before the caption output in the built-in wordpress gallery, as I have a multilanguage blog and would like to display different captions in each language. I haev not had any luck so far. Normally, I just insert apply_filter('the_title', $title) or 'the_content', etc. in plugins or functions, but in this one, I have no idea where to insert this filter, and what the first element of the filter should be. Help would be very much appreciated! THANK YOU.

  11. Stuart

    I've been trying to figure this out, too using the code on this page but it doesn't seem to work. Here is the code I'm using. Am I missing something?

    Thanks so much.

    add_filter( 'disable_captions', create_function('$a', 'return true;') );
    add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );

    function MYNAME_img_caption_shortcode($attr, $content = null) {

    // Allow plugins/themes to override the default caption template.
    $output = apply_filters('img_caption_shortcode', '', $attr, $content);
    if ( $output != '' )
    return $output;

    extract(shortcode_atts(array(
    'id' => '',
    'align' => 'alignnone',
    'width' => '',
    'caption' => ''
    ), $attr));

    if ( 1 > (int) $width || empty($caption) )
    return $content;

    if ( $id ) $id = 'id="' . $id . '" ';

    return ''
    . do_shortcode( $content ) . '' . $caption . '';
    }

    add_shortcode('wp_caption', 'MYNAME_img_caption_shortcode');
    add_shortcode('caption', 'MYNAME_img_caption_shortcode');