Listado de los últimos apuntes de El diario de Pepe Molina (Caricatos) [página 1].
François Hollande: Actual presidente francés, sucesor de Sarkozy.
La arena del desierto es para el viajero fatigado lo mismo que la conversación incesante para el amante del silencio
Anónimo, proverbio persa.
En esta zona están las páginas personales del autor.
Mis clientes ahora también son mis amigos (aunque les cobre).
En Mis amigos Informáticos hay una pequeña colección de páginas de colegas webmasters..
En Mis amigos artistas podemos encontrar artistas de cualquier índole (dibujantes, pintores, escritores...)
Las recomendaciones que proponemos son de índole variada.
Aquí un cajón de sastre de enlaces.
Nos referencian desde sitios de toda índole.
Puede contribuir a mantener esta página con su donativo.
Bienvenidos a "El diario de Pepe Molina (Caricatos)". Nos encuentramos en la página 1 del listado de apuntes del sitio. También se puede ver el listado de los apuntes más leídos.
Hace algunos días me preguntaron en los foros del web si tenía un ejemplo simple de lectura de datos estructurados XML con Ajax...
... después de revisar mis códigos, he encontrado muchas rutinas con esa tecnología, pero de una complejidad que no creí correcto referenciar, así que se me ocurrió hacer algo nuevo que pueda usar en esta página. La conclusión ha sido crear un sistema que despliegue la lista de apuntes del sector "Archivos", a la derecha de este diario.
Viendo el código fuente de la página, descubrimos que se trata de una lista desordenada "ul" (unordered list) y en cada item "li" (list item) el enlace del tipo "?archivos=mayo+2012", y al pinchar nos lleva a la lista correspondiente, pero podríamos simplemente mostrar otra lista de los títulos asociados desplegandola debajo.
Para que sea XML hemos pensado que podría tener una estructura como los ficheros RSS y de esa manera conseguir que sea visible fácilmente usando la hoja XSL que ya teníamos hecha para nuestro sistema de sindicación.
Vamos a dejar de lado tantas siglas y enlazamos al fichero resultante de este mes. Aunque todos nuestros códigos están accesibles en nuestros listados, a continuación mostramos el que hemos usado para nuestro propósito:
$aaaa = $_GET["a"];
$mm = $_GET["m"];
header("Content-type: text/xml");
ob_start();
echo <<< cabecera
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="diario.rss.xsl" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="http://www.pepemolina.com/diario.rss.xml" rel="self" type="application/rss+xml" />
<title>$diario_titulo: extras</title>
<link>{$_SERVER[PHP_SELF]}?extra=extras_xml</link>
<description>$diario_titulo</description>
cabecera;
$cabeza = ob_get_clean();
$sql = "select titulo, apunte from $tabla_apuntes where activo > 0 and fecha like '$aaaa-$mm%' order by fecha desc";
$listado = array();
$res = @mysql_query($sql);
$cuenta = mysql_num_rows($res);
while ($dato = mysql_fetch_array($res)) {
$titulo = $dato["titulo"];
$link = $diario."?titulo=".urlencode($titulo);
preg_match('/\[rss\](.*?)\[\/rss\]/is', $dato["apunte"], $des);
array_push($listado, "\n<item>\n<title>\n$titulo\n</title>\n<link>\n$link\n</link>\n<description>\n{$des[1]}\n</description>\n</item>\n");
}
$lista = implode("\n", $listado);
echo $cabeza.$lista."\n</channel>\n</rss>";
Para que sea más fácil nuestro propósito con el lenguaje javascript hemos modificado los enlaces añadiendo un atributo "id" del tipo "archivos_aaaa_mm", como por ejemplo: id="archivos_2012_05" para el enlace del mes de mayo de este año 2012.
Para que sea inapreciable el arreglo hemos añadido el código después de cargarse la página. No obstante los enlaces seguirán siendo funcionales, así que mientras no se hayan cargado todos los elementos de la página serán los siempre, y cuando se cargue el código, los enlaces desplegarán una lista con las referencias asociadas.
var lista_archivos = new Object();
function enlace_archivo_ajax(e) {
archivos = this;
archivos_id = archivos.id;
desglose_id = archivos.id.split("_");
mes = desglose_id.pop();
año = desglose_id.pop();
id_archivos = "desglose_" + mes + "_" + año;
if (lista_archivos[id_archivos] == undefined) {
lista_archivos[id_archivos] = [];
lista_archivos[id_archivos]["visible"] = true;
nueva_espera = document.createElement("img");
nueva_espera.src = "diario/dibujos/espera.gif";
tag(archivos_id).parentNode.appendChild(nueva_espera);
url = "diario.jocker.php?extra=archivos&a=" + año + "&m=" + mes;
Ajax = objetoAjax();
Ajax.open("get", url, true);
Ajax.onreadystatechange = function() {
if (Ajax.readyState == 4 && Ajax.status == 200) {
nueva_capa = document.createElement("ul");
nueva_capa.id = id_archivos;
nueva_capa.className = "enlaces";
tag(archivos_id).parentNode.appendChild(nueva_capa);
respuesta = Ajax.responseXML.documentElement;
items = respuesta.getElementsByTagName("item");
for (i = 0, total = items.length; i < total; i++) {
el_enlace = items[i].getElementsByTagName("link")[0].firstChild.nodeValue;
el_titulo = items[i].getElementsByTagName("title")[0].firstChild.nodeValue;
la_desc = (items[i].getElementsByTagName("description")[0].hasChildNodes()) ?
items[i].getElementsByTagName("description")[0].firstChild.nodeValue: "sin descripción";
nuevo_li = document.createElement("li");
nuevo_enlace = document.createElement("a");
nuevo_enlace.href = el_enlace;
nuevo_enlace.setAttribute("title", la_desc);
nuevo_enlace.appendChild(document.createTextNode(el_titulo));
nuevo_li.appendChild(nuevo_enlace);
nueva_capa.appendChild(nuevo_li);
};
tag(archivos_id).parentNode.removeChild(nueva_espera);
}
}
Ajax.send();
}
else {
tag(id_archivos).style.display = (lista_archivos[id_archivos]["visible"]) ? "none":"block";
lista_archivos[id_archivos]["visible"] = !lista_archivos[id_archivos]["visible"];
}
cancelar_evento(e);
}
Aunque pueda parecer mucho código, la parte "Ajax" es bastante sencilla: se lee el fichero XML/RSS correspondiente al enlace pinchado y se genera la lista desordenada con sus enlaces asociados. Los mismos quedan resumimos en la siguiente lista:
Por cada item de la lista se obtienen los datos: "title", "link" y "description" que usaremos al desplegar la lista (title es el texto que se muestra, link el enlace y description el atributo title).
Otra parte fundamental del código y tal vez la razón de su extensión, es la que evita realizar más de una vez una misma consulta. Cuando se despliega una lista, se puede plegar pinchando sobre el mismo enlace, pero si volvemos a querer desplegarla simplemente se muestra lo que anteriormente se había ocultado; considerando que es casi imposible que se realizaran cambios en los enlaces de cada lista, no tienen ningún sentido volver a leer los datos ya leídos en la misma sesión (un vicio bastante común).
En dos de los tres congresos que hasta el día de hoy he participado, tuve el agrado de coincidir con Jill Hesketh.
Esta caricaturista holandesa también es muy recomendable, y pueden encontrar más trabajos suyos en su propia página web.
La caricatura que presentamos la realizó durante el minicon Benalmádena 2005. Debo reconocer que no sé exactamente la técnica usada, pero mirando recortes de la imagen (pinchando sobre la misma se accede a su ficha) podemos pensar que se trata de aguadas. De todos modos, siempre se puede usar el formulario de contacto de su sitio web.
La foto de la artista es un recorte de la foto de familia del minicon antes citado.
Ya hemos visto como obtener detalles de una imagen, pero teníamos que hacerlo "artesanalmente". Ahora presentamos una herramienta que nos facilitará las cosas.
En el apunte citado mostrábamos "la semilla" de este apunte, pero la imagen era la que hemos adjuntado (en versión original) sin posibilidad de cambiar, por lo que tan solo nos valía de "caso de estudio"; motivo por el que hemos añadido un control para seleccionar imágenes de Internet.
Esa imagen original la hemos hecho parte de nuestro sistema de imágenes, y si miramos su ficha (pinchando sobre ella), encontramos algunos recortes. También encontraremos recortes en otras fichas que hemos hecho con la misma herramienta.
La principal característica es que se pueden seleccionar imágenes (incluso en formatos menos usados en la web como ".bmp" o ".tif"). Las imágenes se mostrarán sobre una grilla (de forma similar a la de los editores gráficos), y el ratón se muestra con guías (horizontal y vertical). Otra característica nueva es que al seleccionar el primer punto se queda marcado como referencia para el siguiente punto (luego se borra). También se pueden marcar zonas dentro de zonas, o en las mismas coordenadas donde ya teníamos algún recuadro.
Conseguir que se vean las guías por donde pasa el ratón podría parecer muy complejo, pero sabiendo sus coordenadas basta con dos capas adicionales. Para la guía horizontal la capa debe ubicarse en la coordenada [0,0], tener una anchura del 100% y la altura equivalente a la posición del ratón. Solo tenemos que hacer visible el borde inferior para crear nuestra guía. Omitiré la forma de obtener la guía vertical porque es algo "obvio". Añadimos una tercera capa para programar las pulsaciones del ratón. En este caso usaremos un rectángulo invariable, pero lo movemos junto al ratón, para que quede centrada y siempre se pinche sobre esta nueva capa. Para dejar marcada la primera pulsación simplemente clonamos las capas que son guías, sin olvidarnos de borrarlas.
Hemos integrado algunas de las antiguas páginas de este dominio, y ahora también podemos comentarlas y evaluarlas.
Esta funcionalidad ya existía en nuestro editor, pero ahora hemos ampliado la funcionalidad al resto de las páginas que figuran en la sección titulada "Otras páginas del dominio".
Para lograr este objetivo, hemos tenido que seguir unos sencillos pasos que comentaremos a continuación. Recordemos que esta página tiene un diseño modular que nos ha servido para simplificar la tarea.
En primer lugar hemos tenido que conseguir un perfecto aislamiento de los elementos que necesitaremos que podríamos etiquetar como módulo de valoración y módulo de comentario. Pero también hay que considerar dos cosas añadidas: la gestión en sí con sus scripts y funciones asociadas y la presentación de datos; de paso hemos modificado el diseño general de los encabezados y pies de las páginas.
Con respecto a los scripts, podríamos tener problemas de inicialización pero al no existir funciones y variables con el mismo nombre (aún no hemos hecho un chequeo a fondo), simplemente tuvimos que procurar evitar las instrucciones del tipo "onload", fácilmente reemplazables por las del tipo addEventListener/attachEvent como puede verse en los códigos de las páginas mencionadas.
Hemos aislado un fichero con las funciones y la inicialización que básicamente dependerá del siguiente código javascript:
function tag(id) {return document.getElementById(id);}
function poner_evento(elemento, evento, f) {
if (document.addEventListener)
elemento.addEventListener(evento, f, true);
else
if (document.attachEvent)
elemento.attachEvent("on" + evento, f);
else
elemento["on" + evento] = f;
}
Luego, para crear las funciones de inicio, las agrupamos en una función "iniciar_todo()", y más adelante:
poner_evento(window, "load", iniciar_todo);
Con estos sencillos elementos, podemos evitar colisiones con códigos de inicialización existentes, e insertar los necesarios para el funcionamiento de los controles añadidos (validaciones, captcha, coloreo de estrellas...)
No recuerdo si hemos tenido que renombrar alguna variable o etiqueta (¡creo que no!), pero sí tuvimos que retocar los añadidos para mejorar la estética general de las viejas páginas, por ejemplo buscando que la anchura de éstos sea equivalente a los elementos existentes.
Me interesa el futuro porque es el sitio donde voy a pasar el resto de mi vida
Woody Allen, cineasta estadounidense (1935)
En ocasiones podemos tener la intención de mostrar detalles de algún rincón de una foto, tal vez ampliándolos (o reduciéndolos). En este apunte intentaremos explicar como lograrlo.
De la imagen que nos acompaña (al momento de publicar este apunte es la imagen del sector "Última caricatura") vamos a crear un recorte del centro de la misma para que pueda usarse como icono:
.
También usaremos la misma imagen para ampliar otra zona aplicando un zoom o escala y mostraremos un poco más abajo del apunte.
Antes de seguir, tenemos que puntualizar que estamos viendo una miniatura y que la imagen original es de 531x800 píxeles (la miniatura es de 79x120 y en el recuadro hay márgenes específicos que pueden confundir).
Anteriormente habíamos mostrado un resultado similar en esta otra página: Recortes de imágenes.
Tal como acostumbramos a hacer, mostramos el código original para hacer recortes en la página anteriormente citada.
<?php
header("Content-Type: image/png");
if (isset($_GET["altura"])) $altura = $_GET["altura"];
else $altura = 1;
if (isset($_GET["anchura"])) $anchura = $_GET["anchura"];
else $anchura = 1;
if (isset($_GET["origen"])) $origen = imageCreateFromPng($_GET["origen"]);
else $origen = ImageCreate($anchura, $altura);
if (isset($_GET["x"])) $x = $_GET["x"];
else $x = 0;
if (isset($_GET["y"])) $y = $_GET["y"];
else $y = 0;
$destino = ImageCreate($anchura, $altura);
imagecopy($destino, $origen, 0, 0, $x, $y, $anchura, $altura);
@imagepng($destino);
imagedestroy($origen);
imagedestroy($destino);
?>
A este código que habíamos creado hace algunos años, solo nos queda agregarle el parámetro "zoom" para obtener el siguiente resultado:
Puede verse el código actual en el comodín "detalle".
Valoración de esta página: (index)
Esta página ha sido visitada en 34357 ocasiones
Y del Mapa del sitio, además del sitemap.xml.
Aquí podemos encontrar los últimos 10 apuntes publicados.
O si lo prefiere, puede ver los apuntes más leídos.
Una buena forma de buscar un apunte es a partir de su categoría.
También es posible buscar apuntes por medio de las etiquetas (tags).
Hemos decidido poner al alcance de todos algunos comodines.
Adjuntamos una versión reducida del "buscador interno" que vemos en la lista anterior:
También estamos recopilando antiguas páginas del sitio.
Desde este recuadro se puede hacer una búsqueda cronológica.
Se puede crear una postal nueva desde el enlace del sector "Otras páginas del dominio", o editar la que sale en el recuadro, pulsando sobre ella..