Powered By Blogger

miércoles, 31 de octubre de 2012

Building a Scalable App With Backbone.js

Backbone.js is a small library (~5kb minified) that allows you to build single page web applications. Unlike many of its peers, Backbone is not very opinionated about the way you use it. Aside from some basic concepts, the design of your application is left widely up to you.

This tutorial will offer some insight on one of the popular patterns that the community has started to embrace: the Backbone Boilerplate. We will use this boilerplate to create a simple library of books, which you could easily extend into a much more robust application.


A Quick Overview of Libraries

It’s very flexible and incredibly lightweight.

Backbone.js is a JavaScript framework that allows us to easily create single page web applications. It’s very flexible and incredibly lightweight, which is why it has become one of the most popular JavaScript frameworks available.

Require.js is a module loader (leveraging the AMD design pattern) that allows you to asynchronously load your JavaScript modules and their dependencies.

Underscore.js a library that provides a set of utility functions you would come to expect when working with a programming language. Among other things, it gives you the ability to iterate over collections, to test if code is a function, and has a templating language built-in.


What is Backbone Boilerplate?

The Backbone Boilerplate is simply a set of best practices and utilities for building Backbone web applications. It is not an additional library, but it merges together a few libraries to encourage some structure when creating Backbone projects.

The Backbone Boilerplate is not an additional library.

There are a couple of ways to install the Backbone Boilerplate. The easiest (and preferred) method is the grunt-bbb plugin. However, that requires the use of Node.js and NPM, which is out of the scope of this tutorial. We will be doing a manual install instead.

To get started, head on over to the Github repository and download a copy of the code (you should see the .zip icon near the top). The copy you are downloading has been modified from the original with a lot the example code removed. There are a bunch of very useful comments in the example code (from the original boilerplate) – feel free to read over them in your spare time.

That’s it! We can get starting with creating our application.


Your First Module, the Book!

When you are working with the Backbone Boilerplate (or any project using AMD/Require.js), you will be grouping functionality into modules, and generally putting each module in its own file. This creates a “separation of concerns” and allows you (and anyone else who reads your code) to easily understand what the code should be doing.

To create your first module, simply put the following code into the file app/modules/book.js.

  define([    "namespace",    "use!backbone"  ],  function(namespace, Backbone) {    var Book = namespace.module();    // Router    Book.Router = Backbone.Router.extend({      routes: {        "book/:p"   : "details"      },      details: function(hash){        var view = new Book.Views.Details({model: Library.get(hash)});        view.render(function(el){          $("#main").html(el);        });      }    });    // Instantiate Router    var router = new Book.Router();    // Book Model    Book.Model = Backbone.Model.extend({});    // Book Collection    Book.Collection = Backbone.Collection.extend({      model: Book.Model    });    // This will fetch the book template and render it.    Book.Views.Details = Backbone.View.extend({      template: "app/templates/books/details.html",      render: function(done) {        var view = this;        // Fetch the template, render it to the View element and call done.        namespace.fetchTemplate(this.template, function(tmpl) {          view.el.innerHTML = tmpl(view.model.toJSON());          if (_.isFunction(done)) {            done(view.el);          }        });      }    });    // This will fetch the book list template and render it.    Book.Views.List = Backbone.View.extend({      template: "app/templates/books/list.html",      render: function(done){        var view = this;        namespace.fetchTemplate(this.template, function(tmpl){          view.el.innerHTML = tmpl({books: view.collection.toJSON()});          if (_.isFunction(done)){            done(view.el);          }        });      }    });    // Required, return the module for AMD compliance    return Book;  });  

This might look like a lot, but it is really quite simple. Let’s break it down below:

The AMD Module Definition

  define([    "namespace",    "use!backbone"  ], function(namespace, Backbone){    var Book = namespace.module();    return Book;  });  

This is the standard format for any AMD module definition. You are telling the module loader that this module needs access to your namespace and backbone, which are defined in app/config.js. Inside the callback function, you are registering your module, and returning it at the end (which follows AMD compliance).

The Module’s Router

  Book.Router = Backbone.Router.extend({});  var router = new Book.Router();  

Whenever the browser is directed to a route in the routes hash, the associated function is called. This is usually where you instantiate the view and call its render function. We instantiate the router so Backbone knows to start picking up the associated routes.

The Module’s Data

  Book.Model = Backbone.Model.extend({});  Book.Collection = Backbone.Collection.extend({    model: Book.Model  });  

This is where your book data and business logic is defined. You will create new instances of your Book.Model to store each book and its attributes (title, author, etc). Book.Collection is associated with Book.Model, and it is how you represent your models as grouped entities. In other words, a library has many books, and a collection is a lot like a library.

These are pretty bare, but you can place any of your business logic in the objects that are passed to the extend methods. If, for instance, you wanted to create a function that would filter books from the collection based on the author, you would do something like the following:

  Book.Collection = Backbone.Collection.extend({    model: Book.Model,    filterByAuthor: function(author){      return this.filter(function(book){        return book.get('author') === author;      });    }  });  

“Underscore functions can be called directly on a Backbone collection.”

This is leveraging the Underscore filter function, which (like most of the Underscore functions) can be called directly on the collection itself. Feel free to read the Backbone documentation for more information on what Underscore functions you can call on your collections.

The same idea applies to your models. You should ideally push all of your business logic to the model. This might be something like adding the ability for your users to set up a book as a ‘favorite.’ For now, you can remove the filterByAuthor method from your collection, as we won’t be using that in this tutorial.

The Module’s Views

  Book.Views.Details = Backbone.View.extend({    template: "app/templates/books/details.html",    render: function(done) {      var view = this;      // Fetch the template, render it to the View element and call done.      namespace.fetchTemplate(this.template, function(tmpl) {        view.el.innerHTML = tmpl(view.model.toJSON());        if (_.isFunction(done)) {          done(view.el);        }      });    }  });  

Your module will contain multiple views. In our example, we have a list view and a details view. Each of these has its own template, and a render function which calls fetchTemplate (defined in namespace.js), sets the result to the views innerHTML, and calls the associated callback function (done). One thing to notice, the list view is passing a collection to its template function, while the details view is passing the model to its template function. In both cases, we are calling toJSON() on the parameter. This helps us ensure that we are simply dealing with data at the template level.


Templates, With Little to No Logic

In app/templates/books/list.html

  <h1>Listing of Books</h1>  <ul>    <% _.each(books, function(book){ %>      <li><a href="book/<%= book.id %>"><%= book.title %></a></li>    <% }); %>  </ul>  

In app/templates/books/details.html

  <h1><%= title %></h1>  <ul>    <li><b>Author: </b><%= author %></li>    <li><b>Year Published: </b><%= published %></li>  </ul>  <a href="/">Back to List</a>  

Since we have a details view and a list view, we will need a template for each of them. In the list view, we will iterate over our collection and render a link to each book’s details view. In our details view, we display individual pieces of data pertaining to the book that was clicked. We are able to use the properties directly because we are passing the data into the template function with their toJSON() methods, which converts standard models/collections to their JSON representations.

Notice the fact that we didn’t have to call preventDefault() for any of the links that were on the page? That is because of the code at the bottom of app/main.js. We are saying any link on the page without data-bypass="true" will automatically invoke preventDefault(), using our Backbone routes instead of default link behaviour.


Bootstrapping Your Data and Setting Your Default Route

At the top of main.js, replace the code with the following:

  require([    "namespace",    // Libs    "jquery",    "use!backbone",    // Modules    "modules/book"  ],  function(namespace, $, Backbone, Book) {    window.Library = new Book.Collection([      { id: 1, title: "A Tale of Two Cities", author: "Charles Dickens", published: 1859 },      { id: 2, title: "The Lord of the Rings", author: "J. R. R. Tolkien", published: 1954 },      { id: 3, title: "The Hobbit", author: "J. R. R. Tolkien", published: 1937 },      { id: 4, title: "And Then There Were None", author: "Agatha Christie", published: 1939 }    ]);    // Defining the application router, you can attach sub routers here.    var Router = Backbone.Router.extend({      routes: {        "":   "index"      },      index: function(){        var view = new Book.Views.List({collection: Library});        view.render(function(el){          $("#main").html(el);        })      }    });    // Everything after the Router stays the same  });  

Typically, your server side component would pass data to your Backbone application through its API (you set these up in your Collections and Models). However, in this tutorial we are simply bootstrapping your views with a few static books, and creating the default route, which passes the Library to the Book list view as its collection.

The only other thing that has to change is the fact that you are passing your module into the module loader (notice the require instead of the define at the top of main.js). By doing this, you are telling your application to load the file and passing it into the callback function so you have access to all of the Book properties.


Wrapping Up

There are a number of other pieces to truly having a scalable web application.

You might be thinking that this looks very similar to every other Backbone tutorial you have read, so what makes this one different? Well, the key to this is the fact that all functionality relating to the Book is stored in one module, which is in its own file. Let’s say you decided to start sharing your movie collection on this site as well. It would be as simple as creating app/modules/movie.js, the associated templates, and telling main.js to load modules/movie.

There are a number of other pieces to truly having a scalable web application, the biggest of which is a robust API on the server. However, if you remember to create a separation of concerns when dealing with different modules in your application, you will find it much easier to maintain, optimize, and grow your code without running into too many issues as a result of unruly spaghetti code.

Additional Backbone learning on Nettuts+.



Ver Star Wars en ASCII desde la consola

¿Siempre pensaron que la consola era aburrida con esas letritas de colores? Quiero contarles que no todo es así, también la pueden usar para ver Star Wars en ASCII (?).

Para hacerlo sólo tienen que abrir un terminal y pegar lo siguiente y disfrutar de la “película”:

  telnet towel.blinkenlights.nl  

Visto en OSX Daily



Ugly Americans (Primera Temporada Completa) [Sat-Rip][V.O + S.E][2010]



TÍTULO ORIGINAL Ugly Americans
AÑO 2010
DURACIÓN 22 min cada episodio
PAÍS Estados Unidos
DIRECTOR Devin Clark (Creator), David M. Stern (Creator), Devin Clark, Lucy Snyder, Aaron Augenblick
GUIÓN Aaron Blitzstein, Devin Clark, Kevin Shinick, David M. Stern, Greg White, Mick Kelly, Jeffrey Poliquin
MÚSICA Andrew Landry, Bradford Reed
PRODUCTORA Tookie Wilson Productions

SINOPSIS Excelente serie de animación para adultos nunca emitida en España.
El protagonista es Mark Lilly, un humano que vive en este Nueva York alternativo, lleno de zombies, vampiros, demonios y criaturas del estilo. Trabaja en el Departamento de Integración como asistente social y su objetivo es precisamente integrar a estos seres no humanos en nuestro mundo buscándoles trabajo.

DESCARGA










Quarantine [HD-Rip][Español][2008]



TÍTULO ORIGINAL Quarantine
AÑO 2008
DURACIÓN 89 min.
PAÍS Estados Unidos
DIRECTOR John Erick Dowdle
GUIÓN Drew Dowdle, John Erick Dowdle (Remake: Jaume Balagueró, Luiso Berdejo, Paco Plaza) FOTOGRAFÍA Ken Seng
REPARTO Jennifer Carpenter, Jay Hernandez, Columbus Short, Johnathon Schaech, Rade Serbedzija, Marin Hinkle, Greg Germann, Steve Harris, Denis O'Hare, Stacy Chbosky
PRODUCTORA Screen Gems / Vertigo Entertainment

SINOPSIS Una reportera y su cámara se quedan atrapados en un edificio con otra gente cuando, en ese momento, sellan el lugar por una supuesta infección vírica en la ciudad de Los Ángeles. Remake americano de la exitosa película española [REC] (Jaume Balagueró & Paco Plaza, 2007).

DESCARGAR





[•REC]² [HD-Rip][Español][2009]


TÍTULO ORIGINAL [•REC] 2 (AKA REC 2)
AÑO 2009
DURACIÓN 85 min.
PAÍS España
DIRECTOR Jaume Balagueró, Paco Plaza
GUIÓN Jaume Balagueró, Manu Díez, Paco Plaza
FOTOGRAFÍA Pablo Rosso
REPARTO Manuela Velasco, Óscar Zafra, Juli Fàbregas, Javier Botet, Ferrán Terraza, Jonathan Mellor, Àlex Batllori, Andrea Ros, Pablo Rosso
PRODUCTORA Filmax

SINOPSIS Secuela de la película [•REC] (2006), con el mismo formato de falso documental. Quince minutos desde el final de la primera parte, un grupo de policías entran en el edificio acompañados por un doctor con tal de conseguir la sangre de los infectados, en especial la de la infectada inicial que habitaba el ático, para encontrar una cura. A su vez, tres adolescentes, un bombero y un antiguo inquilino entran por el alcantarillado. Lo que ninguno sabe es que van a pasar el peor momento de su vida en cuanto se crucen con los infectados.

DESCARGA



Arqueólogos encuentran en Bulgaria la ciudad más antigua de Europa

Según la definición más clásica, se considera Prehistoria al período de tiempo transcurrido entre la aparición de los primeros homínidos hasta que tenemos constancia de la aparición de los primeros documentos escritos, un hecho que tuvo lugar en Oriente Próximo alrededor del año 3.300 a.C. (y que en otras zonas del planeta se daría con posterioridad) aunque, según otros autores, la Prehistoria podría darse por terminada con la aparición de las primeras sociedades complejas que dieron lugar a sociedades y estados algo organizados. Gran parte de la información que tenemos sobre este período histórico procede de excavaciones arqueológicas que tienen lugar en muchos rincones del mundo (como pueden ser las de Atapuerca en España) y, según se ha publicado hoy, un grupo de arqueólogos de Bulgaria ha anunciado que han encontrado la que podría ser la ciudad prehistórica más antigua de Europa.

El hallazgo ha tenido lugar cerca de la ciudad búlgara de Provadia y, a la vista de los restos encontrados (y que han desenterrado), los arqueólogos habrían encontrado los restos de una ciudad amurallada en la que habría casas de hasta dos plantas. Esta ciudad fortificada con un muro defensivo, según las primeras hipótesis, podría haber sido un centro de producción de sal que podría haber estado funcionando entre los años 4.700 y 4.200 a.C., lo cual podría indicar que esta ciudad se fundó unos 1.500 años antes del nacimiento de la civilización de la Antigua Grecia.

¿Un centro de producción de sal? Esta hipótesis se sustenta en la existencia del propio recinto amurallado puesto que en la antigüedad la sal era un bien muy preciado (la palabra salario deriva del latín salarium que significa “pago con sal” y da una idea de la importancia de este producto que se usaba como conservante de la carne). Además, en Bosnia y en Rumanía se han encontrado antiguas minas de sal que corroborarían la existencia de núcleos de población en el mismo período aunque ésta sería la primera ciudad encontrada de dicho período en la zona.

Hace 40 años, cerca de esta excavación se encontró un “tesoro” de objetos de oro (a unos 35 kilómetros de distancia) que se dató como el más antiguo del mundo de estas características y sirvió de pie para explorar la zona y comenzar las excavaciones en el año 2005 y que, además de revelar la muralla o los restos de viviendas de dos plantas también ha servido para identificar lo que podría ser un pozo y un altar para la realización de rituales.

Un hallazgo, sin duda alguna, fascinante.

Imágenes: Mirror, Telegraph y Argophilia

Provadiatell2 Provadia-Solnitsata Provadia Yacimiento b1_2384879b





Hollywood pide no permitir a los usuarios el acceso a sus datos de Megaupload

Hace unos días os contábamos la historia de Kyle Goodwin, un cámara profesional que había iniciado el proceso legal para la vuelta de sus datos legítimos, trabajos que tras la redada del FBI a los servidores de Megaupload se habían quedado confiscados y que Goodwin reclama. Una situación que será revisada en los próximos días en una audiencia que los estudios de Hollywood no están dispuestos que ocurra. Según la MPAA, los datos de los usuarios no pueden ser devueltos ya que “podrían conducir a la infracción masiva de los derechos de autor” que supuestamente se encuentran en los servidores.

Megaupload

Y es que el grupo de presión de Hollywood parece alarmado por la posibilidad de la vuelta de los datos a sus usuarios. La MPAA ha comunicado al juez de Virginia que revisará el caso de Goodwin que:

La decisión de permitir a los usuarios la llave de los archivos confiscados para acceder a sus propios archivos podría agravar la conducta infractora masiva, ya que se trata en este litigio penal.

Hablamos de unos servidores que contienen aproximadamente 25 petabytes de datos, actualmente sin conexión y almacenados por la empresa de hosting Carpathia.

La MPAA no se ha pronunciado sobre la solicitud de Goodwin a tener sus propios vídeos con derechos de autor, pero aún así, ha pedido participar en la audiencia preparada para principios del mes de noviembre con la idea de:

Describir la cantidad abrumadora de infracciones de derechos de autor que se encuentran en Megaupload.

Pensemos que seis miembros actuales de la MPAA forman parte de Paramount Pictures, Walt Disney, Fox, Universal, Sony y Warner Bros, y que para los estudios de Hollywood Megaupload y su fundador Kim Dotcom son el mal que erradicar. Como llegó a decir en su día Chris Dodd, presidente de la Asociación: “se trata del sitio web más grande y más activo operando ilícitamente en el mundo”.

Mientras, la EFF, quién representa a Kyle Goodwin, ha explicado que la postura es un sinsentido:

No tiene mucho sentido para la MPAA, o para MegaUpload o Carpathia, o incluso para el gobierno, evitar el acceso de terceros a la propiedad legal. No sólo daña a dichos terceros individuales, sino que repercute negativamente en todos los proveedores de almacenamiento en la nube y los clientes, quienes, a fin de cuentas trabajan con esa tecnología, y tienen que ser capaces de confiar en el acceso.

Sea como fuere, la postura de la MPAA se une a la del propio Departamento de Justicia de Estados Unidos. Ahora será el juez de Virginia Liam O´Grady el que tome la decisión en la nueva audiencia sobre la petición de Goodwin.





Crossover gratis durante todo el día

Hoy, 31 de octubre, y repitiendo algo que ya habían hecho en anteriores elecciones presidenciales de los EE.UU., la gente de Codeweavers dan subcripciones gratis durante un año a su aplicación Crossover, que permite la ejecución de programas y juegos de Windows en Linux y MacOS X. La idea detrás de la promoción es incitar a la gente a que vote, pero está abierta a todo el mundo, sin importar donde vivas. Aquí está el enlace para obtener las invitaciones. Codeweavers es la empresa que está detrás de Wine y del grueso de su desarrollo. De hecho, el mantenedor de Wine, Juliard, trabaja para ellos. La versión de pago de Wine se configura automáticamente para la instalación de muchas aplicaciones soportadas, que puedes ver aquí. Tienen un modo muy inteligente de elegir a qué nuevas aplicaciones dar soporte: dejan que los usuarios voten. Y además publican la mayoría de su trabajo bajo licencia LGPL. Que conste que no estoy afiliado a Codeweavers de ningún modo, sencillamente me caen bien. Saludos.

2013, el año de las “carreteras inteligentes” en los Países Bajos

A mediados del próximo año se pondrá en marcha en los Países Bajos un proyecto único y diferente encaminado a mejorar los recursos energéticos actuales y el gasto de energía. En el 2013 se pone en marcha un proyecto de diseño inteligente que ofrecerá nuevas carreteras que brillan sobre el asfalto con indicadores luminosos que se encienden y apagaban al paso de los vehículos.

Smart Highway

Daan Roosegaarde, el diseñador que está detrás del concepto que se pondrá en marcha, explicaba el origen de la idea:

Un día estaba sentado en mi coche y me quedé sorprendido por estos caminos que cuestan millones y que a nadie parece importarle cómo se ven y cómo se comportan. Empecé a imaginar una Ruta 66 del futuro donde la tecnología salte de la pantalla de la computadora y se convierte en parte de nosotros.

Smart Highway

Con esta idea presentó el proyecto The Smart Highway en el concurso Best Future Concept holandés resultando ganador del mismo y convirtiendo en unos meses el concepto en una realidad. Un proyecto donde el estudio de Roosegaarde reemplazará las marcas viales por tecnología que aprovecha la luz del sol para luego brillar en la oscuridad de la noche. Una tecnología donde se aplica un tipo de pintura especial que brilla en la oscuridad.

Smart Highway

Una pintura especial que también se puede utilizar para pintar marcadores en la superficie de la carretera (por ejemplo copos de nieve), cuando la temperatura cae, los marcadores se hacen visibles avisando al conductor sobre la situación.

La provincia de Brabante será la primera en instalar los primeros cientos de metros de luz en la oscuridad a mediados del 2013. Luego pasarán a una segunda fase donde se implementará en carriles prioritarios para vehículos eléctricos, luces interactivas que se encienden al paso de los vehículos y finalmente luces de energía eólica en un proyecto que durará los próximos cinco años.

Smart Highway

Y es que según el estudio, la idea no es sólo usar métodos más sostenibles de iluminación en las carreteras principales (que las harán más seguras y eficientes), sino rediseñar las propias carreteras y los vehículos. El estudio cree que el futuro pasa por coches y sistemas de navegación internos conectados en carreteras interactivas como las que presentan. Un futuro donde el gasto de energía y la utilización eficiente de esta se encuentre tanto en carreteras como en vehículos.