viernes, 21 de marzo de 2014

Tutorial de Backbone.js (II)


Backbone.js es una herramienta que permite separar el trabajo con datos, el trabajo de la capa visual y las acciones de navegación, lo cual hace de ésta una herramienta muy versátil a la hora de trabajar proyectos muy grandes. En la entrada anterior escribí acerca de la potencia de esta herramienta con respecto al manejo que le da a la capa de datos, en esta oportunidad veremos la manera en que se gestiona la interacción con el usuario mediante sus vistas.

Interacción con el usuario
Cuando hablamos de interacción con el usuario hacemos referencia explícita a a las vistas (Views) y a los Enrutadores (routers), en esta ocasión sólo hablaremos de las vistas. Las vistas en Backbone.js son elementos muy importantes puesto que son los encargados de presentar la información que llega del backend del servidor y permitir que los usuarios interactúen con ésta. Para esta labor se extiende la clase Backbone.View, veamos un ejemplo.

var ViewLibro = Backbone.View.extend({
    events:{
        "click a#delete" : "eliminar",
    },
    initialize : function () {
        this.template = _.template(
                 $('#templatelibro').html()
                 );
    },
    render : function() {
        var data = this.model.toJSON();
        var html = this.template(data);
        this.$el.append( html );
    },
    eliminar: function(e) {
        this.model.url = this.model.url+this.model.id;
        this.model.destroy();
        var libro = $(e.currentTarget).parent().parent();
        libro.remove();
        e.stopPropagation();
    }
});

Además hacemos unos pequeños cambios a la función listarLibros
function listarLibros () {
    $(".datos").html("")
    var coleccion_libros = new Libros();
    coleccion_libros.on("add", function(model){
        console.log("Agregado", model.toJSON());
        var vl = new ViewLibro({el:$("ul.datos"),model:model});
        vl.render();
    });
    var xhr = coleccion_libros.fetch()
    xhr.done(function () {
        console.log('Libros descargados...');
        var llibros = coleccion_libros.filter(function (model) {
            var libro = model.toJSON();
            return libro.nombre === "El Principito";
        });
        if(llibros.length==0){
            var libroNuevo = new Libro({
                "nombre":"El Principito",
                "editorial":"Panamericana",
                "genero":"Infantil",
                "autor":"1"
            });
            libroNuevo.save();
            libroNuevo.attributes.id = 1;
            coleccion_libros.add(libroNuevo);
        }
        console.log("0k");
    });

}

Y finalmente agregamos el template respectivo
<script type="text/template" id="templatelibro">
    <div id="libro-<%= id %>" class="libro">
        <strong>Nombre:</strong> <%= nombre %> <br/>
        <strong>Editorial:</strong> <%= editorial %><br/>
        <strong>Genero:</strong> <%= genero %><br/><br/>
        <div class="actions">
            <a href="#" id="delete">Eliminar Libro</a>
        </div>
    </div>
</script>
Muy bien, pero ¿Qué hace todo esto? Primero construimos la vista, para esto hacemos una clase que hereda de Backbone.View, esta tiene una serie de elementos que hacen posible toda la "magia" que hace internamente, el primero es el objeto events, el cual almacena el tipo de evento (por ejemplo click) y sobre que elemento del DOM se aplica, para esto usamos "." (punto) para especificar clases y y "#" para especificar los identificadores. Asociado a esto se encuentra el nombre del método que se ejecutará cuando el evento sea llevado a cabo.
Luego encontramos el método initialize, que inicializa la vista, adentro de este creamos el template de la vista, debemos tener en cuenta que el carácter "_" hace referencia a la librería Underscore.js, también creada por Jeremy Ashkenas, creador de Backbone.js, la cual tiene una serie de herramientas muy útiles y una de estas es un sistema de templates. Cabe aclarar que no es obligatorio usar el sistema de templates de underscore, su puede usar el que se desee (swig, mustache, etc).
Después encontramos el método render, que toma los datos del modelo y los renderiza con el template creado en el método initialize para finalmente mostrarlo al usuario en el lugar de destino, referido por la variable de clase $el.
Como último elemento de la vista encontramos el método eliminar, que actualiza la url del modelo, llama el método eliminar y retira el HTML asociado al modelo del DOM.

Dentro de la función listar libros encontramos que ya no creamos el código HTML necesario para incrustar en el DOM, en cambio creamos una instancia de la vista y la renderizamos y al crear en nuevo libro especificamos como atributo el id de ese nuevo objeto.

Finalmente esta el código del template asociado a la vista, notese que éste se guarda en un tag script de tipo text/template y tiene un identificador para poder recuperarlo con Javascript.

jueves, 20 de marzo de 2014

Tutorial de QtCreator


Hace algunos años hice un tutorial de QtCreator, espero que les guste.


Por favor comparte este articulo. 
:D

jueves, 13 de marzo de 2014

Tutorial de Backbone.js (I)


Hoy en día hay una nueva tendencia a la hora de hacer sitios web,  ésta es usar el patrón MVC en los clientes para lograr una mejor experiencia, es por esto que se han creado frameworks como Backbone.js o Angular.js, los cuales permiten usar MVC en el cliente y permiten sacarle todo el jugo a JavaScript. Una vez dicho esto entremos en materia.

¿Qué es Backbone.js?
Backbone.js es un framework que permite al desarrollador estructurar su aplicación, delegando ciertas labores a elementos específicos con el fin de hacer aplicaciones escalables, robustas y que brinden al usuario una gran experiencia de uso.

Entendiendo Backbone
Antes habíamos hablado de una serie de elementos que estructuran una aplicación, éstos elementos son los modelos (Models) y colecciones (Collections), que manejan la capa de datos, vistas (Views) para gestionar el contenido que interactúa con los usuarios y enrutadores (Routers) que permiten realizar los procesos de navegación en la aplicación. Una de las cosas más interesantes de este framework es que en la mayoría de los objetos se pueden definir una serie de eventos que permiten responder a las acciones del usuario. Otro punto a favor es que la capa de datos puede conectarse con varios tipos de fuentes de datos como REST, local storage y otros más.

Capa de Datos
Como ya mencione antes la capa de datos esta compuesta por modelos (Model) y colecciones (Collection), es necesario entender que un modelo es un elemento asociado a una fuente específica de datos y que un una instancia de un modelo es una unidad de datos, es decir, lo equivalente a un registro en una base de datos. En comparación una colección es es un elemento asociado a una fuente específica de datos y a un modelo específico y una instancia de una colección es un grupo de instancias de un modelo.
Tanto los modelos como las colecciones pueden responder a eventos como un nuevo dato agregado, el cambio de un dato existente y más, respondiendo a estos eventos con acciones asignadas por el programador.
Veamos un ejemplo:
// Ejemplo de modelos y colecciones
var Libro = Backbone.Model.extend({
    url : '/api/libros/',
    initialize: function(){
       // TODO: acciones de inicialización del modelo
    }
});

var Libros = Backbone.Collection.extend({
    model: Libro,
    url: '/api/libros/',
    initialize: function(){
       // TODO: acciones de inicialización del colección
    }
});


Como vemos en el código anterior se definen un modelo y una colección, los cuales tienen como fuente común de datos una api REST que provee los datos. Además la colección tiene asociado un modelo.
Sin embargo el código anterior no permitirá usar ningún dato hasta que se descarguen de manera explicita. Ahora miremos cómo usar modelos y colecciones:
// Ejemplo de modelos y colecciones, como cargar datos del servidor

    function listarLibros () {
        $("ul.datos").html("")
        var coleccion_libros = new Libros();
        coleccion_libros.on("add", function(model){
            console.log("Agregado", model.toJSON());
            $(".datos").append("<li>"+
                JSON.stringify(model.toJSON())+
                "</li>"
                );
        });
        var xhr = coleccion_libros.fetch()
        xhr.done(function () {
            console.log('Libros descargados...');
            var llibros = coleccion_libros.filter(function (model) {
                var libro = model.toJSON();
                return libro.nombre === "El Principito";
            });
            if(llibros.length==0){
                var libroNuevo = new Libro({
                    "nombre":"El Principito",
                    "editorial":"Panamericana",
                    "genero":"Infantil",
                    "autor":"1"
                });
                libroNuevo.save();
                coleccion_libros.add(libroNuevo);
            }
            console.log("0k");
        });

    }


En el último ejemplo vemos una función en la cual se cargan los datos desde el servidor con la instrucción fetch y se agregan a una lista (ul.datos) y si no hay ningún libro con nombre "El Principito" este se agrega.
Como vemos en el ejemplo se crea un objeto de tipo colección (coleccion_libros) y éste gestiona la carga de datos del servidor, además se pueden hacer bindings entre eventos y funciones, de esta manera se muestran los datos en la pagina web dentro de una lista cada vez que se agrega un nuevo elemento a la colección.

Pueden encontrar el código de ejemplo en Github. espero que les sea de ayuda.

Por favor comparte éste post... 
:D

miércoles, 19 de febrero de 2014

Tutorial ¿Cómo compilar Python3 en Linux Debian?


Muchos ya lo han dicho, hay que dejar de lado Python2.X y aunque aun falta para ello he aquí un tutorial para compilar en nuestra maquina linux (debian para ser exactos) Python3.3.

Instalación de dependencias
Como super usuario (root) ejecutamos la siguiente instrucción en la linea de comandos:
apt-get install make build-essential  zlib1g-dev  libbz2-dev  libncurses5-dev  libreadline6-dev  libsqlite3-dev  libssl-dev  libgdbm-dev liblzma-dev tk8.5-dev

Descarga y compilación
Ahora bien, debemos descargar el código fuente y compilarlo, para ello ejecutamos las siguientes instrucciones:
wget -c http://python.org/ftp/python/3.3.4/Python-3.3.4.tgz
tar -zxf Python-3.3.4.tgz
cd Python-3.3.4
# Proceso de compilación
# primero se configuran los makefile para el sistema
./configure
# inicia compilación
make
# se hacen pruebas para saber que todo salió bien, 
# es recomendable pero no obligatorio.
make test
# instalación de los binarios en el sistema
make install

Finalmente solo queda probarlo ejecutando python3.3.

Espero que les haya gustado.

Si te gusto el post
compartelo... :D

martes, 4 de febrero de 2014

Django y las class based views


Cuando se trabaja en django resulta claro que hay muchas labores que son mas y mas fáciles, pero manejar la lógica de una petición mediante una función puede ser perjudicial a la hora de manejar muchas vistas. Es por eso que en este post vamos a ver cómo usar class bases views, una forma mas ordenada de encapsular la lógica.

¿Qué son?
Class-Based-Views (CBV en adelante) es una forma alternativa para crear vistas en django, no pretende reemplazar  las Function-Based-Views (FBV en adelante) , pero si tienen como objetivo permitir al desarrollador:
  • Organización del código relacionado con metodos HTTP específicos (GET, POST, PUT, etc) y que el router pueda acceder a estos sin tener que usar condicionales específicas.
  • Técnicas orientadas a objetos (Como los Mixins) para solucionar ciertos problemas.
¿Por qué usarlas?
La pregunta clave es ¿por qué? y ante esto hay varias cosas que la respaldan:

  • Orden.
  • Estética del Código.
  • Reciclaje del Código.
  • Uso de herramientas de OOP.
  • Simpleza.
  • Estructura bien definida (definición de acciones para cada protocolo, definición de respuestas para casos de éxito y falla con métodos como get_success_url).
¿Cómo funcionan?
Para entender mejor ciertos aspectos de cómo funcionan las CBV debemos ver un poco de FBV

# views.py
from django.shortcuts import render

def index(request):
    if request.method == 'GET':
        # TODO: GET ACTIONS
        return render(request,"template_get.html")
    elif request.method == 'POST':
        # TODO: POST ACTIONS
        return render(request,"template_POST.html")
    elif request.method == 'PUT':
        # TODO: PUT ACTIONS
        return render(request,"template_put.html")
    elif request.method == 'DELETE':
        # TODO: DELETE ACTIONS
        return render(request,"template_del.html")

# end views.py
# ----------------------
# urls.py

from django.conf.urls import patterns

urlpatterns = patterns('',
    (r'^$', "myapp.views.index"),
)
# end urls.py

Como vemos en el código anterior en una sola función la lógica de múltiples ti pos de respuestas, y esto no es adecuado porque restara mantenibilidad y escalabilidad a nuestra aplicación, para evitar eso están las CBV, veamos a continuación cómo sería esto:
# views.py
from django.views.generic.base import View
from django.shortcuts import render

class IndexView(View):

    def get(self, request):
        # TODO: GET ACTIONS
        return render(request,"template_get.html")

    def post(self, request):
        # TODO: POST ACTIONS
        return render(request,"template_POST.html")

    def put(self, request):
        # TODO: PUT ACTIONS
        return render(request,"template_put.html")

    def delete(self, request):
        # TODO: DELETE ACTIONS
        return render(request,"template_del.html")

# end views.py
# ----------------------
# urls.py

from django.conf.urls import patterns
from myapp.views import IndexView

urlpatterns = patterns('',
    (r'^$', IndexView.as_view()),
)

# end urls.py

Como vemos en el código anterior la legibilidad del código mejoraría en caso de que existiesen muchas líneas de código por cada método, además de que ya sería posible usar ciertas técnicas de programación orientada a objetos como los mixins.

Espero que les sea de utilidad.

Si te gusto el post 
compartelo... :D