domingo, 23 de diciembre de 2007

Plantillas en PHP (IV)

Cuarta parte de esta serie. Como había dicho vamos a finalizar con el ejemplo e incluir el paginador en la plantilla principal.


Podríamos, como dije en el anterior post, incluir el paginador en nuestra plantilla haciendo un include del archivo que contiene la plantilla. Podríamos pensar que si todas las plantillas están en la misma carpeta no tenemos que especificar la ruta de la plantilla paginador(¿podemos poner simplemente: include "paginador.phpt";?), pero esto no es así. Como vimos, la plantilla principal en última instancia se carga con un include por lo tanto tendrá como path el del archivo que la haya invocado. Esto es un problema ya que si la plantilla principal puede ser invocada desde scripts en diferentes carpetas la ruta del include del paginador debería variar! Para solventar esto añadiremos un método __toString al objeto Template:

function __toString(){
$this->dump();
return "";
}

Ojo, este método no devuelve una cadena de texto, sino que hace un echo de la plantilla. Es decir, no tendría sentido hacer $cadena=$miPlantilla->__toString() ya que $cadena quedaría vacía. Se que esto no es del todo ortodoxo pero veremos que es una forma muy buena de representar objetos en una plantilla.

Esto nos permitirá crear ambas plantillas por separado de modo que especificamos las rutas de la plantillas desde el script que las va a usar:

$miPlantilla=new Template("plantillas/miPlantilla.phpt");
$paginador=new Template("plantillas/paginador.phpt");

Ahora en nuestra plantilla principal añadimos debajo de la tabla:

<?=$PAGINADOR?>

y en nuestro código PHP haremos:

$miPlantilla->set("PAGINADOR",$paginador);

De esta forma conseguimos incluir el paginador en la plantilla principal de manera elegante.

A continuación veremos como nos quedaría nuestra plantilla principal:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?=$TITULO?></title>
<style type="text/css">
#paginador{
}
#paginador a.pagina{
}
#paginador a.pagina:hover{
}
#paginador a.pagina:visited{
}
</style>
</head>
<body>
<table>
<thead>
<tr><th>campo 1</th><th>campo 2</th></tr>
</thead>
<tbody>
<? foreach($DATOS AS $D): ?>
<tr><td><?=$D->CAMPO1?></td><td><?=$D->CAMPO2?></td></tr>
<? endforeach ?>
</tbody>
</table>
<?=$PAGINADOR?>
</body>
</html>

Si nos fijamos en la sección style he referenciado todos los estilos al id paginador de forma que estos estilos no van a afectar al resto de la página. Tendremos que tener esto en cuenta para no definir ningún otro elemento con id="paginador", ya que los id deben ser únicos.

Hemos dicho en el anterior post que para indicar la página a mostrar usaríamos la variable $_GET["pagina"]. Por lo que si no está definida tendremos que mostrar la primera página y en caso contrario la que nos indique la variable. Veamos entonces la parte de código PHP:

<?php
$num_por_pagina=10;
$pagina=(isset($_GET["pagina"])?$_GET["pagina"]:1);
$desplazamiento=$num_por_pagina*($pagina-1);

$miPlantilla=new Template("plantillas/miPlantilla.phpt");
$miPlantilla->set("TITULO","KROWORK: Anotaciones de PHP (página ".$pagina.")");
$miPlantilla->set("PAGINADOR",$paginador=new Template("plantillas/paginador.phpt"));

list($num)=mysql_fetch_row($result=mysql_query("SELECT COUNT(*) FROM mitabla"));
mysql_free_result($result);

$paginador->set("NUM_PAGINAS", ceil($num/num_por_pagina) );

$result=mysql_query(
"SELECT micampo1 as CAMPO1, micampo2 as CAMPO2 FROM mitabla LIMIT ".$desplazamiento.",".$num_por_pagina
);
while($obj=mysql_fetch_object($result)) $miPlantilla->setArray("DATOS",$obj);

$miPlantilla->dump();
?>

Es sencillo, legible y tenemos separada la parte de presentación de la lógica de la aplicación.

Otra mejora sería cambiar en la plantilla del paginador el src de las imágenes que hacen de botones de "página siguiente" y "página anterior" por dos variables. Si usamos, por ejemplo $URL_FLECHA_IZQUIERDA y $URL_FLECHA_DERECHA, podremos especificar distintas imágenes según el script que use la plantilla y además evitamos problemas con las rutas como sucedía con el include de la plantilla paginador en la principal.

No hay comentarios: