How to have pagination in Frog CMS
Posted by ajcates on Thu, 13 Mar 2008
what you need:
- Clean urls example(http://ajcates.com/portfolio/ajcates-com) Tutorial
Pagination is the little links on the bottom of a page that allow you to basically click prev and next with your results. As we know frog does not have built in pagination, and really the only way to implement it is to do it by hand(Whats the point of a cms if you have to do it by hand?). My site has dynamic pagination and your frog powered site can have them as well.
The first goal is to be able to know which page the user is on. In order to do this we need to pull off variables in the url. If you create a new page and name it something like "Page" and type in yoursite.com/page/1 you will get a 404 error page unless you have a subpage under "Page" named 1. The way to fix this is to change the page behavior on the "Page" page to "Page not found". This will cause all 404s to direct to this page. So now you can have whatever url you want, and latter on I will show you how to keep your real 404s from displaying your list of articles. To do this we need to take the and extract the information from the url. This will place each chunk of the url into an array so mysite.com/page/1 which becomes Array("page", "1").
<?php
$uri = $_SERVER['QUERY_STRING'];
$uriArray = explode("/", $uri);
?>
Now we need to see if the first part of our array is really the word "page", and not a real 404. We use the alternative if statment to do this, because we will have regular plan text after it.
<?php if($uriArray[0] == "page" && 1 < count($uriArray)):?>
Ok in this piece of code we first check to see if the end number in our url is there, if it isn't the current page that the user is on is 1.
The next line of code is how many results per page we are going to have. The higher this number is the more articles per page the user will see. I have mine set to 3, because personally I hate scrolling down a bunch, and sometimes my posts can get rather long in length. If your just showing article titles you may want your number higher.
Next we find how many pages we have total, luckily frog has a very easy to use function built right in the system that does this for us.
Then we need calculate the last page number. After that we set up our article object.
<?php
if(end($uriArray) == null) {
//if the last part of our uriArray is not set, we must be on the first page.
$currentPage = 1;
} else {
$currentPage = end($uriArray);
}
$resultsPerPage = 3; //how many results per page you want.
$totalPages = $this->find('/articles/')->childrenCount(); //the total number of articles all together
$lastPageNumber = ceil($totalPages/$resultsPerPage);//calculateing the total number of pages.
$page_article = $this->find('/articles/');//our article object
?>
With our article object all set up and variables in place we can start displaying results. Our foreach statement is where all the magic happens, we only allow it to display the total number of results per page, then we offset it by our current page - 1 times the page we are on. For whatever page we are on, it will offset it to the correct article.
<?php foreach ($page_article->children(array('limit' => $resultsPerPage, 'offset' => ($currentPage-1) * $resultsPerPage, 'order' => 'page.created_on DESC')) as $article): ?>
<h1><?php echo $article->link(); ?></h1>
<?php echo $article->content(); ?>
<?php if ($article->hasContent('extended')) echo $article->link('Continue Reading…'); ?>
<p class="info">Posted by <?php echo $article->author(); ?> on <?php echo $article->date(); ?></p>
<?php endforeach; ?>
Next we just test to see if it is either the first or last page, and if it isn'tt add in a Next and Prev link.
<?php if($currentPage < $lastPageNumber):?>
<p><a class="prev" href="<?php echo $PUBLIC_URL; ?><?php echo $currentPage+1 ?>">Prev</a></p>
<?php endif; ?>
<?php if($currentPage > 1):?>
<p><a class="next" href="<?php echo $PUBLIC_URL; ?><?php echo $currentPage-1 ?>">Next</a></p>
<?php endif; ?>
Remember when I said I'd show you how to display regular 404 pages and how we didn't close the first if statement? Well we get to close it but before we do we need to add in a else statement so anything that doesn't have the word "page" in the first part of the url and is a 404 shows some text.
<?php else: ?>
<h1>Sorry</h1>
<p>This page does not exist.</p>
<?php endif; ?>
That is basically all there is to pagination here is the complete code.
<?php
$uri = $_SERVER['QUERY_STRING'];
$uriArray = explode("/", $uri);
?>
<?php if($uriArray[0] == "page" && 1 < count($uriArray)):?>
<?php
if(end($uriArray) == null) {
$currentPage = 1;
} else {
$currentPage = end($uriArray);
}
$resultsPerPage = 3;
$totalPages = $this->find('/articles/')->childrenCount();
$lastPageNumber = ceil($totalPages/$resultsPerPage);
$page_article = $this->find('/articles/');
?>
<?php foreach ($page_article->children(array('limit' => $resultsPerPage, 'offset' => ($currentPage-1) * $resultsPerPage, 'order' => 'page.created_on DESC')) as $article): ?>
<h1><?php echo $article->link(); ?></h1>
<?php echo $article->content(); ?>
<?php if ($article->hasContent('extended')) echo $article->link('Continue Reading…'); ?>
<p class="info">Posted by <?php echo $article->author(); ?> on <?php echo $article->date(); ?></p>
<?php endforeach; ?>
<?php if($currentPage < $lastPageNumber):?>
<p><a class="prev" href="<?php echo $PUBLIC_URL; ?><?php echo $currentPage+1 ?>">Prev</a></p>
<?php endif; ?>
<?php if($currentPage > 1):?>
<p><a class="next" href="<?php echo $PUBLIC_URL; ?><?php echo $currentPage-1 ?>">Next</a></p>
<?php endif; ?>
<?php else: ?>
<h1>Sorry</h1>
<p>This page does not exist.</p>
<?php endif; ?>
End Notes
Now if your a xhtml valid junkie like me you realize you are serving out a 404 header message when really this is part of your site, and valid xhtml doesn't have a 404 header. So I have a little hack that corrects this problem only down side is that all 404 pages will server up a 200 OK header.
ftp to yoursite/frog/plugins/page_not_found/index.php and open up the file for editing. Around lines 29 and 30 you will find this.
header("HTTP/1.0 404 Not Found");
header("Status: 404 Not Found");
Replace it with
header("HTTP/1.0 200 OK");
header("Status: 200 OK");