-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Digg Style Pagination Non evasive aproach
Digg Style Pagination, Based on woopsicle's article
First of all thanks to woopsicle for making the first article. If you didnt read his article please do, it may suit your needs better than this one. I personally liked it very much and helped a lot, but i wanted a different approach that didn't change the way the default CodeIgniter lib works, and I didn't have to replace any CI core files which is a pain when updating CI. Furthermore i optimized the code a bit.
The only thing needed is to create a file named MY_Pagination.php and place it under the application/libaries folder so it gets loaded automatically when the Pagination library is loaded. Open that file and copy/paste the following code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2006, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* Pagination Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Pagination
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/pagination.html
*/
class MY_Pagination extends CI_Pagination
{
// --------------------------------------------------------------------
/**
* Generate the pagination links
*
* @access public
* @return string
*/
function create_links()
{
// If our item count or per-page total is zero there is no need to continue.
if ($this->total_rows == 0 OR $this->per_page == 0)
{
return '';
}
// Calculate the total number of pages
$num_pages = ceil($this->total_rows / $this->per_page);
// Is there only one page? Hm... nothing more to do here then.
if ($num_pages == 1)
{
return '';
}
// Determine the current page number.
$CI =& get_instance();
$get_page = array('page');
$page_num = $CI->uri->uri_to_assoc($this->uri_segment, $get_page);
if ($page_num['page'] != FALSE)
{
$this->cur_page = $page_num['page'];
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
$this->num_links = (int)$this->num_links;
if ($this->num_links < 1)
{
show_error('Your number of links must be a positive number.');
}
if ( ! is_numeric($this->cur_page))
{
$this->cur_page = 0;
}
// Is the page number beyond the result range?
// If so we show the last page
if ($this->cur_page > $this->total_rows)
{
$this->cur_page = ($num_pages - 1) * $this->per_page;
}
$uri_page_number = $this->cur_page;
$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
// Calculate the start and end numbers. These determine
// which number to start and end the digit links with
$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
$end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
// Add a trailing slash to the base URL if needed
$this->base_url = rtrim($this->base_url, '/') .'/';
// And here we go...
$output = '';
/* Render the "First" link (Optional)
if ($this->cur_page > $this->num_links)
{
$output .= $this->first_tag_open.'<a >base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
}
*/
// Render the "previous" link
if ($this->cur_page != 1)
{
$i = $uri_page_number - $this->per_page;
if ($i == 0) $i = '';
$output .= $this->prev_tag_open.'<a >base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
}
else
{
$output .= '<span class="disabled">'.$this->prev_link.'</span>';
}
//not enough pages to bother breaking it up
if ($num_pages < 7 + ($this->num_links * 2))
{
$output .= $this->pages_loop($start-1,$end);
}
//enough pages to hide some
elseif($num_pages > 5 + ($this->num_links * 2))
{
//Prepare First pages string
$first_pages = $this->num_tag_open.'<a >base_url.'">1</a>'.$this->num_tag_close;
$first_pages .= $this->num_tag_open.'<a >base_url.'page/'.$this->per_page.'">2</a>'.$this->num_tag_close;
$first_pages .= "...";
//Prepare Second pages string
$num_pages_minus = $num_pages-1;
$last_page_url = (($num_pages * $this->per_page) - $this->per_page);
$secondlast_page_url = ($last_page_url - $this->per_page);
$second_pages = "...";
$second_pages .= $this->num_tag_open.'<a >base_url.'page/'.$secondlast_page_url.'">'.$num_pages_minus.'</a>'.$this->num_tag_close;
$second_pages .= $this->num_tag_open.'<a >base_url.'page/'.$last_page_url.'">'.$num_pages.'</a>'.$this->num_tag_close;
//close to beginning; only hide later pages
if($this->cur_page < 1 + ($this->num_links * 2))
{
$output .= $this->pages_loop(1,3 + ($this->num_links * 2));
$output .= $second_pages;
}
//in middle; hide some front and some back
elseif($num_pages - ($this->num_links * 2) > $this->cur_page && $this->cur_page > ($this->num_links * 2))
{
$output .= $first_pages;
$output .= $this->pages_loop($this->cur_page - $this->num_links,$this->cur_page + $this->num_links);
$output .= $second_pages;
}
//close to end; only hide early pages
else
{
$output .= $first_pages;
$output .= $this->pages_loop($num_pages - (2 + ($this->num_links * 2)),$num_pages);
}
}
// Render the "next" link
if ($this->cur_page < $num_pages)
{
$output .= $this->next_tag_open.'<a >base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;
}
else
{
$output .= '<span class="disabled">'.$this->next_link.'</span>';
}
/* Render the "Last" link (Optional)
if (($this->cur_page + $this->num_links) < $num_pages)
{
$i = (($num_pages * $this->per_page) - $this->per_page);
$output .= $this->last_tag_open.'<a >base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close;
}
*/
// Kill double slashes. Note: Sometimes we can end up with a double slash
// in the penultimate link so we'll kill all double slashes.
$output = preg_replace("#([^:])//+#", "\\1/", $output);
// Add the wrapper HTML if exists
$output = $this->full_tag_open.$output.$this->full_tag_close;
return $output;
}
function pages_loop ($start,$end)
{
$output = "";
for ($loop = $start; $loop <= $end; $loop++)
{
$i = ($loop * $this->per_page) - $this->per_page;
if ($i >= 0)
{
if ($loop == $this->cur_page)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
$n = ($i == 0) ? '' : 'page/'.$i;
$output .= $this->num_tag_open.'<a >base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
}
}
}
return $output;
}
}
?>
This will replace the create_links() function that the Pagination library uses to generate the page links. You're done! You now have Digg like functionality in the pagination. It will work exactly the same as the default lib so you don't have to change anything.
If you want to add the look, you can create a css file with the code that woopsicle kindly provided:
div.pagination
{
padding: 3px;
margin: 3px;
}
div.pagination a
{
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #AAAADD;
text-decoration: none; /* no underline */
color: #000099;
}
div.pagination a:hover, div.pagination a:active
{
border: 1px solid #000099;
color: #000;
}
div.pagination span.current
{
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #000099;
font-weight: bold;
background-color: #993300;
color: #FFF;
}
div.pagination span.disabled
{
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #EEE;
color: #DDD;
}
And then
<div class="pagination">
<?=$this->pagination->create_links();?>
</div>
Thats all, hope it helps. If you have anything to add/optimize please do.