Display Excerpts From an RSS Feed, with Pagination
by
, 02-10-2016 at 02:45 PM (43817 Views)
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!
Demo - Display Excerpts From an RSS Feed, with Pagination: http://fofwebdesign.co.uk/template/_...pagination.php
The RSS file I'm working with is one generated by Joomla!, but it really can be any at all - sample below;The minimum PHP needed to get the contents of this RSS feed out onto a web page is this;Code:<?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>Unfortunately, this will spew out full stories and a massive amount of text.Code:<?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>'; ?>
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;Here's how that looks (with a bit of CSS to make it pretty);Code:<?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>'; ?>
Demo - Display Excerpts From an RSS Feed: http://fofwebdesign.co.uk/template/_...ss-excerpt.php
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;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;Code:$per_page = 5; // entries per page $range = 3; // number of pages each side of active page in paginationNow 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;Code: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"><<</a> <a href="'.$_SERVER['PHP_SELF'].'?page='.( $page - 1 ).'#rss" title="Previous" class="btn prev"><</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">></a> <a href="'.$_SERVER['PHP_SELF'].'?page='.$page_count.'#rss" title="Last" class="btn">>></a> '; } echo '</div>'; }To use the showPagination() function, just call this;Code:$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; }We have the calculations, and we've built the row of pagination buttons - here's how to actually paginate the items from your array;Code:showPagination($page, $page_count, $range);Again, I'm using the array of items from the RSS feed, but here's and example using a simplified array;Code:for ($i = $offset; $i < ($offset + $per_page); $i++) { echo '<li>'.$xml->channel->item[$i]->title.'</li>'; }Here's the full PHP code, with excerpt and pagination functions, for our RSS web page;Code:$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>'; }Here's how it all ties together on the web page (including CSS);Code:<?php $rss_file = 'path/to/rss.xml'; $rss_title = 'Featured Stories'; $words = 50; // words per excerpt $per_page = 5; // entries per page $range = 3; // number of pages each side of active page in pagination function excerpt($string, $count) { // excerpt $words = explode(' ', $string); if (count($words) > $count) { $words = array_slice($words, 0, $count); $string = implode(' ', $words).'...'; } return $string; } function showPagination($page, $page_count, $range) { // pagination 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"><<</a> <a href="'.$_SERVER['PHP_SELF'].'?page='.( $page - 1 ).'#rss" title="Previous" class="btn prev"><</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">></a> <a href="'.$_SERVER['PHP_SELF'].'?page='.$page_count.'#rss" title="Last" class="btn">>></a> '; } echo '</div>'; } $xml = simplexml_load_file($rss_file); $item_count = count($xml->channel->item); $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; } echo '<h2 id="rss">'.$rss_title.'</h2>'; showPagination($page, $page_count, $range); echo '<ul class="rss-items">'; for ($i = $offset; $i < ($offset + $per_page); $i++) { echo '<li> <h3><a href="'.$xml->channel->item[$i]->link.'" target="_blank">'.$xml->channel->item[$i]->title.'</a></h3> '.excerpt($xml->channel->item[$i]->description, $words).'<p><a href="'.$xml->channel->item[$i]->link.'" class="btn" target="_blank">Read More</a></p> </li>'; } echo '</ul>'; showPagination($page, $page_count, $range); ?>
Demo - Display Excerpts From an RSS Feed, with Pagination: http://fofwebdesign.co.uk/template/_...pagination.php
Feedback and questions welcome.
Bye for now.