JMiur [E]

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; 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.

16 comentarios:

Unknown  

Lo voy a probar Jmiur, veremos qué me sale. Que tengas un buen día :)

JMiur  

Pruebe y veremos :-)

Responder
Lisandro  

Muy bueno... intenté hacer algo parecido alguna vez, y por supuesto, no me salió. =)

Responder
Felipe  

Me parece una solución fantástica para un diseño que se está haciendo muy popular en la web. Puede ser muy útil para determinados blogs: gastronómicos, de moda, fotologs, etc.
Felicidades y gracias por hacernos la vida más fácil a los blogueros principiantes :)

JMiur  

Gracias, Felipe :)

Responder
Emilio M. Luna  

He estado experimentando JMiur, la idea es estupenda. Desgraciadamente no me ha funcionado. He seguido los pasos he dejado todo lo que habia en : pero en la vista previa no salían las entradas. Todo en blanco.

Un saludo.

JMiur  

Sin ver tu ejemplo, imposible decirte nada y tampoco me fiaría de la Vista Previa ya que muchas cosas, en ese modo, no funcionan.

Responder
Llusan  

¿Puedo conseguir (aparte de posttitle,posturl,postimg) otros elementos como post-author, fecha, etiquetas?

JMiur  

Cualquier dato que esté en el feed; por ejemplo:

entry.category[] y entry.category[x].term es el array de las etiquetas que tiene la entrada
entry.published.$t es la fecha de publicación
entry.updated.$t es la fecha de la ultima actualización
entry.author[] y entry.author[x].name.$t es el array con los nombres de los autores

Responder
LucasFM  

Hola que tal? quiero poner esto en mi blog pero no se donde va esa parte de codigo donde comentas "AQUÍ DEJO TODO LO QUE TENGA, SEA LO QUE SEA" lo demas ya esta, solo me falta ubicar eso. Gracias

JMiur  

Significa que dejas el contenido del main tal como está en la plantilla porque es lo que se usará para ver als entradas individuales.

Responder
@steban  

Hola, siempre te leo y pocas veces implemente lo que proporcionas, mi pregunta es la siguiente y es algo que me vengo preguntando siempre, se puede hacer que las publicaciones se carguen solo en el main-wrapper sin que se recargue toda la página? de tal modo que solo funcione el main-wrapper manteniendo fijo el resto del sitio... al igual que al hacer click sobre las etiquetas estas no me recarguen el sitio sino que se carguen automaticamente en el main-wrapper. Me gustaria saber como hacerlo, vengo hace meses buscando la forma de hacerlo y no lo encuentro.. Quizás seria un buen tema para publicar! :D

Saludos y muy bueno el sitio!

JMiur  

Es probable que pudiera hacerse a partir del modelo del ejemplo, agregando alguna variable extra y guardando ese dato.

En el script:
postcontent = entry.content.$t;
contendría el HTML de cada post

¿Que hacer con eso? ponerlo en un DIV oculto, guardarlo en un array, habría que pensar la metodología y por último, cambiar el enlace para permutar entre la página principal y ese dato.

Sea como fuere, los posts deberan ser cargados via feeds lo que puede ser algo no recomendable si tenemos en cuenta los motors de busqueda.

Responder
Victor  

Y si quisieramos hacer responsiva la pagina como tendriamos que adaptar el spript?

JMiur  

Más que el script, deberías re-definir las reglas del CSS.

Responder

¿Quiere dejar un comentario?

recuerde que los comentarios están siendo moderados y serán publicados a la brevedad ...

Nota: sólo los miembros de este blog pueden publicar comentarios.

Si le gusta ir a lo seguro utilice este botón para abrir los comentarios en una ventana modal en esta misma pagina.

Si añora tiempos idos, use este enlace para agregar un comentario al viejo estilo ...

 
CERRAR