2015/12/23

Unobtrusive Template Engine para Express


El uso de los sistemas de templates típicos (como jade, handlebars, jinja, etc), involucra aprender el lenguaje del sistema de templates y procesar el html base para que se acomode a los requerimientos del sistema de template.

El proceso se llama templating. El templating para jade es diferente que el de handlebars, o jinja.

Si uno usa express con jade, los templates que obtenga no servirán para express con handlebars.

Y esa forma de trabajo está bastante extendida. Si uno usa Drupal, los templates que obtenga no servirán para Wordpress. Aún más, si uno usa Drupal 6, los templates que obtenga no servirán para Drupal 7.

Todas las horas que se invierten en un templating no se pueden reutilizar si se cambia de framework. Es algo que mucha gente ve como algo natural pero me molesta desde hace algún tiempo :-P

Hace un tiempo, ensayé la idea con php y querypath. También con Wordpress y querypath.

http://akcideas.blogspot.pe/2011/05/unobstrusive-web-dev.html

Esta vez con nodejs-express con cheerio.

https://github.com/akobashikawa/express-unobtrusive-template-engine

La visión

La idea es hacer los reemplazos necesarios usando los mecanismos de jquery. Encontrar un modo en que el código base html no se toque.

Imagina que maquetas un site en html5. Puro frontend. Tomas ese conjunto de archivos y los dejas caer en cierto directorio de un framework. Y que el framework sea capaz de usarlo tal cual, sin que tengas que procesarlo. Luego, paulatinamente, unobtrusivamente, vas haciendo los reemplazos dinámicos.

Claro que hay que hace templating de todos modos, pero ya no es en el html, sino en el backend de la vista.

Me parece que sería más productivo desarrollar de ese modo.

2015/11/29

NodeJS en DigitalOcean


Vengo aprendiendo NodeJS desde hace unos meses.

Actualmente, tengo voy creando aplicaciones sencillas con Express (un framework para Node) y Angular.

Esas aplicaciones suelen funcionar bien en mi localhost:3000, que es la dirección por default de los proyectos en Express.

Recientemente, tuve la necesidad de deployar una de esas aplicaciones en un hosting y eso me ayudó a completar esa parte del cuadro.

DigitalOcean



https://www.digitalocean.com/

Permite crear droplets donde puedes instalar el sistema operativo de tu preferencia y allí dentro lo que desees, como harías con tu propio servidor. Puedes instalar tantos droplets como desees. Hay un pago mensual, dependiendo de tu consumo de recursos, pero me parece que es uno de los más económicos en su rubro.

Linux Ubuntu

Puede ser cualquier variante de Linux. En mi caso, elegí instalar un droplet con Ubuntu 14.04.3 LTS (trusty). Una vez creado el droplet, te envían el password del root por email.

Luego seguí la guía Initial Server Setup with Ubuntu 14.04

NodeJS

Instalé node vía NVM, que permite usar varias versiones de node en simultáneo.


Por ejemplo, para instalar la versión más estable:

$ nvm install stable
$ nvm use stable

Express

Express puede ser agregado como un módulo más a una aplicación web. Hay varios módulos y que se pueden ir agregando paulatinamente para facilitar el paso de parámetros en los request, las sesiones, el debug, etc. El esquema de trabajo también se puede adaptar a las preferencias personales.

Sin embargo, Express Generator puede construir un esquema base típico para ahorrarnos algo de tiempo.

$ npm install -g express express-generator
$ express --git myexpress

La aplicación corre en el puerto 3000 por default:

$ npm start

O también:

$ node ./bin/www

http://localhost:3000

Nodemon

Durante el desarrollo puede ser práctico usar nodemon para que el servidor se reinicie cuando detecte algún cambio en los archivos de la aplicación:

$ npm install -g nodemon
$ nodemon start

Nunjucks

El sistema de templates por default es jade, pero hay alternativas como nunjucks:

PM2

PM2 permite correr la aplicación como un servicio, monitorear su estado, detenerla, reiniciarla, etc.

$ pm2 start ./bin/www

Las opciones de inicio de la aplicación se pueden colocar en un archivo processes.json:

{
  "apps" : [{
    "name"        : "myexpress",
    "script"      : "./bin/www",
    "log_date_format"  : "YYYY-MM-DD HH:mm Z"
  }]
}

$ pm2 start processes.json

Nginx

Aunque es posible hacer que una aplicación node corra en el puerto 80, hay una alternativa y es la de usar Nginx como proxy reverso para que la aplicación node siga usando el puerto 3000 pero pueda ser accedida a través del puerto 80.

/etc/nginx/sites-available/default

server {
    listen 80;

    server_name rulo.me;

    location /myexpress/ {
        proxy_pass http://rulo.me:3000/;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-NginX-Proxy true;
    }

   location /app-two/ {
        proxy_pass http://rulo.me:3010/;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-NginX-Proxy true;
    }

    location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
        root /home/rulo/www/expressdemo/public;
        access_log off;
        expires max;
    }

}

La idea es que se solicita al servidor web nginx algo como http://midominio.com/myexpress/, entonces él revisa en su mapeo previamente configurado que ese url le corresponde a la aplicación que se ejecuta en el puerto 3000 (que se llama myexpress, pero podría ser otro nombre también) y procede a servirla. Para el usuario parece que se estuviera accediendo a la applicación directamente a través del puerto 80.

Esta estrategia permite tener varias aplicaciones corriendo en diferentes puertos que pueden ser accedidas a través de urls adecuadas, por ejemplo cualquiernombre:3010 a través de http://midominio.com/app-two

2015/09/09

Node: de 0.12.5 a 4

NodeJS se ha actualizado a la versión 4.


2015/08/03

Por qué la copia prospera

Todo lo que favorece a la copia prospera y vive. Así ha sido cada vez. Sin la habilidad de copiar de los demás, todo nuestro conocimiento se limitaría a nuestras propias experiencias. Copiar es un modo más eficiente de sobrevivir. No importa la carga moral que le quieras dar, ni que la vuelvas ilegal. Finalmente se abre paso, y todos aquellos que intentan resistir a su avance quedan extintos. El futuro está escrito en open source.

2015/06/29

Buscando números amigos

Leyendo "La fórmula preferida del profesor", de Yoko Ogawa, encontré el concepto de números amigos. Quizás ya lo había oído antes, hace tiempo. Esta vez, se me ocurrió que podría explorar algunas inquietudes con ayuda de la programación.

Un número natural (es decir, entero positivo) siempre se puede dividir sin dejar resto entre sí mismo y entre uno. 12 se puede dividir exactamente entre 12 y entre 1, como cualquier número natural.

Además, la mayoría de números (aparentemente) se puede dividir exactamente entre otros números menores. 12 se puede dividir también entre 2, 3, 4, y 6.

Los divisores de un número son todos los números menores entre los que se puede dividir exactamente. Los divisores de 12 serían 1, 2, 3, 4, y 6.

Los números 220 y 284, que aparecen en la novela, son amigos porque la suma de los divisores de uno resulta en el valor del otro:

220: 1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 = 284
284: 1 + 2 + 4 + 71 + 142 = 220

Se dice que números amigos son extremadamente infrecuentes. Que matemáticos como Fermat y Descartes solo llegaron a encontrar un par, cada uno.

Programando

Pruebo crear un programa en javascript que muestre los divisores, la suma de los divisores, y luego haga lo mismo con esa suma, resaltando un OK si es igual al número:

Se pueden hallar los siguientes pares:
  • 1, 1
  • 6, 6
  • 28, 28
  • 220, 284
Si ampliamos el límite más allá de 300, van apareciendo:
  • 496, 496
  • 1184, 1210
  • 2620, 2924

Los amigos de mis amigos


Para los números amigos, noto este esquema:

a -(sumDiv)-> b -(sumDiv)-> a

¿Qué tal si flexibilizamos un poco la amistad, y que los amigos de mis amigos puedan ser mis amigos?:

a -(sumDiv)-> b -(sumDiv)-> c -(sumDiv)-> d -(sumDiv)-> e -(sumDiv)-> a

Eso sería un grupo de amigos: a, b, c, d, e

Programando

Este programa muestra la serie de suma de divisores del número previo, hasta que se alcance una repetición. Entonces muestra OK.

No conseguí encontrar ningún grupo con más de dos miembros.

Sin embargo, noté que hay números con series largas, que a veces ascienden un poco, antes de converger hacia 1:

  • 30: 42 54 66 78 90 144 259 45 33 15 9 4 3 1
  • 42: 54 66 78 90 144 259 45 33 15 9 4 3 1
  • 54: 66 78 90 144 259 45 33 15 9 4 3 1
  • 60: 108 172 136 134 70 74 40 50 43 1
  • 66: 78 90 144 259 45 33 15 9 4 3 1
  • 102: 114 126 186 198 270 450 759 393 135 105 87 33 15 9 4 3 1
  • 114: 126 186 198 270 450 759 393 135 105 87 33 15 9 4 3 1
  • 120: 240 504 1056 1968 3240 7650 14112 32571 27333 12161 1
  • 126: 186 198 270 450 759 393 135 105 87 33 15 9 4 3 1
  • 132: 204 300 568 512 511 81 40 50 43 1
  • 174: 186 198 270 450 759 393 135 105 87 33 15 9 4 3 1

También aparecieron números con series divergentes:

  • 138: 150 222 234 312 528 960 2088 3762 5598 6570 10746 13254 13830 19434 20886 21606 25098 26742 26754 40446...
  • 150: 222 234 312 528 960 2088 3762 5598 6570 10746 13254 13830 19434 20886 21606 25098 26742 26754 40446 63234...
  • 168: 312 528 960 2088 3762 5598 6570 10746 13254 13830 19434 20886 21606 25098 26742 26754 40446 63234 77406 110754...
  • 180: 366 378 582 594 846 1026 1374 1386 2358 2790 4698 6192 11540 12736 12664 11096 11104 10820 11944 10466...
  • 210: 366 378 582 594 846 1026 1374 1386 2358 2790 4698 6192 11540 12736 12664 11096 11104 10820 11944 10466...

Es como si hubieran ciertos números disparadores: 138, 150, 168, 180, 210, 222, 234, ...

Preguntas

¿Por qué algunas series divergen?
¿Habrá alguna aplicación para los números con series de suma de divisores divergentes?