CodeIgniter

CodeIgniter: Paginar resultados

CodeIgniter, como buen framework que es, tiene una librería para poder paginar nuestros resultados. En cuanto a paginar me refiero a tener la posibilidad de crear paginas entre resultados, por ejemplo, cada 10 resultados 1 pagina. Nosotros vamos a usar el código del blog que creamos en el artículo CodeIgniter: Aplicación Básica (I), Creación de un Blog.

Para empezar vamos a recuperar el código que nos muestra las entradas del blog:

Archivo: /application/controllers/blog.php
[code lang="php"]
function index()
{
$query = $this->db->orderby("id","desc");
$query = $this->db->;get("posts");

$this->load->helper("date");
$datestring = "%d-%m-%Y";

foreach ($query->result() as $row) {
$data["posts"][$row->id]["title"] = $row->title;
$data["posts"][$row->id]["url"] = $row->url_title;
$data["posts"][$row->id]["body"] = $row->body;
$data["posts"][$row->id]["date"] = mdate($datestring,$row->created_on);
}

$this->load->view("blog_front",$data);
}
[/code]

Para no complicar mucho la cosa con rutas y .htaccess vamos a cambiar los enlaces permanentes a nuestras entradas a localhost/blog/goto/enlace-permamente. Lo primero que tenemos que hacer en nuestro controlador es cargar la librería de pagination:

Archivo: /application/controllers/blog.php, Línea: 15
[code lang="php"]
$this->load->library("pagination");
[/code]

Justo antes de $this->load->helper(“date”);. Para usar esta librería tenemos que configurar varias cosas como: la URL base, el total de entradas que tenemos en la base de datos y el total por entrada. Una vez configurado, lo cargamos:

Archivo: /application/controllers/blog.php
[code lang="php"]
$this->load->library("pagination");

$config["base_url"] = base_url().index_page();
$config["total_rows"] = $this->db->count_all("posts");
$config["per_page"] = "4";

$this->pagination->initialize($config);
[/code]

También tenemos que especificar en que posición en la URL se va a especificar la pagina. Esto lo haremos con $this->uri->segment(); como usamos en el artículo anterior.

[code lang="php"]
$num = $this->uri->segment(1);
[/code]

Y lo más importante: como hacer las consultas a la base de datos. Para hacerlo mucho más fácil, vamos a usar un modelo. Es decir, en el controlador solo gestionaremos los datos y mandaremos al modelo hacer las consultas. Sin embargo vamos a usar un pequeño truco para pasar esta la información:

[code lang="php"]
if($num === "all"){
$data["posts"] = $this->blog_model->getPaginated("posts",$config["per_page"]);
} else {
if(!isset($num) OR !is_numeric($num)) $num = 0;
$data["posts"] = $this->blog_model->getPaginated("posts",$config["per_page"],$num);
}
[/code]

Primero comprobamos si $num es igual a all, si es así, mostramos las primeras entradas (las más recientes) limitando al numero que hemos configurado por pagina. Si esto no se cumple comprobamos si $num esta especificado (recordar que lo recupera de la URI) o si es realmente un número, sino atribuye el valor de la variable a 0. A partir de aquí, busca también a partir de $num valores los siguientes siendo estos especificados por pagina. Si veis como es el modelo lo veréis más claro:

Archivo: /application/models/blog_model.php
[code lang="php"]
class Blog_model extends Model
{

function __construct ()
{
parent::__construct();
}

function getPaginated($table,$num=-1,$offset=-1)
{
$sql = "SELECT * from ".$table." order by id desc";
if($num != -1)
$sql .= " limit ";
if($num != -1 AND $offset != -1)
$sql .= "$offset,";
if($num != -1)
$sql .= "$num";

$query = $this->db->query($sql);

$this->load->helper("date");
$datestring = "%d-%m-%Y";

foreach ($query->result() as $row) {
$data["posts"][$row->id]["title"] = $row->title;
$data["posts"][$row->id]["url"] = $row->url_title;
$data["posts"][$row->id]["body"] = $row->body;
$data["posts"][$row->id]["date"] = mdate($datestring,$row->created_on);
}

return $data["posts"];
}

}
?>
[/code]

Como podéis comprobar gran parte del código es el que ya usábamos en el controlador. Es importante que se guarde este fichero con el nombre de blog_model.php y lo carguemos luego en el controlador con $this->load->model(“blog_model”);.

Bien, nuestro controlador blog.php debería ser algo así:

Archivo: /application/controllers/blog.php
[code lang="php"]
function show()
{
$url_title = $this->uri->segment(2, 0);

if($url_title) {
$this->load->helper("date");
$datestring = "%d-%m-%Y";

$query = $this->db->where("url_title",$url_title);
$query = $this->db->get("posts");

foreach ($query->result() as $row) {
$data["post"]["id"] = $row->id;
$data["post"]["title"] = $row->title;
$data["post"]["url"] = $row->url_title;
$data["post"]["body"] = $row->body;
$data["post"]["date"] = mdate($datestring,$row->created_on);
}

$this->load->view("blog_single",$data);
} else {
redirect();
}
}
[/code]

Y también tenemos que editar el routes.php:

[code lang="php"]
$route['default_controller'] = "blog";
$route['scaffolding_trigger'] = "";

$route["blog"] = "blog";
$route["add"] = "blog/add";

$route["goto/:any"] = "blog/show";

$route[":any"] = "blog";
[/code]

Esto implica cambiar en blog_front.php y blog_single.php los enlaces permanentes por: /goto/enlace-permanente.

[code lang="php"]
anchor("goto/".$post["url"],"Enlace Permanente").
[/code]

Y para finalizar solo nos queda añadir los enlaces para crear las paginas. Esto lo hacemos con una función de la librería de pagination $this->pagination->create_links();, yo lo he añadido tal que así:

Archivo: /application/views/blog_front.php
[code lang="php"]

pagination->create_links();?>

foreach ($posts as $id => $post) {

echo "

".anchor("goto/".$post["url"],"#".$id)." ".$post["title"]."

";
echo "

".$post["body"]."

";
echo "".anchor("goto/".$post["url"],"Enlace Permanente")." - ".$post["date"]."";

}
?>

pagination->create_links();?>

Page rendered in {elapsed_time} seconds

[/code]

Conclusión

Con todo esto ya tenemos nuestras entradas al blog paginadas correctamente. Solo me queda decir que la idea me ha venido de una búsqueda que he visto en Google Analytics, así que espero que quien lo buscase pueda volver a encontrarlo otra vez.

Descargar el ejemplo del blog y la su contenido paginado: ipalaus-CodeIgniter_BlogExample_Pagination_v1.rar