WordPress全文带格式Feed输出攻略

2011-05-13 20:05 by hackerzhou

现在不少站点都有自动同步博客文章的功能,比如人人/开心和豆瓣就就可以自动抓取博客的Feed。但是由于文章中使用了代码高亮插件来渲染代码,因此格式就会被弄乱。WordPress默认的全Feed文输出是在<description>标签中显示摘要,然后在<content:encoded>标签中显示正文,这样浏览器渲染出来时只有摘要。本文用了一种简单的方法来实现全文Feed输出,同时能保留文章中用SyntaxHighlighter渲染的代码段,效果请见我的RSS Feed

修改的文件是wp-includes/feed-rss2.php,找到如下代码段:

<?php if (get_option('rss_use_excerpt')) : ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php else : ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
	<?php if ( strlen( $post->post_content ) > 0 ) : ?>
		<content:encoded><![CDATA[<?php the_content_feed('rss2') ?>]]></content:encoded>
	<?php else : ?>
		<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
	<?php endif; ?>
<?php endif; ?>

这段代码很好理解,要是打开了rss_use_excerpt这个选项(对应的设置项为“设置”-“阅读选项”-“对于 feed 中的每篇文章,显示XXX”),Feed只会输出摘要作为description,要是选择全文,那么除了输出摘要作为description外,还输出了文章内容。我们就在这里稍做修改来支持全文在description中输出,且保留换行和内嵌的代码段格式。将代码修改成如下样子:

<?php if (get_option('rss_use_excerpt')) : ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php else : ?>
		<description>
			<?php
				$content = $post->post_content;
				$content = apply_filters('the_content', $content);
				preg_match_all("/<pre class=\"brush:[^>]+>(.+?)<\\/pre>/s"
					, $content, $matches, PREG_PATTERN_ORDER);
				foreach($matches[1] as $match){
					$replacement = str_replace("&", "&amp;", $match);
					$content = str_replace($match, $replacement, $content);
				}
				$content = str_replace('>', '&gt;', $content);
				$content = str_replace('<', '&lt;', $content);
				$content = str_replace('&nbsp;', '&#160;', $content);
				echo $content;
			?>
		</description>
<?php endif; ?>

由于我使用了SyntaxHighlighter插件,在文章中使用[xxx][/xxx]这样的标记就可以用插件高亮代码段,apply_filters的时候会自动把代码包裹在<pre>标签里面。我们需要做pre里面的&字符转义,我实现的方法是先用正则来提取SyntaxHighlighter生成的pre标签,特征是该pre标签的class为brush,因此我写了上面的正则来进行匹配(当然大家可以根据实际情况调整提取pre的正则)。对于每一个匹配得到的结果(也就是每一组pre标签内容),将其中的&转义成&amp;。

另外,只要把大于和小于这两个符号替换成对应的转义符,就可以保持文章的换行以及格式不受改变。由于该php脚本只会在用户对文章进行增加/删除/修改操作是才会触发,生成一次feed并缓存,其余时候都是读取缓存,因此这样额外的操作不会经常被触发,性能上也能得到保障。

同理,大家可以修改feed-rss2-comments.php来使得评论也能进行保留格式的输出,这样就用不着那些全文Feed输出的插件了,自己动手,丰衣足食。

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 hackerzhou 并包含 原文链接
发表评论

本文有 9 条评论

  1. Oneplus
    2012-01-30 17:38

    博主你好,我碰到和你相似的问题。但是,我觉得改feed2.php并不是一个好思路,如果版本升级,还需要再改一次,照成不必要的麻烦。有没有其他的思路呢?

  2. love02xp
    2011-10-17 23:28

    我的是全文输出,可是格式全没了,不知道是怎么回事。。。

    • hackerzhou
      2011-10-18 09:50

      你过滤了大于和小于符号了么?不太明白你所说的格式没了是什么样子的。debug是必须的

  3. FreeGeeker猎头博客
    2011-10-14 23:11

    写的很好,这就去试用。先谢了!

  4. 米高
    2011-07-20 16:41

    真的是非常实用,虽然找到问题的原因,还是看了这篇才知道转义的匹配怎么写,总之谢谢了。

    • hackerzhou
      2011-07-21 11:32

      用熟练了就行,其实我对php也不怎么熟悉的

发表评论