[wp-hackers] XSLT: Sample implementation

David House dmhouse at gmail.com
Fri Jan 27 21:13:46 GMT 2006


I hacked together some XSLT to give us all something to talk about.
patch -p0 < patchfile from the attachment, give it a whirl.

Some problems:

1) Konqueror doesn't transform the feed. I have unconfirmed reports
that Safari doesn't either.
2) Atom support isn't there. Firefox and Konqueror (the browsers I
tested in) get scared off by Atom's mime type and prompt the user to
download it. They don't recognise it as XML, so they don't transform
it. We have two options here: give up or serve as text/xml (I guess
the latter won't be too popular). Really, browsers should recognise
application/atom+xml as something they can parse as XML and do so.

The Atom problem is fairly major. Users getting prompted to download
files out of the blue is still a usability hole.

No RSS 1.0 support, but I remember the tags being so similar that the
same XSLT can be used for both. Experiment.

--
-David House, dmhouse at gmail.com, http://xmouse.ithium.net
-------------- next part --------------
Index: wp-includes/classes.php
===================================================================
--- wp-includes/classes.php	(revision 3487)
+++ wp-includes/classes.php	(working copy)
@@ -1459,7 +1459,7 @@
 }
 
 class WP {
-	var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview');
+	var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'feed_stylesheet');
 
 	var $private_query_vars = array('posts_per_page', 'posts_per_archive_page', 'what_to_show', 'showposts', 'nopaging', 'show_post_type');
 
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 3487)
+++ wp-includes/functions.php	(working copy)
@@ -1684,6 +1684,11 @@
 	return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
 }
 
+function get_feed_stylesheet_uri() {
+	$feed_stylesheet = get_template_directory_uri() . '/feed.css';
+	return apply_filters('feed_stylesheet_uri', $feed_stylesheet);
+}
+
 function get_template() {
 	$template = get_settings('template');
 	if (!file_exists(get_theme_root() . "/$template")) { //works for dirs too
Index: wp-content/themes/default/feed.css
===================================================================
--- wp-content/themes/default/feed.css	(revision 0)
+++ wp-content/themes/default/feed.css	(revision 0)
@@ -0,0 +1,4 @@
+body, html { font-family: "Trebuchet MS", Arial, sans; background-color: #ccc }
+div#e { width: 800px; background-color: #fff; border: 1px solid #666; padding: 20px }
+
+h2 { font-size: 1.3em }
\ No newline at end of file
Index: wp-rss2.php
===================================================================
--- wp-rss2.php	(revision 3487)
+++ wp-rss2.php	(working copy)
@@ -10,6 +10,7 @@
 
 ?>
 <?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
+<?php echo '<?xml-stylesheet type="text/xml" href="/wp-feed.php?feed_stylesheet=true" ?'.'>'; ?>
 
 <!-- generator="wordpress/<?php bloginfo_rss('version') ?>" -->
 <rss version="2.0" 
Index: wp-xslt.php
===================================================================
--- wp-xslt.php	(revision 0)
+++ wp-xslt.php	(revision 0)
@@ -0,0 +1,75 @@
+<?php
+
+header('Content-Type: text/xml;charset=' . get_settings('charset'));
+
+switch ($feed) {
+
+case 'rss': 
+case 'rss2': 
+?>
+<?php echo '<?xml version="1.0" encoding="utf-8"?'.'>'; ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:template match="rss/channel">
+	<html>
+		<head>
+			<title><xsl:value-of select="title" /></title>
+			<link rel="stylesheet" type="text/css" href="<?php echo get_feed_stylesheet_uri(); ?>" />
+		</head>
+		<body>
+			<div id="e">
+				<h1 id="header"><abbr title="Really Simple Syndication">RSS</abbr> feed for <?php bloginfo('blogname'); ?></h1>
+				<p>This is an <abbr>RSS</abbr> feed for <a href="<?php bloginfo('siteurl'); ?>"><?php bloginfo('blogname'); ?></a>. It is a lightweight format that allows devices called 'Feed Readers' to read recent entries, useful because most feed readers manage anywhere between 10 and 5000 blogs. This feed is displayed in easy-read format here for you. <a href="http://whatisrss.com">Read more about <abbr>RSS</abbr></a></p>
+	
+				<ol id="posts">
+					<xsl:for-each select="item">
+						<li class="post">
+							<h2><a href="{link}"><xsl:value-of select="title" /></a></h2>
+							<p><xsl:value-of select="description" /></p>
+						</li>
+					</xsl:for-each>
+				</ol>
+			</div>
+		</body>
+	</html>			
+</xsl:template>
+
+</xsl:stylesheet>
+
+<?php
+break;
+
+case 'atom': ?>
+<?php echo '<?xml version="1.0" encoding="utf-8"?'.'>'; ?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:template match="feed">
+	<html>
+		<head>
+			<title><xsl:value-of select="title" /></title>
+			<link rel="stylesheet" type="text/css" href="/img/feed.css" />
+		</head>
+		<body>
+			<div id="e">
+				<h1 id="header">Atom feed for <?php bloginfo('blogname'); ?></h1>
+				<p>This is an Atom feed for <a href="<?php bloginfo('siteurl'); ?>"><?php bloginfo('blogname'); ?></a>. It is a lightweight format that allows devices called 'Feed Readers' to read recent entries, useful because most feed readers manage anywhere between 10 and 5000 blogs. This feed is displayed in easy-read format here for you.</p>
+	
+				<ol class="posts">
+					<xsl:for-each select="entry">
+					<li class="post">
+						<h2><a href="{link/@href}"><xsl:value-of select="title" /></a></h2>
+						<p><xsl:value-of select="summary" /></p>
+					</li>
+					</xsl:for-each>
+				</ol>
+			</div>
+		</body>
+	</html>
+			
+</xsl:template>
+
+</xsl:stylesheet>
+<?php
+break;
+}
+?>
\ No newline at end of file
Index: wp-feed.php
===================================================================
--- wp-feed.php	(revision 3487)
+++ wp-feed.php	(working copy)
@@ -12,7 +12,9 @@
     $feed = 'rss2';
 }
 
-if ( is_single() || ($withcomments == 1) ) {
+if ($feed_stylesheet) {
+	require ABSPATH . 'wp-xslt.php';
+} elseif ( is_single() || ($withcomments == 1) ) {
     require(ABSPATH . 'wp-commentsrss2.php');
 } else {
     switch ($feed) {



More information about the wp-hackers mailing list