AJAX paso a paso: paginación de entradas para WordPress
Siguiendo con AJAX, hoy vamos a realizar un ejemplo que puede ser útil para los usuarios de WordPress. Se trata de un marco que muestra una lista con las entradas de nuestro blog, con paginación y efecto de fundido para darle más vistosidad.

El método que vamos a seguir es el siguiente: la aplicación se conecta mediante AJAX a un script PHP que nos devuelve 5 entradas del blog, las cuales mostraremos en la ventana, inicialmente carga 3 páginas y cuando se avance en la paginación irá cargando otra página.
Esta es la parte AJAX, la parte HTML funciona de la siguiente manera: hay un marco que tiene clipping para solo mostrar lo que nos interesa, y donde estará la página actual que estamos viendo, el resto de las páginas estarán a la derecha o a la izquierda de esta (ocultas debido al clipping). Si se avanza en la paginación, la página actual irá a la izquierda al igual que la nueva que se va a mostrar (que se habrá cargado con AJAX y que inicialmente estará a la derecha). Si se retrocede en la paginación, la página actual irá a la derecha, al igual que la que queremos mostrar. A parte habrá un efecto de fundido para darle más espectacularidad.
La parte PHP es las más sencilla, consta de dos partes: una que obtiene los datos de la base de datos y otra que crea un XML con los datos y los devuelve.
En WordPress existe una tabla que se llama wp_posts que contiene las entradas del blog, tiene dos columnas que nos interesan: el tÃtulo del post (post_title) y la url del post (guid). Estas dos columnas son las que necesitamos para crear nuestra lista de entradas.
$inc = 5;
$pos = $_GET['pos'];
// Conectamos a la BD
$bd = mysql_connect("localhost", $usuario, $password) or
die("No se puede conectar a la BD: " . mysql_error());
mysql_select_db($nombreBD);
// Obtenemos las entradas y sus enlaces
$res = mysql_query("SELECT guid, post_title FROM wp_posts w where guid is not null AND guid <> '' LIMIT ".($pos-1).", ".($pos+$inc-1));
$datos = null;
// Cargamos los datos en un array
while ($fila = mysql_fetch_array($res)) {
$datos[count($datos)] = array($fila['guid'], $fila['post_title']);
//$datos[count($datos)] = array($fila, $fila);
}
// Liberamos
mysql_free_result($res);
mysql_close($bd);
La creación del XML es simple: leemos los datos, nos creamos una cadena de texto con el XML y lo devolvemos. El XML tiene una raÃz llamada datos (como en los ejemplos anteriores de AJAX que hemos publicado), y de este cuelga una elemento entrada por cada uno de los post, y este a su vez un elemento titulo y otro url:
// Devuelvo el XML con la palabra que mostramos (con los '_') y si hay éxito o no
$xml = '<?xml version="1.0" standalone="yes"?>';
$xml .= '<datos>';
$xml .= '<total>'.count($datos).'</total>';
$xml .= '<inicio>'.$pos.'</inicio>';
$xml .= '<final>'.min($pos+$inc-1, count($datos)).'</final>';
for ($i = 0; $i<count($datos); $i++) {
$xml .= '<entrada>';
$xml .= '<titulo>'.$datos[$i][0].'</titulo>';
$xml .= '<url>'.$datos[$i][1].'</url>';
$xml .= '</entrada>';
}
$xml .= '</datos>';
header('Content-type: text/xml');
echo $xml;
La parte HTML/Javascript quizás sea un poco más compleja, pero supongo que no habrá problemas para entenderla. Dispondremos de dos capas, una que contiene el fondo y el recuadro para la paginación y otra que contendrá las distintas páginas.
<div class="contenedor">
<p id="paginacion">
<a href="javascript: anterior()"><<</a>
<span id="inicio">_</span> al <span id="final">_</span> (<span id="total">_</span>)
<a href="javascript: siguiente()">>></a></p>
</div>
<div id="contenido">
<div id="marco"></div>
</div>
Con sus estilos:
div.contenedor {
margin: 0 0 0 50%;
left: -100px;
position: absolute;
}
div#contenido {
margin: 0 0 0 50%;
left: -100px;
width: 200px;
height: 120px;
border: 2px solid #008585;
xoverflow: auto;
position: relative;
background: url(gr.gif) repeat-x;
}
div#marco {
width: 200px;
height: 120px;
position: absolute;
clip: rect(auto 200px auto auto);
}
div#contenido p {
width: 200px;
margin: 0px;
padding: 2px 4px 2px 4px;
}
a {
color: #008585;
font-family: Arial;
font-weight: bold;
text-decoration: none;
font-size: 9pt;
}
p#paginacion {
text-align: center;
font-weight: bold;
top: 102px;
position: relative;
border: 2px solid #008585;
background-color: #FFFFFF;
width: 110px;
left: 46px;
font-family: Arial;
font-size: 9pt;
z-index: 100;
}
div#contenido p a {
font-weight: bold;
display: block;
position: relative;
}
div#contenido p a:hover {
background-color: #008585;
color: #FFFFFF;
}
El elemento que se encarga la paginación consta de varios span que son los que modificaremos para escribir de cual a cual enseñamos y cuantos hay en total. El elemento marco es el que usaremos para añadir cada una de las páginas y es el que tiene el clipping. Cuando se carga una página se colocará a la derecha del recuadro (fuera del clipping), menos la página para la posición 1 (la primera), que se colocará dentro del recuadro.
function paginacion(pos) {
max = Math.max(pos, max);
ajax = ajaxobj();
ajax.open("GET", "paginacion.php?pos="+pos, true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
// Accion que ejecutamos cuando recibimos los datos
var datos = ajax.responseXML;
var entradas = datos.getElementsByTagName('entrada');
var contenido = document.getElementById("marco");
// Creamos una capa con posición
// absoluta para poder moverla
// La capa representa la página
var capa = document.createElement("DIV");
capa.id = "capa"+pos;
capa.style.position = "absolute";
// Si no es la primera página la colocamos a la derecha
if (pos != 1) {
capa.style.left = ancho+"px";
}
// Para cada entrada nos creamos mediante DOM
// un objeto P y dentro un objeto A con el enlace
// a la página
for (var i=0; i<entradas.length; i++) {
var p = document.createElement("P");
var link = document.createElement("A");
link.setAttribute("href", entradas[i].childNodes[0].firstChild.data);
var txt = entradas[i].childNodes[1].firstChild.data;
// Acortamos el texto para que no se sobrepase
var linkTxt = document.createTextNode(txt.substring(0, 25)+(txt.length <= 25? "":"..."));
link.appendChild(linkTxt);
p.appendChild(link);
capa.appendChild(p);
}
contenido.appendChild(capa);
var ini = datos.getElementsByTagName('inicio').item(0).firstChild.data;
var act = datos.getElementsByTagName('final').item(0).firstChild.data;
var tot = datos.getElementsByTagName('total').item(0).firstChild.data;
paginas[ini] = new Array(act, tot);
// Si es el primero modificamos los datos de paginacion
// si no, ya se cambiarán cuando avancemos/retrocedamos
if (pos == 1) {
document.getElementById("inicio").innerHTML = ini;
document.getElementById("final").innerHTML = act;
document.getElementById("total").innerHTML = tot;
inicio = false;
}
}
}
ajax.send(null);
}
Las funciones para avanzar o retroceder en la paginación existen las siguientes funciones:
// Avanza en la paginacion
function siguiente() {
if (paginas[posActual + inc]) {
// Muevo a la izquierda la actual
desplazar("capa"+posActual, false, 1);
posActual += inc;
visitados[posActual] = true;
// Muevo a la izquierda la nueva
desplazar("capa"+posActual, false, ancho);
document.getElementById("inicio").innerHTML = posActual;
document.getElementById("final").innerHTML = paginas[posActual][0];
document.getElementById("total").innerHTML = paginas[posActual][1];
// Cargo una nueva pagina
if (posActual < paginas[posActual][1]) {
paginacion(parseInt(max)+inc);
}
}
}
// Retroce en la paginacion
function anterior() {
if (paginas[posActual - inc]) {
// Muevo a la derecha la actual
desplazar("capa"+posActual, true, 1);
posActual -= inc;
// Muevo a la derecha la nueva
desplazar("capa"+posActual, true, -ancho);
document.getElementById("inicio").innerHTML = posActual;
document.getElementById("final").innerHTML = paginas[posActual][0];
document.getElementById("total").innerHTML = paginas[posActual][1];
}
}
Y las funciones para desplezar las capas y el efecto de fundido son las siguientes:
function desplazar(id, derecha, pos) {
var obj = document.getElementById(id);
var desp = (derecha? -1: 1)*velocidad;
obj.style.left = (pos-desp)+"px";
if (Math.abs(pos-desp) < ancho && pos-desp != 0) {
setTimeout("desplazar('"+id+"', "+derecha+", "+(pos-desp)+")", 30);
}
transparencia(obj, 100 - (Math.abs(pos-desp)*100/ancho));
}
function transparencia(obj, porc) {
if (typeof obj.style.filter != 'undefined') { // Es IE
obj.style.filter = "alpha(opacity="+porc+")";
} else {
obj.style.opacity = porc/100;
}
}
Podéis bajaros el código aquÃ
Weebly nos ofrece la posibilidad de crear páginas web de forma rápida, sencilla y online. Mediante el uso de Ajax y gracias al drag&drop, podemos crearnos nuestro sitio web en pocos minutos.
El otro dÃa nos preguntaban una forma de migrar una base de datos Access a otra MySQL. En ese momento no conocÃa ninguna aplicación que pudiera hacerlo, pero hoy me he enterado que los propios de MySQL tienen MySQL Migration Toolkit, que permite mediante una serie de pasos realizar una migración de forma correcta.