Gestión de repositorios enormes con Git

Git es una opción elegante para seguir la evolución del código base y para colaborar eficazmente entre equipos de trabajo.

Información completa:

Crecimiento de repositorios

Es un hecho que los repositorios crecen durante un largo período de tiempo de desarrollo, esto quiere decir que van acumulando un historial. Por otro lado, además es probable que algunos proyectos pueden incluir enormes activos binarios que también deben ser seguidos y combinados con el código.

Así que un repositorio puede crecer en dos direcciones: el tamaño del directorio de trabajo – es decir, el último “commit” – y el tamaño de todo el historial acumulado. Otro escenario problemático es que a veces existen artefactos binarios antiguos en desuso, que siguen almacenados en el repositorio.

Shallow Clone

Clonar sin tanta profundidad permite jalar un repositorio manteniendo sólo las últimas n confirmaciones del historial.

git clone --depth NUMERIC-VAL REMOTE-REPO-URl OPTIONAL-LOCAL-FOLDER-NAME

git clone --depth 1 https://github.com/joyent/node.git node

Opción recomendada

De manera alternativa es posible clonar sólo una rama, por ejemplo:

git clone --depth NUMERIC-VAL REMOTE-REPO-URl --branch REMOTE-BRANCH-NAME --single-branch OPTIONAL-LOCAL-FOLDER-NAME

git clone --depth 1 https://github.com/joyent/node.git --branch master --single-branch node

Corroboración

git branch

* master
git branch -a

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
git rev-list HEAD --count

1
git shortlog | grep -E '^[ ]+\w+' | wc -l

1
git shortlog | grep -E '^[^ ]'

Chuck Norris (1):

 

Evangelizándome lo modular que es Angular

Directivas ng-

Ls Directivas, sirven para enseñar nuevos trucos a HTML. De hecho, con Angular se puede extender el HTML. Para empezar, las directivas más utilizadas son las siguientes:

ng-app

Inicializa una aplicación Angular. Sirve para auto-arrancar una aplicación AngularJS . Esta directiva designa el elemento raíz de la aplicación y normalmente se coloca cerca del elemento raíz de la página – por ejemplo, en las etiquetas <body> o <html>.

Para correr múltiples aplicaciones en un documento HTML, éstas se deben arrancar manualmente utilizando angular.bootstrap. Las aplicaciones AngularJS no se pueden anidar unas dentro de otras. Entonces es posible especificar un módulo AngularJS que pueda ser utilizado como el módulo raíz de la aplicación. Este módulo se puede cargar en el $inyector cuando se arranca la aplicación, además debe contener el código necesario de la aplicación, también puede definir las dependencias de otros módulos que también comparten el código necesario para la aplicación.

<html ng-app"App">

ng-model

Coloca una propiedad en la memoria, dentro de lo que Angular conoce como el $scope. Lo que sucede detrás de cámaras es que se crea un Vista-Modelo vacío y lo rellena con el valor que adquiere la propiedad.

<input type="text" ng-model="title" /> {{ title }}

Data Binding Expression:

{{ title }}

Más información en:

ng-init

La directiva ng-init permite evaluar una expresión en el ámbito/$scope actual.

El uso apropiado de ng-init es para apodar/”aliasing” propiedades especiales de ng-repeat. Además del caso anterior, se recomienda usar Controladores en lugar de ng-init que inicializa valores en un sólo ámbito.

Más información:

ng-repeat

Facilita la duplicación de elementos al iterar sobre información.

La directiva ng-repeat instancia una plantilla, una vez por cada elemento de una colección. Cada instancia de plantilla tiene su propio ámbito, por esta razó en un bucle se ajusta al elemento actual de la colección, y el $index se establece en el índice o clave del elemento.

<ul>
    <li ng-repeat="title in titles">{{ title }}.</li>
</ul>

Más información:

Filtros

En el siguiente caso se hace un data-binding con {{ listing.title }} y de paso en el proceso se convierte a mayúsculas:

<ul>
    <li ng-repeat="listing in listings | orderBy:'title'">
        {{ listing.title | uppercase }}
    </li>
</ul>

En el siguiente caso “titleText” es el valor que escribe/”input” el usuario. Por ejemplo, si existe 50 listados, se podría filtrar esos listados por todos aquellos que comiencen con “Pretty” o con “Quiet”.

<body ng-init="listings=[{title: 'Pretty', address:'Here'}, {title: 'Quiet', address:'There'}, {title: 'Pretty Quiet', address:'Here and There'}]">

<input type="text" ng-model="titleText">

ViewModel = Ambiente/$scope

Por el bienestar de este artículo, se va a comparar Angular con el patrón de diseño MVC.

La arquitectura de Angular se puede parecer a la de una aplicación basada en MVC. Como existe éste vínculo, es posible ver la plantilla/”template” como la “View” y el Ambiente/”$scope” como el “Modelo”.

El $scope Object es el pegamento ViewModel

Es simple, es el pegamento (ViewModel) que integra el Controlador con la Vista. Como el Controlador no sabe nada de la Vista y es por es razón se afecta la vista inyectando el $scope de manera automática en la Vista.

La Vista, el Ambiente y el Controlador son los tres principales bloques de construcción de una aplicación potenciada por Angular.

Más información:

https://www.youtube.com/watch?v=HvTZbQ_hUZY

Modules, Routes and Factories

Todo Module/Container puede tener una función llamada Config que se puede utilizar para definir diferentes Routes. En esencia los Routes sirven para rastrear y asociar que Vistas que necesitan estar casadas con determinados Controladores.

  • Module -> Config -> Routes

Casi todo Controlador necesita estar enrutado con una Vista:

  • Routes -> View
  • Routes -> Controller

Los Controladores pueden manipular el objeto $scope, el cual puede ser automáticamente ajustado a la Vista. Por lo tanto, en lugar de tener toda la funcionalidad que obtiene o actualiza los datos (CRUD) en el Controlador, en una aplicación de la vida real este acceso y manipulación a los datos se hace por medio Factories, Services, Resources o Providers.

  • Controller -> Factory

En las Vistas es donde colocamos las Directivas y los Filtros.

  • View -> Directives

En resumen los Módulos son Objetos, son Contenedores. Y dentro de esos contenedores se puede tener todo lo que acabamos de ver.

Dfinición de un nuevo Módulo

var myAppModule = angular.module('myAppModule', []);

¿Qué es []?

Es el arreglo donde podemos inyectar otros Módulos de los cuales puede depender nuestro Módulo.

var myAppModule = angular.module('myAppModule', ['myHelperModule']);

Definiendo un Controlador dentro de un Módulo

myAppModule.controller('myCustomController', function ($scope) {
    $scope.listings = [
        {title: 'Pretty', address: 'Here'},
        {title: 'Quiet', address: 'There'},
        {title: 'PrettyQuiet', address: 'Here and There'},
    ];
});

Definiendo el proveedor de Rutas (el pegamento)

myModuleApp.config(function ($routerProvider) {
    $routerProvider
        .when('/'
            {
                controller: 'MyHomeController',
                controller: 'view-home.html'
            })
        .when('/custom'
            {
                controller: 'MyCustomController',
                controller: 'view-custom.html'
            })
        .otherwise({ redirectTo: '/'});
});

En las Rutas es donde ocurre el verdadero pegamento entre la Vista y el Controlador. También se puede decir que gracias a las Rutas, es que Angular sabe como manejar el “History”.

Factories, Servicios y Proveedores

Primero que todo, sirven para encapsular funcionalidad común sobre los datos, para evitar duplicación y facilitar la re-utilización. La diferencia entre los tres radica en cómo crean el objeto, proceden y obtienen los datos:

  • Con Factory se crea un Objeto dentro del Factory y se devuelve.
  • Service es una función estándar que utiliza la palabra clave this para definir funciones.
  • Con Provider hay una función $get que se usa para obtener el Objeto que retorna los datos.
  • Value, es para tener un valor simple de configuración. “Name Value Pairs“.

Definiendo un Factory en nuestro Módulo

.factory('myCustomFactory', function () {
    var factory = {};
    // Async: Include your Ajax call here.
    var listings = [ ... ];

    factory.getListings = function () {
        return listings;
    };

    return factory;
});

AngularJS innyecta los Factories de manera automática gracias a un parámetro que se pasa al Controlador. Además pueden depender o confiar en otros Factories para funcionar. Con Factory es más fácil manipular el Objeto mismo, en cambio con Service hay que usar la palabra clave this.

.controller('myCustomController', function($scope, myCustomFactory) {
    $scope.listings = [];

    // Private Function Init.
    function init() {
        $scope.customers = myCustomFactory.getListings();        
    }

    init();
});

Siempre hay más:

https://www.youtube.com/watch?v=Lx7ycjC8qjE&list=PLP6DbQBkn9ymGQh2qpk9ImLHdSH5T7yw7

Para más información, por favor consulte:

Promesas en JavaScript

En esencia, una Promesa es el resultado de una tarea, que puede o no haber terminado. El único requisito de interfaz de una promesa es tener una función llamada “then”, que puede hacer un “callback” cuando la promesa se cumple o cuando falla.

Listings.getAll("ID").then(function(listing) {
  return query.find();
}).then(function(results) {
  return results[0].update({ key: value });
}).then(function(result) {
  console.log('Ok').
}, function(error) {
  console.log('Error').
});

La ventaja “cuántica” de una Promesa

JavaScript es “single threaded”, lo que significa que dos bits de un Script no se pueden ejecutar al mismo tiempo, se van corriendo uno tras otro. Además en un navegador Web, JavaScript comparte un hilo con muchas otras cosas que suceden.

https://www.youtube.com/watch?v=o84ryzNp36Q

AngularJS Promises

Las promesas son muy útiles cuando se está trabajando con “Async: Success/Error” porque el interés se centra ​​en reaccionar ante el resultado y no en el momento exacto en que algo se vuelve disponible.

Una promesa puede ser:

  • Fulfilled – La acción en relación con la promesa se logró.
  • Rejected – La acción en relación con la promesa falló.
  • Pending – Pendiente, no se ha cumplido o rechazado aún.
  • Settled – Reiterada, se ha cumplido o se ha rechazado.

La diferencia es sutil, pero muy útil. Los fallos o rechazos de Promesas saltan hacia adelante al siguiente “then”, con un “callback” de rechazo (o “catch”, que es equivalente). Por ejemplo, con then(func1, func2), func1 o func2 pueden ser llamados, pero nunca ambos. Pero con then(func1).catch(func2), ambos serán llamados aún si func1 falla, ya que son pasos separados en la cadena.

ECMAScript 6 (ES6)

Para ampliar información sobre Excepciones, Paralelismo, Secuencias y Generadores:

WordPress JSON-based REST API & Cordova

REST es un concepto de diseño. De hecho, la misma World Wide Web representa la mayor implementación de un sistema conforme al estilo arquitectónico REST.

REST no es tan rígido como SOAP. Los “RESTful web-services” utilizan URIs y métodos estándar para hacer llamadas a un “Webservice”. Por lo tanto, cuando se solicita un URI, se recibe una respuesta con la representación de un objeto, sobre el cual se puede realizar operaciones, por ejemplo: GET, PUT, POST y DELETE. Por dicha no estamos limitados a usar XML para representar datos, la opción recomendada es escoger las basadas en JSON, son muy útiles para representar datos.

JSON y XML, son “funcionalmente equivalentes”. Pero XML es considerado como demasiado detallado, y muchas veces muy difícil de analizar, por otro lado, parece más decente representar los datos usando JSON.

Crear Document Root del Dominio

sudo mkdir -p /var/www/app.josoroma.lh/htdocs

sudo chown -R josoroma:josoroma /var/www/app.josoroma.com

Bajar y descomprimir WordPress

cd /var/www/app.josoroma.lh/htdocs

wget http://wordpress.org/latest.tar.gz

tar -xvzpf latest.tar.gz --strip-components=1

Sólo porque es un Ambiente de Desarrollo

chmod -R 777 /var/www/app.josoroma.lh

Crear usuario y Base de Datos

mysql -u root -p -h localhost
CREATE USER 'josoromapp'@'localhost' IDENTIFIED BY  '***';

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,
 FILE, INDEX, ALTER, CREATE TEMPORARY TABLES, CREATE VIEW, EVENT, TRIGGER, SHOW VIEW,
 CREATE ROUTINE, ALTER ROUTINE,
 EXECUTE ON * . * TO  'josoromapp'@'localhost' IDENTIFIED BY  '***' WITH 
  MAX_QUERIES_PER_HOUR 0 
  MAX_CONNECTIONS_PER_HOUR 0 
  MAX_UPDATES_PER_HOUR 0 
  MAX_USER_CONNECTIONS 0;

CREATE DATABASE IF NOT EXISTS  `dbjosoromapp`;

GRANT ALL PRIVILEGES ON  `dbjosoromapp` . * TO  'josoromapp'@'localhost';

Configuración básica con Apache

sudo su

vi /etc/apache2/sites-available/app.josoroma.lh.conf
<VirtualHost *:80>
        ServerName app.josoroma.lh

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/app.josoroma.lh/htdocs

        <Directory /var/www/app.josoroma.lh/htdocs/>
                Options FollowSymlinks
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        LogLevel warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Mapear el Host a una IP

127.0.0.1       app.josoroma.lh

Habilitar el “VirtualHost”

a2ensite app.josoroma.lh.conf

Agregar Mod Rewrite y reiniciar Apache

sudo a2enmod rewrite

service apache2 reload

WordPress Coding Standards para Sublime/phpcs

mkdir ~/.gitvendor

# idiotic path
git clone git://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git ~/.gitvendor/wordpress/coder_sniffer/WordPress

ls -la .gitvendor/wordpress/coder_sniffer/WordPress

cd ~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards

ln -s ~/.gitvendor/wordpress/coder_sniffer/WordPress WordPress
phpcs -i

The installed coding standards are WordPress, PEAR, PHPCS, PSR1, Drupal, Zend, Squiz, PSR2 and MySource

Para tener acceso a un API tan confortable como el de:

WordPress.com

existen varias opciones, las que parecen interesantes de escarbar son las siguientes:

Que una instalación de WordPress ofrezca un REST API basado en JSON es muy importante porque permite que otras aplicaciones conversen con este API para solicitar información, por ejemplo, mediante un Web Service desde la otra aplicación. Esta otra aplicación puede ser una App de teléfono Android o IOS, creada con una solución como PhoneGap-Corodova. Además se puede negociar con el API para crear, actualizar o borrar “cosas”.

En combinación con AngularJS-Ionic se puede jugar bastante con APIS externos. Las implicaciones son muy interesantes y parece que bastante capitalizables con soluciones desde juegos hasta buscadores mezclados con Mapas para nichos como Bienes Raíces, Turismo, Profesionales, Autos, por mencionar algunos.

Por favor consulte:

<VirtualHost *:80>
        ServerName app.josoroma.lh

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/app.josoroma.lh/htdocs

        <Directory /var/www/app.josoroma.lh/htdocs/>
                Header set Access-Control-Allow-Origin "*"
                Options FollowSymlinks
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        LogLevel warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Ejemplo de una solicitud utilizando HTTP-GET:

/posts: {
    supports: [
        "HEAD",
        "GET",
        "POST"
    ],
    meta: {
        self: "http://app.josoroma.lh/api/posts"
    },
    accepts_json: true
},
/posts/: {
    supports: [
        "HEAD",
        "GET",
        "POST",
        "PUT",
        "PATCH",
        "DELETE"
    ],
    accepts_json: true
}

PHP – Patrón de diseño Singleton

Algunos recursos de aplicaciones son exclusivos, por ejemplo, la conexión a una base de datos a través del manejador de la base de datos es exclusivo.

Se comparte el manejador de la base de datos porque puede darse un “overhead” al estar abriendo y cerrando conexiones, en particular durante la petición a una sola página.

Un Objeto es un Singleton si la aplicación puede incluir uno y sólo uno de esos objetos a la vez.

PHP – Patrón de diseño Factory

En vez de usar new para crear Objetos, se usa una Clase Factory. Entonces, si se necesita el tipo de los Objetos creados, sólo se cambia la Clase Factory. Por lo tanto, todo el código que use la Clase Factory cambiará de manera automática.

En sistemas complejos, la mayoría del código confía en pocas Clases clave. Las dificultades surgen cuando se necesita cambiar esas Clases. Por ejemplo, si hay una Clase User que lee desde un archivo y se necesita cambiar el código para que más bien lea desde una Base de Datos. En este caso es cuando el patrón de diseño Factory se vuelve útil.

Esta variación usa Métodos Factory (static) en lugar de Clases Factory.

DRY: Encapsula el proceso de crear Objetos User en un sólo lugar, de ésta manera trozos de código complejo para inicializar Objetos no van a ser copiados y pegados una y otra vez por todo lado.

Configurar ambiente con GitHub

Generación de claves RSA

El primer paso consiste en crear el conjunto de claves RSA para usar en la autenticación con GitHub. A continuación vamos a crear nuestra propias claves SSH, una pública y otra privada:

mkdir ~/.ssh
chmod 700 ~/.ssh

ssh-keygen -t rsa -b 2048 -C "MY_EMAIL"

Entonces agregamos nuestra nueva clave al ssh-agent:

ssh-add ~/.ssh/id_rsa

Para más información sobre como agregar nuestra propia llave pública a GitHub, por favor consulte:

sudo apt-get install ssh-copy-id

man ssh-copy-id

De manera alternativa, se pueden pegar las llaves usando SSH, por ejemplo:

cat ~/.ssh/id_rsa.pub | ssh MY_USER@REMOTE_HOST "cat >> ~/.ssh/authorized_keys"

Configuración básica

git config --global user.name "MY_USERNAME"

git config --global user.email "MY_EMAIL"

git config --global push.default upstream
git config --global push.default tracking  (deprecated)

git config --global branch.autosetuprebase always

Rastreo automático de ramas

Por ejemplo, empujar la rama llamada “hotfix/issueShortName_issueID_username” en el “origin” remoto:

git push REPOSITORIO_REMOTO RAMA_REMOTA

git push -u origin hotfix/issueShortName_issueID_username

Para más información: Git Workflows.

Tracking” significa: una relación entre una rama local y una rama remota. Cuando se trabaja en una rama local que rastrea otra rama, se puede correr “git pull” y “git push” sin argumentos adicionales y git sabrá qué hacer.

Sin embargo, hay que recordar que por defecto “git push” empuja todas las ramas que tienen el mismo nombre remoto. Para limitar este comportamiento sólo a la rama actual, se debe configurar la siguiente opción:

git config --global push.default tracking

Lo anterior sirve para evitar “push” accidentales a ramas a las que no se está listo para empujar aún.

¿Qué es “origin”?

Es un alias dado a la URL que apunta al repositorio remoto.

Digamos que deseamos configurar una rama remota llamada origin/master para ser la rama de rastreo de nuestra rama local llamada master:

git branch --set-upstream  master origin/master

Si mi “repositorioLocal” declara a “repositorioRemotoRepo”, entonces estamos:

  • Pulling – Jalando del “upstream” llamado “repositorioRemoto”. Esto quiere decir que “repositorioRemoto” es “upstream” para mi “repositorioLocal” y mi “repositorioLocal” es “downstream” para “repositorioRemoto”.
  • Pushing – Empujando hacia el “upstream” llamado “repositorioRemoto”.

“origin” es el nombre del repositorio remoto donde deseamos publicar nuestros “commits”. Por convención, el repositorio remoto predeterminado se llama “origin”, pero se puede trabajar con diferentes repositorios remotos al gusto (con diferentes nombres) al mismo tiempo. Para más información, por favor consulte: gitref.org

Los Repositorios Remotos de manera general se almacenan un equipo aparte o en un servidor centralizado. Sin embargo, también pueden apuntar a un repositorio en la misma máquina. No hay nada de especial en el nombre de “origin”, pero existe una convención para utilizarlo como el repositorio centralizado primario (si los hay):

git remote

origin

Desplegar información sobre el repositorio remoto llamado “origin”:

git remote show origin

Rastrear una rama remota de otra persona

git checkout -t origin/feature/issueShortname_issueID_username

El comando anterior, crea y se pasa a la rama “feature/issueShortname_issueID_username” la cual rastrea a la rama remota “origin/feature/issueShortname_issueID_username”.

Una vez que un compañero del equipo nos comparte la rama en la cual estaba trabajando, necesitamos crear una rama local que nos permita hacer cambios sobre la rama del compañero. Por lo tanto, con este tipo de seguimiento establecido es que podemos hacer cambios y luego correr “git push” empujarlos remotamente.

Al empujar use “rebase” no “merge”

git pull --rebase

Si estamos en la rama “master” entonces realiza un “git fetch origin”.

Una historia de tiempo lineal

Debido a que la fusiones de ramas son grabadas con un “merge commit“, se supone que deben ser significativas, por ejemplo, para indicar cuando un “feature” haya sido fusionado a un “branch release“. Sin embargo, durante el flujo de un día de trabajo diario regular, donde varios miembros del equipo de continuamente sincronizan desde una sola rama, la línea de tiempo se contamina con micro-fusiones innecesarias al realizar “git pull“. Por otro lado, “rebase” asegura que los “commits” son siempre re-aplicados para mantener una historia de tiempo lineal.

Es posible configurar ciertas ramas para que siempre hagan lo anterior sin necesidad de usar la opción –rebase. Hacer que “git pull” en “master” siempre use “rebase“.

git config branch.master.rebase true

Rebase automático para todas las ramas rastreadas

Es posible configurar esta opción de manera global, para cada nueva rama rastreada:

git config --global branch.autosetuprebase always

Watch your Sass!

Los navegadores Web sí entienden bien los archivos CSS, sin embargo no entienden los archivos Sass. Por esta razón, los archivos Saas necesitan ser procesados y transformados en archivos CSS. Con Sass es posible gestionar muchos archivos y combinarlos todos en un sólo archivo CSS.

Automatización de Saas para Ionic

Para dar salida de forma automática a un archivo CSS que el navegador Web sí pueda entender hay que “mirar” los archivos Sass de la aplicación para conocer si hay cambios. Por lo tanto, cada vez que se guardan cambios en un archivo Sass, también se reconstruye de manera automática el archivo CSS.

touch www/lib/ionic/scss/app.scss

sass --watch www/lib/ionic/scss/app.scss:www/css/app.css

Variables Sass

Hay que pensar en las variables como en una forma de almacenar información que se desea reusar a lo largo de la hoja de estilos. Pueden almacenar cosas como: colores, “font stacks”, o cualquier valor CSS que se necesite reutilizar.

Para más información, por favor consulte:

Para instalar Saas hay que tener instalado Ruby

sudo su

\curl -sSL https://get.rvm.io | bash -s stable --rails

La barra invertida antes del comando asegura que estamos usando el comando curl y no un alias o versión alterada.

La opción -s indica que la utilidad debe funcionar en modo silencioso, la opción -S anula esto para permitir el aviso de errores sólo en caso de que algo falle. La opción -L le dice a curl que sí siga las redirecciones.

Entonces el script se canaliza hacia bash para su procesamiento. La opción -s indica que la entrada proviene de “standard in”, además se especifica que queremos que la última versión estable de RVM junto a la última versión estable de Rails, que también se trae el Ruby adecuado.

Para comenzar a utilizar RVM

Se necesita ejecutar en todas las cosolas abiertas:

source /usr/local/rvm/scripts/rvm

which rvm

rvm -v

rvm 1.25.25 (stable)...[https://rvm.io/]

Para comenzar a utilizar Rails

rails new PROJECT_DIR

Para más información, por favor consulte:

Instalar Sass

sudo gem install sass

sudo gem update sass

which sass

sass -v
Sass 3.3.7 (Maptastic Maple)

Para más información, por favor consulte:

Los bloques fundamentales para la construcción de la Web

Polymer es una librería que utiliza las últimas tecnologías Web para permitir la creación de elementos HTML personalizados. Con Polymer es posible construir cualquier cosa, desde un botón hasta una aplicación como un elemento encapsulado y re-usable que también pueda funcionar tanto en el escritorio como en dispositivos móviles.

Por favor consulte:

Los elementos son muy declarativos

Son descritivos y semánticos por si mismos. Además son transparentes para el usario, ya que suceden aunque no sea necesario conocer por qué suceden.

Por ejempo, el elemento “select” es un buen ejemplo de un componente nativo:

<select>

. . <option>Small</option>

. . <option>Medium</option>

. . <option>Large</option>

<select>

se puede notar que dentro del elemento se permite declarar un conjunto de elementos conocidos como “option“.

Los elementos son configurables

Mediante los atributos:

<select id=”component“>

. . <option disabled>Small</option>

. . <option selected>Medium</option>

. . <option>Large</option>

<select>

y el navegador sabe como “renderearlos”, no hay scripting.

Los elementos tienen comportamientos

también podemos cambiar la forma en que el “select” se comporta e interactúa, una vez más, no sabemos cómo pasa, pero pasa:

<select size=”4″ multiple>

. . <option>Black</option>

. . <option>White</option>

. . <option>Red</option>

. . <option>Green</option>

. . <option>Blue</option>

<select>

Los elementos pueden ser componibles

Se pueden agrupar, por ejemplo, mediante el elemento “optgroup” que además también es configurable a través de sus atributos:

<select>

. . <optgroup label=”RGB”>

. . . . <option>Red</option>

. . . . <option>Green</option>

. . . . <option>Blue</option>

. . </optgroup>

. . <optgroup label=”CMYK”>

. . . . <option>Cyan</option>

. . . . <option>Magenta</option>

. . . . <option>Yellow</option>

. . . . <option>Key – Black</option>

. . </optgroup>

<select>

Nota: La “K” en CMYK es sinónimo de clave porque en la impresión a cuatro colores, las placas de impresión: cian, magenta y amarillo son cuidadosamente alineadas(keyed), con la clave de la placa negra.

Los elementos pueden estar dentro de un contexto

Por ejemplo, podemos tomar el elemento “select” dentro del contexto de un elemento “form”:

<form>

. . <select name=”size”>

. . . . <option value=”s”>Small</option>

. . . . <option value=”m”>Medium</option>

. . . . <option value=”l”>Large</option>

. . </select>

</form>

en el contexto anterior, el navegador conoce:

  • Cómo enviar el formulario.
  • Los valores de las variables o llaves.

Los elementos pueden ser componibles en diferentes contextos.

Los elementos tienen APIs

Los elementos reaccionan a eventos:

select.onchange = function() {
    var idx = this.selectedIndex;
    var val = this.options[idx].value;
};

Por ejemplo, el componente TAB

Es uno de los componente con más implementaciones, todo el mundo lo desarrolla diferente y todos los desarrolladores tienen que aprender cómo usarlo. Sin embargo, esto no debería ser así. Sólo debe ser:

  • Declarativo.
  • Configurable.
  • Componible.

de esta manera es transparente para el usuario. Por ejemplo:

<x-tabs>

. . <x-tab>Tab 1</x-tab>

. . <x-tab>Tab 2</x-tab>

. . <x-tab>Tab 3</x-tab>

</x-tabs>

La declaración del componente anterior es super descriptiva, con tan sólo ver el código/”markup” podemos deducir qué es lo que posiblemente hace.

Veamos el ejemplo de un elemento Google Map

¿Quién puede deducir lo que el siguiente código/”markup” hace?

<google-map></google-map>

exacto, presenta un mapa (aunque por debajo use un API de mapas). Por lo tanto, como usuario, no hay que conocer las complejidades del API, ni preocuparnos por cargar librerías dependientes para lograrlo.

Las mismas reglas aplican para los elementos creados al gusto, por ejemplo, es posible configurar el elemento mediante sus atributos:

<google-map lat=”37.774″ lng=”-122.41942″ zoom=”15″></google-map>

también es componible:

<google-map lat=”37.774″ lng=”-122.41942″>

. . <google-map-marker lat=”37.78″ lng=”-122.41″ title=”Home” draggable=”true”>

. . <google-map-marker lat=”37.779″ lng=”-122.3892″ title=”Go Giants!” icon=”baseball.png”>

</google-map>

en el caso anterior, dentro del elemento “google-map” se pueden agrupar elementos “google-map-markers” que a la vez también se pueden configurar a través de sus atributos. Por otro lado, permite alterar el comportamiento mediante el el uso de “shrinktomarkers” para poder centrar el mapa de acuerdo a los marcadores existentes y presentados en la pantalla:

<google-map lat=”37.774″ lng=”-122.41942″ shrinktomarkers>

. . <google-map-marker lat=”37.78″ lng=”-122.41″ title=”Home” draggable=”true”>

. . <google-map-marker lat=”37.779″ lng=”-122.3892″ title=”Go Giants!” icon=”baseball.png”>

</google-map>

Los “Web Components” son:

  • Declarativos: Se puede usar el famoso HTML para tomar ventaja en su desarrollo y distribución.
  • Componibles: En diferentes contextos se puede tomar un componente de aquí y otro de allá para ser mezclados y ofrecer una nueva aplicación. Esto quiere decir que no se re-inventa la rueda, más bien se re-utiliza, transforma y extiende.
  • Determinados/Scoping: Por elemento CSS / DOM / APIs. Es posible encontrar un componente con usa sección de CSS. Además permite encapsulación de CSS y DOM. Además de la ventaja de contar con un API por componente.

polymer

Los “Web Components” abren con llave:

  • Nuevas maneras de usar elementos HTML: Emerge un area declarativa para los APIs, librerías y servicios existentes.
  • La interoperabilidad: Todos los frameworks, las librerías y los desarrolladores entienden y hablan HTML/DOM. No importa su implementacion, lo importante es como los elementos se componen y comunican entre si, todo es HTML/DOM, las cosas que ya conocemos. Por lo tanto se puede usar sobre ellos: desde jQuery hasta detectores de eventos.
  • El soporte de DevTools: Las herramientas conocen DOM. Por lo tanto van a permitir inspeccionar, consultar y aplicar “live coding” para transformar sus atributos o estilos.
  • Extensibilidad: Puede heredar el UI y/o API de otro elemento. por ejemplo, para el componente “google-map” parece necesario extender su funcionalidad para que permita la inclusión y presentación de marcadores sobre el mapa: “<google-map-marker>“.

<all-done-cats>

Ionic – HTML mejorado para Apps

A continuación una lista de los frameworks que parecen ser más efectivos para el desarrollo de proyectos para dispositivos móviles o que requieran “Responsive Web Design”. También es importante conocer si en el Proyecto se ocupan características como “semantic templates” o “data binding”:

Cabe mencionar que existen opciones interesantes como Mustache, Handlebars y Underscore/Lodash.

Ionic tiene integración con Cordova

Un aspecto interesante es la integración de Ionic con Cordova. De hecho, el CLI de Ionic está construido sobre el CLI de Cordova.

Instalar Ionic con npm

sudo npm install -g gulp ionic

Crear un proyecto base (seed project)

ionic start myApp

Agregar una plataforma

cd myApp

ionic platform android

Correr App en el Emulador

ionic build android

ionic emulate android

Correr App en el Dispositivo conectado por USB

ionic run android

ionic-emulate-android

Creación de Apps con Cordova (AKA PhoneGap)

PhoneGap es más que un framework de código abierto, también es una herramienta y una solución que permite crear un sólo código basado en HTML5, CS3 y JavaScript. Además permite que ese código pueda ser compilado en el respectivo formato nativo de más de un dispositivo requerido (Servicio PhoneGap Build).

API de JavaScript y Código Nativo

El Framework Apache Cordava mediante un API comunica el código HTML5, CS3 y JavaScript con el código nativo.

cordova-logo

Cordova ofrece a través de JavaScript la comunicación con las distintas posibilidades y características que ofrecen los diversos dispositivos móviles, mencionando algunos, por ejemplo acceder: al acelerómetro, al GPS, a la cámara de fotos o los contactos.

PhoneGap Build – Sistema de Compilación

Cuando se tiene el código listo se puede usar PhoneGap Build para crear los archivos de istalación para los dispositivos o aparatos requeridos.

Expansión de PhoneGap

PhoneGap permite trabajar con HTML5, por ejemplo, con CSS para controlar el tamaño de los dispositivos sobre los que se va a trabajar. También permite conectar con otros frameworks como Ionic, Angular, Lumx, Amber, entre otros. Esto para lograr aplicaciones más interactivas que además lucen y se sienten igual para cualquier dispositivo disponible.

También es posible usar Plugins propios o de terceros, esto sirve para empujar el framework de PhoneGap con soluciones y mejoras más específicas por proyecto.

Las distintas características soportadas:

Tabla de compatibilidad HTML5 para los diversos dispositivos:

Por razones obvias, las aplicaciones para IOS y Android son las más apatecidos.

Documentación

Para saber si estamos en la documentación adecuada:

debemos comparar el URL de la documentación con la versión que corresponde al comando:

phonegap -v

3.4.0-0.19.21

¿Cuál es la diferencia entre Apache Cordova y PhoneGap?

PhoneGap-Cordova and what’s in a name?

PhoneGap es una distribución de Apache Cordova. Usted puede pensar en Apache Cordova como el motor que impulsa a PhoneGap, similar a la forma en que WebKit/Blink impulsa a Chrome.

“Semblance of Parity”

PhoneGap es un proyecto muy ambicioso y se basa en una gran comunidad para empujar muchas implementaciones de sistema operativo en la “semblanza de la paridad”.

Instalar Cordova

sudo npm install -g cordova

Nota: La bandera -g le dice a npm de instalar cordova de manera global.

La interfaz de línea de comandos

Crear una App

cordova create psych com.psych.app Psych
Creating a new cordova project with name "Psych" and id "com.psych.app" at location "~/Workspace/phonegap/psych"

dentro del subdirectorio “www” vive la portada de la aplicación.

cordova-create

Agregar Platformas

Todos los siguientes comandos ser ejecutados dentro del directorio del proyecto, o cualquier subdirectorio dentro de su ámbito de aplicación:

cd psych

cordova platform add android

cordova-platform-add

posible mensaje que se despliega luego de agregar una plataforma:

Creating android project...

Creating Cordova project for the Android platform:
    Path: platforms/android
    Package: com.psych.app
    Name: Psych
    Android target: android-19
...

Verficar el conjunto de plataformas actuales

cordova platforms ls

Installed platforms: android 3.4.0
Available platforms: amazon-fireos, blackberry10, firefoxos, ubuntu

Borrar una plataforma

cordova platform rm android

Sólo se pueden editar los archivos dentro del subdirectorio “www”, pero no los archivos dentro dentro de los subdirectorios “www” de “platforms”:

  • platforms/ios/www
  • platforms/android/assets/www

Control de versiones, es un hecho que hay que agregar el subdirectorio “www”, junto con el directorio “merges”, al sistema de control de versiones.

Construir la App

Por defecto, el script cordova genera un esqueleto cuya página de inicio es el archivo “www/index.html” del proyecto.

El controlador de eventos “deviceready”

El archivo “www/index.html” se puede editar cuantas veces se requiera, pero cualquier inicialización debe especificarse como parte del controlador de eventos “deviceready”, referenciado por defecto desde:

  • www/js/index.js

Construir de manera iterativa el Proyecto

cordova build

Lo anterior genera código específico de plataforma dentro del subditectorio “platforms” del proyecto.

Construir una App limitando su alcance

Es posible generar sólo para plataformas específicas, porjemplo:

cordova build android

El comando cordova build es atajo de:

cordova prepare android
cordova compile android

En el caso anterior, una vez que que se corre “prepare”, se puede usar el Apple’s Xcode SDK como una alternativa para modificar y compilar el código específico de plataforma que Cordova genera dentro de “platforms/ios”. Este mismo método se puede utilizar con los SDK de otras plataformas.

Emuladores

cordova platforms ls
id: 2 or "android-19"
     Name: Android 4.4.2
     Type: Platform
     API level: 19
     Revision: 3
     Skins: WXGA800-7in, WSVGA, WQVGA432, WXGA800, WXGA720, QVGA, WVGA854, HVGA, WQVGA400, WVGA800 (default), AndroidWearSquare, AndroidWea

Crear un Dispositivo Android Virtual – Android Virtual Device (AVD)

android create avd --name Android-4-4-2_hvga --target 19 --skin HVGA

también parece fácil crear un AVD con el comando:

android avd

android-avd

Test de la App en un Dispositivo Android Virtual

El SDK para plataformas móviles a menudo viene equipado con emuladores que ejecutan una imagenes de dispositivos, de modo que es posible lanzar la aplicación en la pantalla principal para interactuar con muchas de las características de la plataforma.

cordova-emulate-android

Ejecutar el siguiente comando para reconstruir la aplicación y verla dentro de emulador de una plataforma específico:

cordova emulate android

Test de la App en un AVD específico

Primero debe ejecutar el comando:

android

para lanzar el SDK de Android, a continuación, empezar(Start) una imagen de dispositivo en particular, que iniciará en blanco de acuerdo a su comportamiento predeterminado.

por último debe ejecutar el comando:

cordova emulate android

para refrescar la imagen emulador que va a desplegar la aplicación en la pantalla principal.

Como alternativa, es posible conectar el teléfono a la computadora para probar directamente la aplicación:

cordova run android

Nota: Es posible que sea necesario habilitar la opción de “USB Debugging”:

Settings -> More -> Developer Options -> USB Debugging

Test de la App en un Servidor Web Local

cordova serve 8080

Ejecuta un Servidor Web Local para “www/assets”. El puerto por defecto es 8000.

El Proyecto se puede acceder por Web desde:

http://localhost:8080/android/www/

Desarrollo en JavaScript con Sublime Text

Aunque ahora me considero un fiel usuario del editor Atom y todas sus bondades:

Configurar Sublime Text

‘Preferences’ -> ‘Settings – User’:

{
	"color_scheme": "Packages/Color Scheme - Default/Monokai.tmTheme",
	"default_line_ending": "unix",
	"ensure_newline_at_eof_on_save": true,
	"fallback_encoding": "UTF-8",
	"font_size": 11.0,
	"ignored_packages":
	[
		"Vintage",
		"Goto Drupal API",
		"Drupal Snippets",
		"Drupal Project Autocomplete"
	],
	"rulers":
	[
		80
	],
	"shift_tab_unindent": true,
	"soda_classic_tabs": true,
	"soda_folder_icons": true,
	"tab_size": 4,
	"theme": "Soda Dark.sublime-theme",
	"translate_tabs_to_spaces": true,
	"trim_automatic_white_space": true,
	"trim_trailing_white_space_on_save": true,
	"use_tab_stops": true
}

Instalar CSSLint y JSHint mediante npm

sudo npm install -g csslint
sudo npm install -g jshint
sudo npm install -g jslint

which csslint jshint jslint

/usr/local/bin/csslint
/usr/local/bin/jshint
/usr/local/bin/jslint
ls -la /usr/local/bin/*int*
/usr/local/bin/csslint -> ../lib/node_modules/csslint/cli.js
/usr/local/bin/jshint -> ../lib/node_modules/jshint/bin/jshint
/usr/local/bin/jslint -> ../lib/node_modules/jslint/bin/jslint.js

SublimeLinter y HTML-CSS-JS Prettify

Luego de instalar a Sublime Text los dos paquetes anteriores:

‘Preferences’ -> ‘Package Settings’ -> ‘SublimeLinter’ -> ‘Settings – User’:

{
    "sublimelinter": "load-save",
    "javascript_linter": "jshint",
    "jshint_options":
    {
        "evil": true,
        "regexdash": true,
        "browser": true,
        "wsh": true,
        "trailing": true,
        "sub": true
    }
}

JSHint Fork

Aunque el código de JSLint es muy agradable a la vista, mucha gente odia lo estricto que es.

Algunas de las cosas, por ejemplo, de espacios en blanco que JSLint hace cumplir, no son necesariamente mal usadas, además están fuera de sincronía con algunas convenciones de espacios en blanco bastante estándar para otros lenguajes. Por lo tanto, como un desarrollador puede estar creando en varios lenguajes durante el día, y al mismo tiempo trabajando cruzado con los demás miembros del equipo, parace que JSHint es un buen equilibrio para producir código JavaScript elegante y también agradable de leer. Dependiendo de los requerimientos del proyecto también es muy fácil decirle a Sublime Text que use JSLint en lugar de JSHint.

Las razones detrás de la bifurcación de JSLint hacia JSHint explican muy bien la razón de existir de JSHint: