Blog (my web musings)

Find out what's interesting me, get tips, advice, and code gems that don't fit elsewhere.


Search Blog


Last month I showed you how to Get XML Data into a Web Page - this month we use that knowledge to create a paginated web page of featured story excerpts, from an RSS feed. The pagination script is a freebie that you can plug in to your own projects too! You certainly get lots for your money with this blog!

Display Excerpts From an RSS Feed, with Pagination:

Demo

The RSS file I'm working with is one generated by Joomla!, but it really can be any at all - sample below;

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
       <link>http://www.mywebsite.com/news</link>
       <item>
          <title>Story One</title>
         <link>http://www.mywebsite.com/news/story-one</link>
          <description><p>Story One text here.</p></description>
          <category>Main</category>
          <pubDate>Wed, 03 Feb 2016 00:00:00 +0000</pubDate>
       </item>
       <item>
          <title>Story Two</title>
          <link>http://www.mywebsite.com/news/story-two</link>
          <description><p>Story Two text here.</p></description>
          <category>Main</category>
          <pubDate>Wed, 03 Feb 2016 00:00:00 +0000</pubDate>
       </item>
       <item>
          <title>Story Three</title>
          <link>http://www.mywebsite.com/news/story-three</link>
          <description><p>Story Three text here.</p></description>
          <category>Main</category>
          <pubDate>Mon, 01 Feb 2016 00:00:00 +0000</pubDate>
       </item>
    </channel>
</rss>

The minimum PHP needed to get the contents of this RSS feed out onto a web page is this;

<?php

$rss_file = 'path/to/rss.xml';
$rss_title = 'Featured Stories';

$xml = simplexml_load_file($rss_file);
echo '<h2>'.$rss_title.'</h2>';
echo '<ul class="rss-items">';
foreach ($xml->channel->item as $item) {
    echo '<li>
       <h3><a href="'.$item->link.'" target="_blank">'.$item->title.'</a></h3>
            '.$item->description
       </li>';
    }
echo '</ul>';

?>

Unfortunately, this will spew out full stories and a massive amount of text.

Extract intro text as an excerpt

To make the web page easier to read, we can cut down on the amount of text show on screen by introducing a function that extracts a few sentences from the start of each story. This will act as a teaser to entice visitors to continue reading. Here's that PHP code again with a text excerpt() function added;

<?php

$rss_file = 'path/to/rss.xml';
$rss_title = 'Featured Stories';
$words = 50; // words per excerpt

function excerpt($string, $count) { // excerpt
    $words = explode(' ', $string);
    if (count($words) > $count) {
        $words = array_slice($words, 0, $count);
        $string = implode(' ', $words).'...';
        }
    return $string;
    }

$xml = simplexml_load_file($rss_file);
echo '<h2>'.$rss_title.'</h2>';
echo '<ul class="rss-items">';
foreach ($xml->channel->item as $item) {
    echo '<li>
    <h3><a href="'.$item->link.'" target="_blank">'.$item->title.'</a></h3>
        '.excerpt($item->description, $words).'<p><a href="'.$item->link.'" class="btn" target="_blank">Read More</a></p>
     </li>';
    }
echo '</ul>';

?>

Here's how that looks (with a bit of CSS to make it pretty) - Display Excerpts From an RSS Feed:

Demo

Better, but if you have lots and lots of content, the web page could still be very long. So let's paginate the output to display 5 excerpts at a time.

Paginate the excerpts - take-away PHP code to plug into any repetitive, looped output

The first thing we'll do is setup 2 variables, to define the number of entries shown per page, and the number of page buttons to show at either side of the active page in the row of pagination buttons;

$per_page = 5; // entries per page
$range = 3; // number of pages each side of active page in pagination

Next comes the showPagination() function - I've created a function so that I can reuse the code at the top and bottom of the page. This builds the row of pagination buttons for easier visitor navigation;

function showPagination($page, $page_count, $range) { 
    echo '<div class="pagination">';
    echo '<span class="pages">Page(s): </span>';
    if ($page > 1) {
        echo '<a href="'.$_SERVER['PHP_SELF'].'?page=1#rss" title="First" class="btn">&lt;&lt;</a> <a href="'.$_SERVER['PHP_SELF'].'?page='.( $page - 1 ).'#rss" title="Previous" class="btn prev">&lt;</a> | ';
        }
    for ($num = ($page - $range); $num < (($page + $range) + 1); $num++) {
        if($num > 0 && $num <= $page_count) {
           if($num == $page) {
               echo ' <span class="num">'.$num.'</span> |';
               } else {
               echo ' <a href="'.$_SERVER['PHP_SELF'].'?page='.$num.'#rss" class="num">'.$num.'</a> |';
               }
           }
        }
    if ($page != $page_count) {
        echo ' <a href="'.$_SERVER['PHP_SELF'].'?page='.( $page + 1 ).'#rss" title="Next" class="btn next">&gt;</a> <a href="'.$_SERVER['PHP_SELF'].'?page='.$page_count.'#rss" title="Last" class="btn">&gt;&gt;</a> ';
        }
    echo '</div>';
    }

Now we need some calculations to create pages for the items in an array - for us, the array is the items within the RSS feed, but you could define any array in the $item_count variable;

$item_count = count($xml->channel->item); // array
$page_count = ceil($item_count / $per_page);
$page = (isset($_GET['page']) && is_numeric($_GET['page'])) ? (int)$_GET['page'] : 1;
if ($page > $page_count) { $page = $page_count; }
if ($page < 1) { $page = 1; }
$remaining = $per_page - (($page * $per_page) - $item_count);
$offset = (($page - 1) * $per_page);
if ($remaining < $per_page) { $per_page = $remaining; }

To use the showPagination() function, just call this;

showPagination($page, $page_count, $range);

We have the calculations, and we've built the row of pagination buttons - here's how to actually paginate the items from your array;

for ($i = $offset; $i < ($offset + $per_page); $i++) { 
    echo '<li>'.$xml->channel->item[$i]->title.'</li>';
    }

Again, I'm using the array of items from the RSS feed, but here's and example using a simplified array;

$num_array = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten');

$item_count = count($num_array); // array

for ($i = $offset; $i < ($offset + $per_page); $i++) {
        echo '<li>'.$num_array[$i].'</li>';
    }

Check out the demo page to see the full PHP code, with excerpt and pagination functions, plus CSS, for our RSS web page - Display Excerpts From an RSS Feed, with Pagination:

Demo