Recent Topics

RSS cache

Started by on Jul 18, 2005 – Contents updated: Jul 18, 2005

Jul 18, 2005 20:15    

That versions put a cache on the feeds (just playing with headers)

/xmlsrv/rss.php


<?php
ob_start();
	/**
   * This template generates an RSS 0.92 feed for the requested blog's latest posts
	 *
	 * See {@link http://backend.userland.com/rss092}
	 *
	 * b2evolution - {@link http://b2evolution.net/}
	 * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
	 * @copyright (c)2003-2004 by Francois PLANQUE - {@link http://fplanque.net/}
	 *
	 * @package xmlsrv
	 */
  $skin = '';										// We don't want this do be displayed in a skin !
	$show_statuses = array();     // Restrict to published posts
	$timestamp_min = '';					// Show past
	$timestamp_max = 'now';				// Hide future
	/**
	 * Initialize everything:
	 */
  require dirname(__FILE__).'/../b2evocore/_blog_main.php';

    $lastpostdate = get_lastpostdate( $blog, $show_statuses, $cat, $catsel,	$timestamp_min, $timestamp_max );
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = getallheaders();

if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))){
	if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)){
		header("HTTP/1.1 304 Not Modified");
		ob_end_clean();
		exit;
	}
}

  
  header("Content-type: application/xml");
  echo "<?xml version=\"1.0\"?".">";
 
?>
<!-- generator="b2evolution/<?php echo $b2_version ?>" -->
<rss version="0.92">
  <channel>
		<title><?php 
			$Blog->disp( 'name', 'xml' );
			single_cat_title( ' - ', 'xml' ); 
			single_month_title( ' - ', 'xml' );
			single_post_title( ' - ', 'xml' );
		?></title>
    <link><?php $Blog->disp( 'blogurl', 'xml' ) ?></link>
    <description><?php $Blog->disp( 'shortdesc' ,'xml' ) ?></description>
    <language><?php $Blog->disp( 'locale', 'xml' ) ?></language>
    <docs>http://backend.userland.com/rss092</docs>
    <?php while( $Item = $MainList->get_item() ) { ?>
    <item>
      <title><?php $Item->title( '', '', false, 'xml' ) ?></title>
      <description><?php
        $Item->url_link( '', ' ', 'entityencoded' );
        $Item->content( 1, false, T_('[...] Read more!'), '', '', '', 'entityencoded' );
      ?></description>
      <link><?php $Item->permalink( 'single' ) ?></link>
    </item>
    <?php } ?>
  </channel>
<?
header("Last-Modified: ".$gmt_date);
header("ETag: \"{$hash}\"");
?>
</rss>
<?php log_hit();  // log the hit on this page 
ob_end_flush();
?>

atom.php


<?php
ob_start();
	/**
	 * This template generates an Atom feed for the requested blog's latest posts
	 *
	 * See {@link http://www.mnot.net/drafts/draft-nottingham-atom-format-02.html}
	 *
	 * b2evolution - {@link http://b2evolution.net/}
	 * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
	 * @copyright (c)2003-2004 by Francois PLANQUE - {@link http://fplanque.net/}
	 *
	 * @package xmlsrv
	 */
	$skin = '';										// We don't want this do be displayed in a skin !
	$show_statuses = array();			// Restrict to published posts
	$timestamp_min = '';					// Show past
	$timestamp_max = 'now';				// Hide future
	/**
	 * Initialize everything:
	 */
	require dirname(__FILE__).'/../b2evocore/_blog_main.php';

    $lastpostdate = get_lastpostdate( $blog, $show_statuses, $cat, $catsel,	$timestamp_min, $timestamp_max );
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = getallheaders();
    
if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))){
	if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)){
		header("HTTP/1.1 304 Not Modified");
		ob_end_clean();
		exit;
	}
}
    
	header("Content-type: application/atom+xml");

//     header("Content-type: text/xml");
	echo '<?xml version="1.0" encoding="utf-8"?'.'>';
?>
<feed version="0.3" xml:lang="<?php $Blog->disp( 'locale', 'xml' ) ?>" xmlns="http://purl.org/atom/ns#">
	<title><?php 
		$Blog->disp( 'name', 'xml' );
		single_cat_title( ' - ', 'xml' ); 
		single_month_title( ' - ', 'xml' );
		single_post_title( ' - ', 'xml' );
	?></title>
	<link rel="alternate" type="text/html" href="<?php $Blog->disp( 'blogurl', 'xml' ) ?>" />
	<tagline><?php $Blog->disp( 'shortdesc', 'xml' ) ?></tagline>
	<generator url="http://b2evolution.net/" version="<?php echo $b2_version ?>">b2evolution</generator>
	<modified><?php $MainList->mod_date( 'isoZ', true ) ?></modified>
	<?php while( $Item = $MainList->get_item() ) {	?>
	<entry>
		<title type="text/plain" mode="xml"><?php $Item->title( '', '', false, 'xml' ) ?></title>
		<link rel="alternate" type="text/html" href="<?php $Item->permalink( 'single' ) ?>" />
		<author>
			<name><?php $Item->Author->prefered_name( 'xml' ) ?></name>
			<?php $Item->Author->url( '<url>', "</url>\n", 'xml' ) ?>
		</author>
		<id><?php $Item->permalink( 'single' ) ?></id>
		<issued><?php $Item->issue_date( 'isoZ', true ) ?></issued>
		<modified><?php $Item->mod_date( 'isoZ', true ) ?></modified>
		<content type="text/html" mode="escaped"><![CDATA[<?php
			$Item->url_link( '<p>', '</p>' );
			$Item->content()
		?>]]></content>
	</entry>
	<?php } ?>
<?php
header("Last-Modified: ".$gmt_date);
header("ETag: \"{$hash}\"");
?>
</feed>
<?php log_hit(); // log the hit on this page
ob_end_flush();
?>

rss2.php


<?php
ob_start();
	/**
	 * This template generates an RSS 2.0 feed for the requested blog
	 *
	 * See {@link http://backend.userland.com/rss}
	 *
	 * b2evolution - {@link http://b2evolution.net/}
	 * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
	 * @copyright (c)2003-2004 by Francois PLANQUE - {@link http://fplanque.net/}
	 *
	 * @package xmlsrv
	 */
	$skin = '';										// We don't want this do be displayed in a skin !
	$show_statuses = array();			// Restrict to published posts
	$timestamp_min = '';					// Show past
	$timestamp_max = 'now';				// Hide future
	/**
	 * Initialize everything:
	 */
	require dirname(__FILE__).'/../b2evocore/_blog_main.php' ;

    $lastpostdate = get_lastpostdate( $blog, $show_statuses, $cat, $catsel,	$timestamp_min, $timestamp_max );
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = getallheaders();
if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))){
	if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)){
		header("HTTP/1.1 304 Not Modified");
		ob_end_clean();
		exit;
	}
}

    
	header("Content-type: application/xml");
	echo "<?xml version=\"1.0\"?".">";
?>
<!-- generator="b2evolution/<?php echo $b2_version ?>" -->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title><?php 
			$Blog->disp( 'name', 'xml' );
			single_cat_title( ' - ', 'xml' ); 
			single_month_title( ' - ', 'xml' );
			single_post_title( ' - ', 'xml' );
		?></title>
		<link><?php $Blog->disp( 'blogurl', 'xml' ) ?></link>
		<description><?php $Blog->disp( 'shortdesc', 'xml' ) ?></description>
		<language><?php $Blog->disp( 'locale', 'xml' ) ?></language>
		<docs>http://backend.userland.com/rss</docs>
		<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=<?php echo $b2_version ?>"/>
		<ttl>60</ttl>
		<?php while( $Item = $MainList->get_item() ) {	?>
		<item>
			<title><?php $Item->title( '', '', false, 'xml' ) ?></title>
			<link><?php $Item->permalink( 'single' ) ?></link>
			<pubDate><?php $Item->issue_date( 'r', true ) ?></pubDate>
			<?php // Disabled because of spambots: <author><php the_author_email( 'xml' ) ></author>?>
			<?php $Item->categories( false, '<category domain="main">', '</category>', '<category domain="alt">', '</category>', '<category domain="external">', '</category>', "\n", 'xml' ) ?>
			<guid isPermaLink="false"><?php the_ID() ?>@<?php echo $baseurl ?></guid>
			<description><?php
				$Item->url_link( '', ' ', 'xml' );
				$Item->content( 1, false, T_('[...] Read more!'), '', '', '', 'xml', $rss_excerpt_length );
			?></description>
			<content:encoded><![CDATA[<?php
				$Item->url_link( '<p>', '</p>' );
				$Item->content()
			?>]]></content:encoded>
			<comments><?php comments_link( '', 1, 1 ) ?></comments>
		</item>
		<?php } ?>
	</channel>
<?php
header("Last-Modified: ".$gmt_date);
header("ETag: \"{$hash}\"");
?>    
</rss>
<?php log_hit(); // log the hit on this page
ob_end_flush();
?>

rdf.php


<?php
ob_start();
	/**
	 * This template generates an RSS 1.0 (RDF) feed for the requested blog's latest posts
	 *
	 * See {@link http://web.resource.org/rss/1.0/}
	 *
	 * b2evolution - {@link http://b2evolution.net/}
	 * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
	 * @copyright (c)2003-2004 by Francois PLANQUE - {@link http://fplanque.net/}
	 *
	 * @package xmlsrv
	 */
	$skin = '';													 // We don't want this do be displayed in a skin !
	$show_statuses = array();			// Restrict to published posts
	$timestamp_min = '';								// Show past
	$timestamp_max = 'now';							// Hide future
	/**
	 * Initialize everything:
	 */
	require dirname(__FILE__).'/../b2evocore/_blog_main.php' ;
    
    $lastpostdate = get_lastpostdate( $blog, $show_statuses, $cat, $catsel,	$timestamp_min, $timestamp_max );
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = getallheaders();
if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))){
	if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)){
		header("HTTP/1.1 304 Not Modified");
		ob_end_clean();
		exit;
	}
}


	header("Content-type: application/xml");
	echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?".">";
?>
<!-- generator="b2evolution/<?php echo $b2_version ?>" -->
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"					xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel rdf:about="<?php $Blog->disp( 'blogurl', 'xmlattr' ) ?>">
	<title><?php 
		$Blog->disp( 'name', 'xml' );
		single_cat_title( ' - ', 'xml' ); 
		single_month_title( ' - ', 'xml' );
		single_post_title( ' - ', 'xml' );
	?></title>
	<link><?php $Blog->disp( 'blogurl', 'xml' ) ?></link>
	<description><?php $Blog->disp( 'shortdesc', 'xml' ) ?></description>
	<dc:language><?php $Blog->disp( 'locale', 'xml' ) ?></dc:language>
	<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=<?php echo $b2_version ?>"/>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
	<items>
		<rdf:Seq>
		<?php while( $Item = $MainList->get_item() ) { ?>
			<rdf:li rdf:resource="<?php $Item->permalink( 'single' ) ?>"/>
		<?php } ?>
		</rdf:Seq>
	</items>
</channel>
<?php
$MainList->restart();
while( $Item = $MainList->get_item() )
{ ?>
<item rdf:about="<?php $Item->permalink( 'single' ) ?>">
	<title><?php $Item->title( '', '', false, 'xml' ) ?></title>
	<link><?php $Item->permalink( 'single' ) ?></link>
	<dc:date><?php $Item->issue_date( 'isoZ', true ) ?></dc:date>
	<dc:creator><?php $Item->Author->prefered_name( 'xml' ) ?></dc:creator>
	<dc:subject><?php $Item->main_category( 'xml' ) ?></dc:subject>
	<description><?php
		$Item->url_link( '', ' ', 'xml' );
		$Item->content( 1, false, T_('[...] Read more!'), '', '', '', 'xml', $rss_excerpt_length );
	?></description>
	<content:encoded><![CDATA[<?php
		$Item->url_link( '<p>', '</p>' );
		$Item->content()
	?>]]></content:encoded>
</item>
<?php } ?>
<?php
header("Last-Modified: ".$gmt_date);
header("ETag: \"{$hash}\"");
?>
</rdf:RDF>
<?php log_hit(); // log the hit on this page
ob_end_flush();
?>

Aug 10, 2006 16:24

Thanks, just what I was looking for all day!

Very useful if, like me, you find the biggest bandwidth consumption on your site is from feeds.

However, using your code amendments I got warnings in my feed saying headers already sent. So I moved the last bit

    $hash = md5($gmt_date); 
    $headers = getallheaders(); 


to just after $headers = getallheaders();

Monitoring the situation with LiveHTTPheaders it apparently works. I'll wait and see what happens to my bandwidth stats.

I am running 0.9.1 if that makes a difference

Nov 11, 2006 10:49

I am currently testing the following code to see if it works well, just want to share it here since I took the code that Walter posted and modified it slightly.

Its for RSS2:


<?php
/**
 * This template generates an RSS 2.0 feed for the requested blog's latest posts
 *
 * See {@link http://backend.userland.com/rss}
 *
 * This file is not meant to be called directly.
 * It is meant to be called automagically by b2evolution.
 *
 * This file is part of the b2evolution project - {@link http://b2evolution.net/}
 *
 * @copyright (c)2003-2006 by Francois PLANQUE - {@link http://fplanque.net/}
 *
 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
 *
 * {@internal Open Source relicensing agreement:
 * Daniel HAHLER grants Francois PLANQUE the right to license
 * Daniel HAHLER's contributions to this file and the b2evolution project
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
 * }}
 *
 * @package evoskins
 * @subpackage rss
 *
 * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
 * @author blueyed: Daniel HAHLER.
 * @author fplanque: Francois PLANQUE - {@link http://fplanque.net/}
 *
 * @version $Id: _main.php,v 1.7.2.4 2006/09/05 22:32:41 fplanque Exp $
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

    $lastpostdate = $MainList->get_lastpostdate();
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = getallheaders();
    if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))) {
        if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)) {
            header("HTTP/1.1 304 Not Modified");
            exit;
        }
    }

    header("Last-Modified: ".$gmt_date);
    header("ETag: \"{$hash}\"");

skin_content_header( 'application/xml' );	// Sets charset!

echo '<?xml version="1.0" encoding="'.$io_charset.'"?'.'>';

?>
<!-- generator="<?php echo $app_name ?>/<?php echo $app_version ?>" -->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title><?php
			$Blog->disp( 'name', 'xml' );
			request_title( ' - ', '', ' - ', 'xml' );
		?></title>
		<?php
		switch( $disp )
		{
			case 'comments':
				// this includes the last comments if requested:
				require( dirname(__FILE__).'/_lastcomments.php' );
				break;

			default:
				?>
				<link><?php $Blog->disp( 'blogurl', 'xml' ) ?></link>
				<description><?php $Blog->disp( 'shortdesc', 'xml' ) ?></description>
				<language><?php $Blog->disp( 'locale', 'xml' ) ?></language>
				<docs>http://backend.userland.com/rss</docs>
				<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=<?php echo $app_version ?>"/>
				<ttl>60</ttl>
				<?php while( $Item = $MainList->get_item() ) {	?>
				<item>
					<title><?php $Item->title( '', '', false, 'xml' ) ?></title>
					<link><?php $Item->permanent_url( 'single' ) ?></link>
					<pubDate><?php $Item->issue_date( 'r', true ) ?></pubDate>
					<?php /* Disabled because of spambots: <author><php $Item->get_creator_User(); $Item->creator_User->email( 'xml' ) ></author> */ ?>
					<?php $Item->categories( false, '<category domain="main">', '</category>', '<category domain="alt">', '</category>', '<category domain="external">', '</category>', "\n", 'xml' ) ?>
					<guid isPermaLink="false"><?php $Item->ID() ?>@<?php echo $baseurl ?></guid>
					<description><?php
						$Item->url_link( '', ' ', '%s', array(), 'xml' );
						$Item->content( 1, false, T_('[...] Read more!'), '', '', '', 'xml', $rss_excerpt_length );
					?></description>
					<content:encoded><![CDATA[<?php
						$Item->url_link( '<p>', '</p>' );
						$Item->content()
					?>]]></content:encoded>
					<comments><?php comments_link( '', 1, 1 ) ?></comments>
				</item>
				<?php }
		}
		?>
	</channel>
</rss>
<?php
	$Hit->log(); // log the hit on this page

	// This is a self contained XML document, make sure there is no additional output:
	exit();
?>

Nov 12, 2006 03:27

I've added this feature to the transport optimizer idea.
It works only for the item feeds (not the comment ones).

May 08, 2008 17:35

I've just updated to 2.4.2, and I'm disappointed to find no last-modified headers in there at all!

I'm trying to add this to my atom skin file , but I find the function get_lastpostdate doesn't exist any more.

I also suspect the function skin_content_header in inc/skins/_skin.funcs.php might be a good way of doing this for all served pages.

Has anyone tried this? Or is there a way of doing get_lastpostdate in 2.4.2?

May 25, 2008 17:45

You'll find get_lastpostdate function in inc/items/model/_itemlistlight.class.php on line 825

May 26, 2008 17:04

Thanks sam2kb. I added to the following function in my inc/skins/_skin.funcs.php


function skin_content_header( $type = 'text/html' )
{
	global $generating_static, $io_charset;

	if( empty($generating_static) )
	{	// We use this method when we are NOT generating a static page
		header( 'Content-type: '.$type.'; charset='.$io_charset );
	}
	
function request_headers()
{
    if(function_exists("apache_request_headers")) // If apache_request_headers() exists...
    {
        if($headers = apache_request_headers()) // And works...
        {
            return $headers; // Use it
        }
    }

    $headers = array();

    foreach(array_keys($_SERVER) as $skey)
    {
        if(substr($skey, 0, 5) == "HTTP_")
        {
            $headername = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($skey, 0, 5)))));
            $headers[$headername] = $_SERVER[$skey];
        }
    }

    return $headers;
}

global $MainList;

$lastpostdate = $MainList->get_lastpostdate();
    $gmt_date = gmdate("D, d M Y H:i:s", mysql2date("U", $lastpostdate)) . ' GMT';
    $hash = md5($gmt_date);
    $headers = request_headers();
    if ((isset($headers["If-None-Match"])) || (isset($headers["If-Modified-Since"]))) {
        if(((ereg($hash, $headers["If-None-Match"]))) || ($headers["If-Modified-Since"] == $gmt_date)) {
            header("HTTP/1.1 304 Not Modified");
            exit;
        }
    }

    header("Last-Modified: ".$gmt_date);
    header("ETag: \"{$hash}\""); 
	
}

The request_headers function is in there because my host does not support getallheaders()

This works and now all my pages have ETags and Last-Modified dates that match the last post date. However, I'm not sure if the exit; part is exiting the skin_content_header function or generating the whole skin, and whether this then misses the point.


Form is loading...

Photo gallery software – This forum is powered by b2evolution CMS, a complete engine for your website.