在WordPress后台中,我们如果从自带的媒体库中插入图片,且图片标题(caption)不为空时,WordPress会创建[-caption]这个标签,在编辑器的代码视图中,将会出现类似的代码(注:为禁止程序 解析而加入短标签中的-):

从WP媒体库中插入图片
[-caption id="attachment_28" align="aligncenter" width="480" caption="IIS中的URL Rewrite模块"]<a href="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg"><img class="size-full wp-image-28" title="URL Rewrite on IIS" src="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg" alt="IIS中的URL Rewrite模块" width="480" height="334" /></a>[/-caption]
前台输出对应的代码为:
<div id="attachment_28" class="wp-caption aligncenter" style="width: 490px">
<a href="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg">
<img class="size-full wp-image-28" title="URL Rewrite on IIS" src="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg" alt="IIS中的URL Rewrite模块" width="480" height="334" />
</a>
<p class="wp-caption-text">IIS中的URL Rewrite模块</p>
</div>
[-caption]短标签函数位于wp-includes目录里的media.php文件中701-741行(WP3.01),代码如下:
add_shortcode('wp_caption', 'img_caption_shortcode');
add_shortcode('caption', 'img_caption_shortcode');
/**
* 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'.
*
* @since 2.6.0
*
* @param array $attr Attributes attributed to the shortcode.
* @param string $content Optional. Shortcode content.
* @return string
*/
function 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="' . 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>';
}
[-caption]输出的html中,容器div用内联样式设定了宽度,值为图片宽度加10px,之所以多出来10px,是因为默认主题中的样式为容器内的图片左右设置了5px的边距:
#content .wp-caption img {
margin: 5px 5px 0;
}
个人觉得没有必要设置容器的宽度,网上也有人不喜欢这多出来的10px。当然,今天写这篇文章的原因不是因为这10px,CSSPod近期将投入使用的主题将使用HTML 5,所以我想把[-caption]输出的html用<figure>、<figcaption>组合,使其更加语义化,贴近HTML 5,此文应运而生。(题外话:WordPress 3.0的默认主题已经将Doctype改为HTML 5,不过也就仅此而已,正如国内部分网站自称使用HTML 5,其实也就改了一下Doctype,连语法都没有改变,更不用说新元素的应用了。)
正如上面提到,不是所有用户都想要[-caption]默认的输出内容,对于一些很个性化的主题,默认输出的代码并不适合;或者有的用户想使用lightbox之类的图片浏览插件,想在代码中加入相关钩子,等等。基本上有三种方式来修改输出内容:
- 扩展CSS并隐藏自动创建的div:可以立即排除此法,因为只有在有样式时才有效,而且代码标记仍然不巧当地存在;
- 插入图片后手动删除或者添加HTML代码:这也很麻烦,有时可能忘记操作,而且耗费无谓的时间和精力让人颇不爽;
- 通过插入钩子及过滤器调整所需输出代码。
下面我们就按照第三种思路,使用一点PHP来实现输出代码修改,需要重申的是,方法有很多种,至于选择哪一种,还是根据自己的需求而定。
插入的时候删除
通过返回真的函数添加disable_captions过滤器,以下代码可以放在插件中,或者放在主题functions.php中。

插入图片时删除caption短标签
add_filter( 'disable_captions', create_function('$a', 'return true;') );
过滤输出代码
可能有的用户并不想直接在插入编辑器的时候就移除短标签,而是想在主题中根据页面需要输出或不输出包裹图片的div。
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’.
引用文件的是官方对这个函数的说明,我们可以通过一个函数让短标签在前台不生成div标签。
add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );
同样可以放在主题functions.php中,或者放在插件里,这样前台就没有生成的div标签了。
这个过滤器可以结合条件语句使用,使过滤器只在特定页面激活。比如只有在首页的时候才激活过滤器:
if ( is_home() )
add_filter( 'img_caption_shortcode', create_function('$a, $b, $c', 'return $c;'), 10, 3 );
返回指定的HTML
有的时候,我们需要的不仅仅是删除多余的代码,而是希望按自己的需求输出代码。以CSSPod为例,我需要输出一个以HTML 5新元素、包裹的图片和标题组合,同时移除内联的样式。最终前台预想的代码为:
<figure id="attachment_28" class="wp-caption aligncenter">
<a href="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg">
<img class="size-full wp-image-28" title="URL Rewrite on IIS" src="http://static.csspod.com/images/2010/08/URL-Rewrite-on-IIS.jpg" alt="IIS中的URL Rewrite模块" width="480" height="334" />
</a>
<figcaption class="wp-caption-text">IIS中的URL Rewrite模块</figcaption>
</figure>
只需修改函数,复写默认的输出函数,代码如下(添加到插件或者主题functions.php中):
function csspod_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="' . esc_attr($id) . '" ';
return '<figure ' . $id . 'class="wp-caption ' . esc_attr($align) . '">'
. do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $caption . '</figcaption></figure>';
}
//Override default function
add_shortcode('wp_caption', 'csspod_img_caption_shortcode');
add_shortcode('caption', 'csspod_img_caption_shortcode');
为保证IE9以下版本能识别HTML 5的新元素,使用条件注释引入下面的脚本(放在functions.php中,也可以在主题header文件中直接加入):
function ltIE9_script() {
echo "<!--[if lt IE 9]><script type='text/javascript' src='http://static.csspod.com/lib/html5.js?ver=1.5.1'></script><![endif]-->\n";
}
add_action('wp_head', 'ltIE9_script');
关于这个脚本参见HTML5 enabling script及IE Print Protector。此外,我们可能还需要为新引入的HTML 5元素定义样式。