Behind the scenes: El rediseño de The Next Web

Hace unos días hemos lanzado un nuevo diseño en The Next Web. A pesar de que la última versión del sitio tenía apenas un año, su funcionalidad había quedado rápidamente anticuada debido a los rápidos avances en el desarrollo de los navegadores, el aumento de las visitas desde el móvil, la aparición de nuevos dispositivos (tablets, etc).

Por este motivo, en esta iteración de la web teníamos los siguientes objetivos:

  • Conseguir que la navegación entre artículos fuera lo más rápida e intuitiva posible.
  • Incluir soporte para dispositivos móviles y pantallas de alta resolución (aka Retina).

Gracias a que en la actualidad la mayoría de funcionalidades que nos ofrece HTML5 y CSS3 están siendo soportadas universalmente (incluso por nuestro querido Internet Explorer), hemos podido aplicar todos los métodos que hace poco parecían imposibles de llevar a la práctica.

Podéis leer más sobre los motivos del rediseño y las nuevas funcionalidades en este post, pero aquí me gustaría detenerme en los aspectos técnicos del nuevo sitio. Como resumen, diré que el nuevo sitio está construido sobre Backbone.js + Underscore.js, y hace uso de las APIs de HTML5 History/State (pushState, replaceState, onPopState), entre otras cosas que iré desgranando poco a poco.

Voy a estructurar este post en una serie de artículos dónde explicaré como hemos utilizado todas estas tecnologías para conseguir los objetivos marcados al principio.


El feed de noticias

El feed de noticias es el elemento más importante para navegar por el sitio. Viene del backend como un objeto JSON y es incluido en la página dinámicamente via Javascript, por motivos que después explicaré. Es cacheado en el servidor y en el cliente por 60 segundos, para asegurarnos que siempre muestra contenido fresco.

Para implementar este feed en el cliente vamos a ayudarnos de Backbone.js, una excelente framework de Javascript con arquitectura MVC que hace posible modelar de forma colecciones de datos en JSON de las que disponemos (en este caso artículos), para trabajar de forma sencilla con ellas.

En primer lugar vamos a crear la siguiente estructura de objetos que servirán para representar un artículo (el modelo), la representación visual de ese artículo en la interfaz (la vista) y una colección de modelos tipo artículo, llamado collection en la terminología de Backbone.

Model

// Objeto Post. Hereda de Model
var Post = Backbone.Model.extend({
	idAttribute: "post_id",
});

La primera versión del modelo no tiene mucho que explicar. Simplemente vamos a definir explícitamente que atributo del objeto queremos usar como identificador, lo que nos será útil después para buscar y manipular objectos dentro de la colección.

Collection

// Colección de Posts. Hereda de Collection.
var StreamList = Backbone.Collection.extend({
	model: Post,
	url: THEME_URL + 'ajax/stream.php'
});

Para definir la colección tenemos que definir 2 atributos como mínimo: Cuál es el el tipo de dato de los modelos que formarán la colección (Post, en nuestro caso), y cual es la URL que devolverá un array de objetos JSON que formarán esta colección.

View

// Representación de Post en la UI
var PostView = Backbone.View.extend({
	tagName: "li",
	className: "stream-item",

	initialize: function() {
		this.template = _.template($("#stream-item-template").html());
	},
	render: function() {
		$(this.el).html(this.template({post: this.model.toJSON()}));
		return this;
	},
});

En la vista vamos a definir la apariencia de nuestros modelos en la interfaz. En nuestro ejemplo, simplemente serán elementos de una listacon la clase stream-item.

En el método initialize vamos a utilizar el método template para definir la estructura HTML de cada post en la lista. Este código puedes incluirlo directamente en tu página html (Asegurate de asignar al tag script el mismo ID que has declarado previamente en initialize)

<script type="text/template" id="stream-item-template">
	<div class="thumb"><a data-post-id="<%= post.post_id %>" href="<%= post.permalink %>" title="<%= post.title%>"><%= post.thumbnail %></a></div>
	<div class="body">
		<div class="date" data-timestamp="<%= post.timestamp %>"><%= post.date %></div>
		<a class="title" href="<%= post.permalink %>" title="<%= post.title%>"><%= post.short_title %></a>
	</div>
</script>

Por último, es preciso indicar que cada post viene representado de la siguiente manera desde el JSON que cargamos desde el backend. Fijaos que cada atributo que definamos en el template tiene que existir en el JSON.

{
	"post_id":497909,
	"thumbnail":"<img width="79" height="66" src="http://cdn.thenextweb.com/wp-content/blogs.dir/1/files/2012/11/Pure-79x66.jpg" class="attachment-posts_loop wp-post-image" alt="Pure" title="Pure" />",
	"permalink":"http://thenextweb.com/apps/2012/11/05/pure-stream-launched-for-ios-and-android-devices-allowing-music-to-be-played-wirelessly-on-pure-devices/",
	"title":"Pure Stream lets iOS and Android phone owners stream music wirelessly on select Pure devices",
	"short_title":"Pure Stream Allows iOS and Android Users to Play Music Wirelessly ...",
	"date":"5 November 2012",
	"timestamp":1352125279
}

Como véis, es muy sencillo construir el esqueleto de una aplicación basada en Backbone.js. Según vayamos avanzando en el tutorial iremos incluyendo métodos para interactuar con estos objetos. En el siguiente artículo explicaré cómo crear una aplicación en Javascript que haga uso de estos objetos Backbone para construir un feed de noticias interactivo como el que podeis usar en el blog de The Next Web.

Lee ahora: Cómo implementar una navegación usando atajos de teclado »

  • http://twitter.com/ciudadanoB Juan Hernando

    Enhorabuena por el rediseño y por irlo desgranando poco a poco por aquí :)

  • Lucas García

    un trabajo excelente, si antes ya me gustaba, ahora más, enhorabuena.

  • Alex Lozano

    genial!! el pueblo quiere mas!!