Google Reader 还有不到十天就关闭了,再次缅怀一下。Feedburner 头上也悬着一把达摩克利斯之剑,真令人不安。为数不多的好消息就是 Feedly 升级成 Feedly Cloud 了,纯 Web 端,界面也比 Google Reader 漂亮一些,发送到 Evernote、Twitter、Pocket 服务也更简单一点。Feedly 和国内的鲜果(可以跳墙抓取 Feedburner 和 Blogspot)目前看来是 Google Reader 最靠谱的替代品。

Feedburner 和 Feedsky 都有一个叫做“BrowserFriendly”的功能,就是用浏览器打开 Feed(实质上是一个 XML 文档)后,会将对人不友好的 XML 文档转换为 HTML 文档,配合 CSS 和 JavaScript 就可以有更好的可读性和更丰富的功能。这个转换过程不是依靠服务器,而是由浏览器客户端完成的,转换使用到了 XSLT ,注意不是 Excel 的 XLS 文件 :wink: !这是一种对 XML 文档进行转化的语言。XSLT 的使用不是三言两语可以说清楚的,具体可以看这里:XSLT 教程

我是在 Feedburner 和 Feedsky 提供的 XSLT 基础上大量!修改而来的,最终效果(先不要考虑是否美观的问题...)可以参考我的博客,地址在页面 Logo 的右上角。

transform.xsl,文件为 UTF-8 NO-BOM 格式,转换 XML 为 HTML(CSS 和 JS 的内容就不再贴出,下面的代码里面有地址):

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:output method="html" indent="yes" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
<xsl:variable name="title" select="/rss/channel/title" />
<xsl:variable name="feedUrl" select="/rss/channel/atom10:link[@rel='self']/@href" xmlns:atom10="http://www.w3.org/2005/Atom" />
<!-- HTML head -->
<xsl:template match="/">
	<xsl:element name="html">
		<head>
			<title><xsl:value-of select="$title" /> -- 欢迎订阅!</title>
			<!-- 加载样式表 -->
			<link href="http://xia.im/wp-content/themes/simgrey/feed/feedstyle.css" rel="stylesheet" type="text/css" media="all"/>
			<!-- 一些浏览器可以选择 RSS 源 -->
			<link rel="alternate" type="application/rss+xml" title="订阅 {$title}(博客原生 RSS 源)" href="{$feedUrl}"/>
			<!-- 解码 JS 的路径,只有 FireFox 需要用 JS 恢复格式 -->
			<xsl:if test="system-property('xsl:vendor')='Transformiix'">
				<xsl:element name="script">
					<xsl:attribute name="type">text/javascript</xsl:attribute>
					<xsl:attribute name="src">http://xia.im/wp-content/themes/simgrey/feed/decode.js</xsl:attribute>
				</xsl:element>
			</xsl:if>
		</head>
		<xsl:apply-templates select="rss/channel" />
	</xsl:element>
</xsl:template>
<!-- HTML body -->
<xsl:template match="channel">
	<!-- 只有 FireFox 需要执行 JS -->
	<body onload="if(navigator.userAgent.indexOf('Gecko/')>0)go_decoding();">
		<div id="container">
			<div id="leftcol">
				<div id="subscribe">
					<div id="subscribe-about">
						<p><strong>订阅博客:</strong>您可以选择订阅地址并添加到您惯用的 RSS 阅读器中。您也可以点击下列图标,添加订阅到在线 RSS 阅读器中。</p>
					</div>
					<div class="subscribe-desc">
						<p><a href="http://feeds.feedburner.com/neverweep/" title="推荐选择这个 RSS 源地址">Feedburner(推荐)</a></p>
					</div>
					<ul class="subscribe-items">
						<li>订阅地址 1</li>
						<li>订阅地址 2</li>
					</ul>
				</div>
			</div>
			<div id="rightcol">
				<div id="header">
					<!-- 博客标题 自动获取 -->
					<h1>
						<xsl:choose>
							<xsl:when test="link">
								<a href="{normalize-space(link)}" title=""><xsl:value-of select="$title" /></a>
							</xsl:when>
							<xsl:otherwise>
								<xsl:value-of select="$title" />
							</xsl:otherwise>
						</xsl:choose>
					</h1>
					<!-- 博客描述 -->
					<p id="blog-desc"><xsl:apply-templates select="description" /></p>
				</div>
				<!-- 文章内容,来自文章循环主体 -->
				<div id="main">
					<ul id="content"><xsl:apply-templates select="item" /></ul>
				</div>
				<!-- 尾部内容 -->
				<div id="footer">
					<p>
						<a rel="license" id="license" href="http://creativecommons.org/licenses/by/3.0/cn/"><img alt="知识共享许可协议" src="http://i.creativecommons.org/l/by/3.0/cn/80x15.png" /></a>
					</p>
				</div>
			</div>
			<div style="clear:both"></div>
		</div>
	</body>
</xsl:template>
<!-- 文章循环主体 -->
<xsl:template match="item" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<li class="regularitem">
		<!-- 文章标题 -->
		<h2 class="entry-title">
			<xsl:choose>
				<xsl:when test="guid[@isPermaLink='true' or not(@isPermaLink)]">
					<a href="{normalize-space(guid)}"><xsl:value-of select="title" /></a>
				</xsl:when>
				<xsl:when test="link">
					<a href="{normalize-space(link)}"><xsl:value-of select="title" /></a>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="title" />
				</xsl:otherwise>
			</xsl:choose>
		</h2>
		<!-- 文章发布时间 -->
		<p class="entry-date">
			<xsl:if test="count(child::pubDate)=1">
				发布时间:<xsl:value-of select="pubDate" />
			</xsl:if>
			<xsl:if test="count(child::dc:date)=1">
				发布时间:<xsl:value-of select="dc:date" />
			</xsl:if>
		</p>
		<!-- 文章内容 -->
		<div class="entry-content" name="decodeable">
			<xsl:call-template name="outputContent" />
		</div>
	</li>
</xsl:template>
<!-- 最终输出 -->
<xsl:template name="outputContent">
	<xsl:choose>
		<xsl:when xmlns:xhtml="http://www.w3.org/1999/xhtml" test="xhtml:body">
			<xsl:copy-of select="xhtml:body/*" />
		</xsl:when>
		<xsl:when xmlns:xhtml="http://www.w3.org/1999/xhtml" test="xhtml:div">
			<xsl:copy-of select="xhtml:div" />
		</xsl:when>
		<xsl:when xmlns:content="http://purl.org/rss/1.0/modules/content/" test="content:encoded">
			<xsl:value-of select="content:encoded" disable-output-escaping="yes" />
		</xsl:when>
		<xsl:when test="description">
			<xsl:value-of select="description" disable-output-escaping="yes"/>
		</xsl:when>
	</xsl:choose>
</xsl:template>
</xsl:stylesheet>

复制/wp-includes/feed-rss2.php一份作为 Feed 模板,命名为feed.php放到主题文件夹feed目录下,修改(请认真阅读注释!):

echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
echo '<?xml-stylesheet href="http:// 你的站点 /wp-content/themes/ 你的主题 /transform.xsl" type="text/xsl"?'.'>';
// 请注意 PHP 的结束标签
?>
<!-- // 根据 https://developer.mozilla.org/en-US/docs/XSL_Transformations_in_Mozilla_FAQ 的解释,FireFox 等浏览器必须在 rss 或 feed 标签之前有大于等于 512 个字节的内容,才会使用自定义 XSLT,否则将会使用浏览器自带的 XSLT 覆盖。所以请在这里凑够 512 个字节内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容 -->

文件编码记得由 ANSI 改为 UTF-8 NO-BOM 格式!

然后修改主题的functions.php,添加:

// 自定义 feed 输出
remove_all_actions( 'do_feed_rss2' );
add_action( 'do_feed_rss2', 'simgrey_feed_rss2', 10, 1 );
function simgrey_feed_rss2( $for_comments ) {
	$rss_template = get_template_directory() . '/feed/feed.php';
	// 仅当地址为 /feed/ 时才使用自定义 feed 输出(这里地址严格匹配,所以请修改为你博客的 feed 地址)
	if( $_SERVER["REQUEST_URI"] == '/feed/' && file_exists( $rss_template ) )
		load_template( $rss_template );
	else
		do_feed_rss2( $for_comments );
}

我做的限定条件:只有在输出最新文章且格式为 RSS 2.0 时才使用自定义模板。

经过这样处理后,就可以看到自定义的 Feed 模板了,如果编辑 XSL 出错也不会影响抓取 Feed 的程序,虽然你的浏览器可能不会显示内容,但是不论你看得见,或者看不见,你的 Feed 就在那里,不离不弃。 :smile:

  1. 折腾成功,看起来不错,等 feedsky 那天挂掉了,就把域名绑定到这个 feed 上。

  2. 测试了一下,没有出效果,正在排查中。

  3. 貌似没多少人会看这东东。。。

  4. markmark. 对比了一下, 比传统的好看一万倍!

  5. 好不容易看到一个月经贴,居然是这么头疼的内容。 :mad:

  6. 比直接输出好看多了。先 Mark 了,有空再折腾下 :cool: