martes, 16 de junio de 2009

Mostrar entradas de hace un año en Blogger.

Mostrar las entradas del mismo día del año pasado en la barra lateral del blog parecía una tarea sencilla, y como toda tarea sencilla se volvió un verdadero desafío. Finalmente he llegado a una solución que, aunque con sus contras, funciona. Por eso les recomendaría leer el post hasta el final antes de decidirse a implementarla.

La solución (más bien el hack) utiliza la Javascript Client Library de Google para obtener los títulos y links de las entradas de hace un año mediante mediante la API de datos de Blogger.

Primero vamos a lo que importa:

  1. Ingresamos al escritorio de Blogger y luego seleccionamos “Diseño” y “Edición de Html”. 
  2. Antes que nada es recomendable hacer un backup del template de nuestro blog, haciendo click en el link “Descargar plantilla completa”.
  3. Esa cosa rara e ilegible que vemos ahí es el código de nuestro template de Blogger. Buscar la etiqueta <head> (está en las primeras líneas) e insertar el siguiente código a continuación:
    <script src='http://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A1.x%2Cpackages%3A%5Bblogger%5D%7D%5D%7D' type='text/javascript'/>
  4. Guardar los cambios.
  5. Luego ir a “Elementos de página”. Noten que la dirección de la página (en la barra de direcciones del navegador) dice “BlogID=xxxx”. Anoten ese número.
  6. Agregar un gadget (donde más nos guste) del tipo “HTML/Javascript”.
  7. Escribir un título (ej.:”Hace un año en…”) y como contenido copiar lo siguiente (por temas de formateo lo tengo en tres partes, pegar una detrás de la otra):
        <div id="haceUnAnio" style="display:none" ></div>
            
        <script type='text/javascript'>        
        <!--
        
    var _blogID = 'xxxx';
       
    function date2RFC3339(dateObject)
    {          	
        var _ = function(text,size){
            var out = text.toString();
            while(out.length < size)
                out = '0' + out;                    	            
            return out;     
        }
        
        var formattedDate = [];
        var date = [_(dateObject.getFullYear(),4), _(dateObject.getMonth()+1,2), _(dateObject.getDate(),2)].join('-');
        formattedDate.push(date);
        
        var time = [_(dateObject.getHours(),2), _(dateObject.getMinutes(),2), _(dateObject.getSeconds(),2)].join(':');
        var timezoneOffset = dateObject.getTimezoneOffset();
        time = time + (timezoneOffset > 0 ? '-' : '+') + 
                                _(Math.floor(Math.abs(timezoneOffset)/60),2) + ':' +
                                _(Math.abs(timezoneOffset)%60,2);
        formattedDate.push(time);	        
        return formattedDate.join('T');
    };        
                                 
    function handleErrorPostsDeHaceUnAnio(){};        
    
    function handleGetPostsDeHaceUnAnio(feedRoot)
    {            
        var feedItems = feedRoot.feed.getEntries();
    
        if(feedItems.length==0)
            return;
            
        var boxHTML = '<ul>';
        
        for(var i=0;i<feedItems.length;i++)
        {
            var feedItem = feedItems[i];
            boxHTML = boxHTML + '<li><a href="'+feedItem.getHtmlLink().getHref()+'">' + feedItem.getTitle().getText() + '</a></li>';
        }
        
        boxHTML = boxHTML + '</ul>';
        
        var placeHolder = document.getElementById("haceUnAnio");
        placeHolder.innerHTML = boxHTML;
        placeHolder.style.display='';
    }
                    
    function getPostsDeHaceUnAnio()
    {
        var minDate = new Date();
        minDate.setFullYear(minDate.getFullYear()-1);        
        minDate.setHours(0,0,0);
        
        var maxDate = new Date();
        maxDate.setFullYear(maxDate.getFullYear()-1);
        maxDate.setHours(23,59,59);
           
        var feedUrl = 'http://www.blogger.com/feeds/'+_blogID+'/posts/default?published-min='+date2RFC3339(minDate)+'&published-max='+date2RFC3339(maxDate);
        var bloggerService = new google.gdata.blogger.BloggerService('ACP-OneYearAgo-v100');                    
        bloggerService.getBlogPostFeed(feedUrl, handleGetPostsDeHaceUnAnio, handleErrorPostsDeHaceUnAnio);     
    }
    
    google.setOnLoadCallback(getPostsDeHaceUnAnio);
    	-->
        </script>
  8. Verán que al principio de todo eso decía “var _blogID = 'xxxxxx';”. Bueno, hay que cambiar las “xxx” por el ID de su blog, que es el número que anotaron en el punto 5 (¿no lo hicieron?, pues retroceden tres casilleros).
  9. Bueno, eso es lo básico.

¿Qué hace el código? Busca los posts y crea una lista (utilizando los elementos UL y LI) de los links correspondientes en el elemento div que está al inicio del código. Pueden agregarse algo de estilo con CSS a gusto de cada quien.

Algunas aclaraciones. Definitivamente no es el método más eficiente para hacerlo, tiene por lo menos tres contras:

La primera es que necesita la librería cliente de Javascript de Google (ese código que pusieron luego del <head>) y eso es… pesado en relación al uso que se le da. Pero bueno, la librería está bastante optimizada, y si no notan que la carga se hace pesada es soportable.

La segunda es que por más que el código muestre sólo el título y el link a los posts correspondientes, por detrás está pidiendo al servidor los posts completos. Esto es, hasta donde yo sé, inevitable (se escuchan sugerencias). Si la cuestión es que en aquel inspiradísimo fin de semana de 2008 escribimos 5 posts larguísimos… bueno, eso se va a notar.

Y la tercera es que está escasamente probado. Por lo menos en mi caso funciona bien con Chrome, Firefox y IE 8. Tomen sus recaudos y prueben por su cuenta. Cualquier problema comenten y vemos de ir actualizando.

Actualización: arreglado un pequeño error en la línea 34 (al generar el html para mostrar los posts no iniciaba la lista con el tag <ul>, quedando huérfano el </ul> que está más abajo, en la 42.

2 comentarios:

Anónimo dijo...

uhmmmmm...


Firefox 3.0.11 en Vista.

Veo el título "Hace un año..." pero nada debajo, directamente el separador y la nube de tags estática.

AcP dijo...

Problema: No se ven los títulos del mismo día del año pasado.

Estado: Este comportamiento es por diseño (me gusta más en inglés: this behavior is by design).

Causa: Blogger perezoso, no escribe todos los días. Hace exactamente un año no posteó nada.

Pasos para reproducir el comportamiento: sólo espere, algunos días va a pasar.

Ahora en serio, tengo en agenda modificar la función para que si un día no encuentra nada busque para atrás hasta encontrar algo para que no quede vacío.