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

Code

<?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

Code

<?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

Code

<?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

Code

<?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

Code

$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:

Code

<?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

Code

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.