martes, 4 de diciembre de 2012

Blogger: Resúmenes tipo mosaico

Cuando se quieren mostrar las entradas resumidas en un formato tipo mosaico y que las imágenes que generalmente se utilizan como adorno, mantengan su proporción, estamos hablando de una estructura distinta a la clásica que muestra una serie de rectángulos donde la altura es siempre fija:


Es el caso del famoso Pinterest o sitios similares que van colocando rectángulos de altura variable, acomodándolos una debajo del otro, llenando los espacios vacíos.


Para que sea simple de hacer, ese tipo de estructura requiere CSS3 y utilizar las distintas variantes de la propiedad column lo que implica que sólo será visible en navegadores de última generación. Para colmo, a mi entender, ese sistema no es muy razonable en un blog ya que las columnas se escriben de arriba hacia abajo con lo que, si colocáramos 15 entradas en tres columnas, la columna izquierda tendría las primera 5, la del centro las segundas 5 y la tercera el resto; algo que puede ser molesto ya que un lee e interpreta de izquierda a derecha.

Otra forma de hacer lo mismo es usar scripts o plugins específicos aunque algunos de ellos no solucionan esos problemas ya que la única manera de hacer algo así y que se vea en cualquier navegador es mediante alguna clase de script que calcule alturas y vaya "dibujando cada rectangulito estableciendo propiedades absolutas.

Ahora bien, si uno no quiere complicarse la vida, en Blogger, habría una solución simple que no requiere nada sofisticado y que debería funcionar en cualquier navegador ya que no se necesitan propiedades especiales y el script es similar a cualquier otro que lea los feeds del sitio utilizando json.

La idea es crear tres DIVs que serán las columnas, uno flota a la izquierda, otro a la derecha y el tercero está centrado. Luego, vamos agregando las entradas a cada una de ellos en el orden en que las leemos de tal manera que si mostramos 15 entradas, los post 1,4,7,10 y 13 estarán en DIV izquierdo, los posts 2,5,8,11,14 en el centro y los posts 3,6,9,12,15 en el DIV derecho.

Voy hacer lo con un ejemplo concreto que puede verse online en el home de este sitio; allí busqué el includable principal del blog:
<b:includable id='main' var='top'>
.......
</b:includable>
Y como es algo que sólo quiero mostrar en el home sin hacer una plantilla nueva, me limitaré a condicionar su contenido y agregar las nuevas columnas de este modo:

<b:includable id='main' var='top'>
<b:if cond='data:blog.url == data:blog.homepageUrl'>
<div id='left-col'/>
<div id='right-col'/>
<div style='clear:both;'/>
<script src='/feeds/posts/default?start-index=1&amp;max-results=12&amp;orderby=published&amp;alt=json-in-script&amp;callback=mosaicocols' type='text/javascript'/>
<b:else/>
<!-- AQUÍ DEJO TODO LO QUE TENGA, SEA LO QUE SEA -->
</b:if>
</b:includable>
Y ahora, el script que es el que interpreta los feeds; lo coloco antes de </head> y usa jQuery para simplificar las cosas pero, podría hacerse con cualquier otra librería o con ninguna:
<b:if cond='data:blog.url == data:blog.homepageUrl'>
<script type='text/javascript'>
//<![CDATA[
function mosaicocols(json) {
var entry, posttitle,posturl,postimg;
var salida = "";
var contar = 0;
for (var i = 0; i < 24; i++) { // voy a mostrar 24 entradas
if (i == json.feed.entry.length) { break; }
entry = json.feed.entry[i]; // el feed
posttitle = entry.title.$t;; // el título de cada post
for (var k = 0; k < entry.link.length; k++) {
if (entry.link[k].rel == 'alternate') {
posturl = entry.link[k].href; // la dirección url de cada post
break;
}
}
// buscamos una imagen para decorar
var t = "";
if ("media$thumbnail" in entry) {
postimg = entry.media$thumbnail.url; // es la que Blogger detecta
postimg = postimg .replace('s72-c','s275'); // pero la cambio para que sea más grande y no una miniatura
} else {
// si no se detecta una, buscamos en el mismo post
var s, a, b, c, d;
s = entry.content.$t;
a = s.indexOf("<img");b = s.indexOf("src=\"",a);c = s.indexOf("\"",b+5);d = s.substr(b+5,c-b-5);
if((a!=-1)&&(b!=-1)&&(c!=-1)&&(d!="")) {
postimg = d; // es la primera imagen del post
} else {
// y si no hay ninguna, usamos una imagen genérica
postimg = 'url_imagenxdefecto';
}
}
// ahora, armo la salida de cada rectángulo utiilizando cualquier estructurura HTML que se me ocurra
salida = "<div class='m-post' id='"+i+"'>";
salida += "<a class='miniatura' href='" + posturl + "' target='_blank'><img src='" + postimg + "' /></a>";
salida += "<h2><a href='" + posturl + "' target='_blank'>" + posttitle + "</a></h2>";
salida += "</div>";
contar = contar+1; // para simplificar las cosas, voy contando los posts
if (contar==1) { // posts 0 3 6 9 12 15 etc
$('#left-col').append(salida); // los agrego a la columna izquierda
} else if (contar == 2) { // posts 1 4 7 10 13 16 etc
$('#right-col').append(salida); // los agrego a la columna derecha
} else { // posts 2 5 8 11 14 17 etc
$('#center-col').append(salida); // los agrego a la columna central
contar = 0; cada tres, pongo el contador a cero
}
}
}
//]]>
</script>
</b:if>
Estas son las tres líneas que deberían cambiarse si se usa otra librería o si no se usa ninguna:
$('#left-col').append(salida);
$('#right-col').append(salida);
$('#center-col').append(salida);
Por último, el CSS que también va antes de </head>:
<b:if cond='data:blog.url == data:blog.homepageUrl'>
<style>
// si es necesario, agrego cualquier cosa que se necesaria para cambiar anchos u ocultar elementos
#outer-wrapper, #content-wrapper, #header-wrapper, #main-wrapper {width:930px;}
#sidebar-wrapper {display:none;}
// estas serían las reglas de las tres columnas
#left-col {float:left;}
#right-col {float:right;}
#center-col {margin:0 auto;width: 297px;}
// cada uno de los rectángulos
.m-post {
border: 1px solid #EEE;
margin-bottom: 20px;
padding: 10px;
text-align: center;
width: 275px;
background-color: #FFF;
box-shadow: 0 5px 5px #AAA;
position: relative;
}
.m-post a {text-decoration:none;}
// la imagen de los posts
.m-post .miniatura {
display: inline-block;
}
.m-post .miniatura img {
vertical-align: top;
width: 275px;
}
// el título de los posts
.m-post h2 a {
color:#666;
font-size: 17px;
font-family: Tahoma;
font-weight: normal;
letter-spacing: 0;
padding: 0;
text-transform: none;
}
</style>
</b:if>
Y eso es todo. Obviamente, de ahí en adelante, cualquier cosa es posible y cada uno deberá investigar y jugar un poco.

No hay comentarios:

Publicar un comentario