<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vinco Orbis Proyectos, S.A. de C.V.</title>
	<atom:link href="http://vincoorbis.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://vincoorbis.com</link>
	<description>Desarrollo Web + SEO + App</description>
	<lastBuildDate>Thu, 03 May 2012 21:41:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>El diablo está en los detalles</title>
		<link>http://vincoorbis.com/el-diablo-esta-en-los-detalles/</link>
		<comments>http://vincoorbis.com/el-diablo-esta-en-los-detalles/#comments</comments>
		<pubDate>Thu, 03 May 2012 21:41:20 +0000</pubDate>
		<dc:creator>ao</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1583</guid>
		<description><![CDATA[<p>La complejidad de la realidad es innegable, la cantidad de estímulos disponibles al ser, innumerables.</p>
<p>De hecho, el cerebro humano es un filtro negativo que se dedica a descartar información, de nada sirve el canto del pájaro cuando venimos manejando, del mismo modo que es innecesario pensar en el funcionamiento del motor de combustión interna para que este funcione. Pero si tuvieramos que analizar un accidente sucedido en ese preciso instante, necesitariamos saber si el canto del pájaro distrajo al conductor, o si el motor falló durante alguno de sus ciclos.</p>
<p>El problema es que no siempre sabemos cuando van a fallar las cosas y monitorearlo todo todo el tiempo no es rentable. Asi que tenemos que escoger y tenemos que excluir. Cuales son los detalles relevantes y cuales no.</p>
<p>Lo mismo sucede cuando planeamos un proyecto, nuestro cerebro solo ve pequeñas porciones ... <a href="http://vincoorbis.com/el-diablo-esta-en-los-detalles/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>La complejidad de la realidad es innegable, la cantidad de estímulos disponibles al ser, innumerables.</p>
<p>De hecho, el cerebro humano es un filtro negativo que se dedica a descartar información, de nada sirve el canto del pájaro cuando venimos manejando, del mismo modo que es innecesario pensar en el funcionamiento del motor de combustión interna para que este funcione. Pero si tuvieramos que analizar un accidente sucedido en ese preciso instante, necesitariamos saber si el canto del pájaro distrajo al conductor, o si el motor falló durante alguno de sus ciclos.</p>
<p>El problema es que no siempre sabemos cuando van a fallar las cosas y monitorearlo todo todo el tiempo no es rentable. Asi que tenemos que escoger y tenemos que excluir. Cuales son los detalles relevantes y cuales no.</p>
<p>Lo mismo sucede cuando planeamos un proyecto, nuestro cerebro solo ve pequeñas porciones de la realidad. Si quisieramos construir un avión, la primera imágen en nuestra mente es el avión completo, no cada uno de sus tornillos.</p>
<p>Es por eso que a la hora de planear un proyecto es muy importante tomarse el tiempo de planear y describir cada uno de los tornillos de avión.</p>
<p>En Vinco Orbis creemos que la planeación adecuada es el secreto del éxito.</p>
<p>Pero sabemos que existen variables incontrolables, es imposible saber si justo al momento de comenzar a cosntruir un avión, la competencia va a construir un submarino utilizando justo el mismo tipo de tornillos provocando una escases que retrase el proyecto.</p>
<p>Finalmente estos dos elementos, lo que creíamos que iba a pasar, y lo que realmente pasó solo existen en el futuro donde podrán ser comparados.</p>
<p>En Vinco Orbis estamos trabajando para que <a href="http://manoderecha.mx">manoderecha</a>, nuestro software de administración de proyectos, sirva para tener una idea clara de que es lo que pensamos será el proyecto, y que es lo que realmente fue el proyecto. Así con cada ciclo de Planeación/Realización intentamos cerrar la brecha entre la realidad como quisieramos que fuera y la realidad como es.</p>
<p>En Vinco Orbis ponemos a su disposición las herramientas, usted decide si quiere seguir trabajando a ciegas, o si quiere empezar a eficientar sus procesos a partir de hoy mismo.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/el-diablo-esta-en-los-detalles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Crear un archivo CSV con groovy</title>
		<link>http://vincoorbis.com/crear-un-archivo-csv-con-groovy/</link>
		<comments>http://vincoorbis.com/crear-un-archivo-csv-con-groovy/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 04:24:41 +0000</pubDate>
		<dc:creator>Edgar</dc:creator>
				<category><![CDATA[Desarrollo en Grails]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1568</guid>
		<description><![CDATA[<p>Para este ejemplo, supongamos que tenemos un Array de Arrays como datos.</p>


def animales = [
 [id:'1',color:'gris',animal:'Elefante',descripcion:'El Elefante es &#34;gris&#34;'],
 [id:'2',color:'verde',animal:'tortuga',descripcion:'Hay tortugas &#34;verdes&#34;'],
 [id:'3',color:'amarillo',animal:'Canario',descripcion:'El canario es &#34;Amarillo&#34;'],]

<p>A continuación, podemos crear nuestro archivo CSV de la siguiente manera:</p>


def out = new File('C:/Users/ubicacion/animals.csv')
 animales.each {
 def row = [it.id, it.color, it.animal, it.descripcion]
 out.append row.join(',')
 out.append '\n'
 }

<p>El resultado del archivo creado es el siguiente:</p>
<p><a href="http://vincoorbis.com/wp-content/uploads/2012/04/animal1.jpg"></a></p>
]]></description>
			<content:encoded><![CDATA[<p>Para este ejemplo, supongamos que tenemos un Array de Arrays como datos.</p>
<pre class="brush: java; title: ; notranslate">

def animales = [
 [id:'1',color:'gris',animal:'Elefante',descripcion:'El Elefante es &quot;gris&quot;'],
 [id:'2',color:'verde',animal:'tortuga',descripcion:'Hay tortugas &quot;verdes&quot;'],
 [id:'3',color:'amarillo',animal:'Canario',descripcion:'El canario es &quot;Amarillo&quot;'],]
</pre>
<p>A continuación, podemos crear nuestro archivo CSV de la siguiente manera:</p>
<pre class="brush: java; title: ; notranslate">

def out = new File('C:/Users/ubicacion/animals.csv')
 animales.each {
 def row = [it.id, it.color, it.animal, it.descripcion]
 out.append row.join(',')
 out.append '\n'
 }
</pre>
<p>El resultado del archivo creado es el siguiente:</p>
<p><a href="http://vincoorbis.com/wp-content/uploads/2012/04/animal1.jpg"><img class="alignleft size-medium wp-image-1576" title="animal" src="http://vincoorbis.com/wp-content/uploads/2012/04/animal1-300x88.jpg" alt="" width="300" height="88" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/crear-un-archivo-csv-con-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>¿Usas EGit y tienes problemas? Prueba con Git Bash</title>
		<link>http://vincoorbis.com/usas-egit-y-tienes-problemas-prueba-con-git-bash/</link>
		<comments>http://vincoorbis.com/usas-egit-y-tienes-problemas-prueba-con-git-bash/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 14:50:51 +0000</pubDate>
		<dc:creator>Rafael Vargas</dc:creator>
				<category><![CDATA[Desarrollo y Programación]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1554</guid>
		<description><![CDATA[<p>Ayer me encontraba con Francisco <em>pulleando</em> cambios a su repositorio local, cuando de pronto apareció un <em>wild</em> EGit que no nos lo permitió.</p>
<p>¿Y por qué no nos dejaba? Por el mensaje de error que nos devolvió EGit, quien sabe. Simplemente EGit nos dijo que no podíamos y ya. Lo intentamos de nuevo sin hacer ningún cambio y la respuesta que nos dio ahora fue que ya estaba todo al día. Mentiroso.</p>
<p>Usando Git Bash encontramos que no nos dejaba hacer pull tranquilamente porque un archivo en especifico tenia cambios y requería de un commit. Pero si nos hubiéramos quedado usando Eit, quizá nos hubiera llevado mucho mas tiempo en averiguarlo.</p>
<p>http://msysgit.github.com/</p>
]]></description>
			<content:encoded><![CDATA[<p>Ayer me encontraba con Francisco <em>pulleando</em> cambios a su repositorio local, cuando de pronto apareció un <em>wild</em> EGit que no nos lo permitió.</p>
<p>¿Y por qué no nos dejaba? Por el mensaje de error que nos devolvió EGit, quien sabe. Simplemente EGit nos dijo que no podíamos y ya. Lo intentamos de nuevo sin hacer ningún cambio y la respuesta que nos dio ahora fue que ya estaba todo al día. Mentiroso.</p>
<p>Usando Git Bash encontramos que no nos dejaba hacer pull tranquilamente porque un archivo en especifico tenia cambios y requería de un commit. Pero si nos hubiéramos quedado usando Eit, quizá nos hubiera llevado mucho mas tiempo en averiguarlo.</p>
<p>http://msysgit.github.com/</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/usas-egit-y-tienes-problemas-prueba-con-git-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google &#8220;Webspam Algorithm Update&#8221; y algunas precauciones SEO</title>
		<link>http://vincoorbis.com/google-webspam-algorithm-update-y-algunas-precauciones-seo/</link>
		<comments>http://vincoorbis.com/google-webspam-algorithm-update-y-algunas-precauciones-seo/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 06:22:17 +0000</pubDate>
		<dc:creator>Christian Aranda</dc:creator>
				<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Optimización de Sitios para resultados en Buscadores]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Google Search]]></category>
		<category><![CDATA[Over Optimization Penalty]]></category>
		<category><![CDATA[Webspam Algorithm Update]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1547</guid>
		<description><![CDATA[<p><a title="Matt Cutts" href="http://www.mattcutts.com/blog/" target="_blank">Matt Cutts</a>, el jefe y gurú espiritual del equipo de anti-Spam de Google comentó en el pasado <a title="SXSW" href="http://sxsw.com/" target="_blank">SXSW </a>que Google no tardaba en soltar una actualización en su algoritmo específicamente enfocada a detectar sitios que anden pasándose de listos exagerando en la aplicación de SEO, es decir, &#8220;Sobre optimizando&#8221;.</p>
<p><a title="Another step to reward high-quality sites &#124; Inside Search Blog by Google" href="http://insidesearch.blogspot.mx/2012/04/another-step-to-reward-high-quality.html" target="_blank">Aquí una nota al respecto dentro del blog oficial de Google Search</a></p>
<p>La idea detrás de todo esto es que los que hacemos SEO no nos pasemos de lanza, que quienes hacen SEO al mero estilo rudo y sucio no pasen por encima de los que tratamos de hacer las cosas al mero estilo Jedi.</p>
<p>Cómo este tema es muy nuevo, es cosa de esta última semana y unos día antes, estuve leyendo ... <a href="http://vincoorbis.com/google-webspam-algorithm-update-y-algunas-precauciones-seo/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a title="Matt Cutts" href="http://www.mattcutts.com/blog/" target="_blank">Matt Cutts</a>, el jefe y gurú espiritual del equipo de anti-Spam de Google comentó en el pasado <a title="SXSW" href="http://sxsw.com/" target="_blank">SXSW </a>que Google no tardaba en soltar una actualización en su algoritmo específicamente enfocada a detectar sitios que anden pasándose de listos exagerando en la aplicación de SEO, es decir, &#8220;Sobre optimizando&#8221;.</p>
<p><a title="Another step to reward high-quality sites | Inside Search Blog by Google" href="http://insidesearch.blogspot.mx/2012/04/another-step-to-reward-high-quality.html" target="_blank">Aquí una nota al respecto dentro del blog oficial de Google Search</a></p>
<p>La idea detrás de todo esto es que los que hacemos SEO no nos pasemos de lanza, que quienes hacen SEO al mero estilo rudo y sucio no pasen por encima de los que tratamos de hacer las cosas al mero estilo Jedi.</p>
<p>Cómo este tema es muy nuevo, es cosa de esta última semana y unos día antes, estuve leyendo un par de artículos y notas al respecto, en uno encontré <a title="6 changes Every SEO Should Make BEFORE the Over-Optimization Penalty Hits" href="http://www.seomoz.org/blog/6-changes-every-seo-should-make-before-the-over-optimization-penalty-hits-whiteboard-friday" target="_blank">algo muy interesante</a> que he de compartir con ustedes los fans e interesados en SEO con la intención de que diosito Google no les penalice sus sitios.</p>
<p>En este artículo (que incluye video muy cool) el presentador menciona seis cambios que todo SEO deberá considerar, aunque no se están manejando como absolutos ni determinantes sino más como &#8220;lo más super probable, casi segurisísimo&#8221; estoy convencido personalmente que no andan nada errados.</p>
<p>Matt Cutts siempre deja muy claro que la intención es hacer a Google cada vez más humano, si esto sigue el camino que hasta ahora lleva, los siguientes 6 temas de SEO deberán ser tomados en cuenta para no entrar en listas negras, cajas de arena, malasfamas y letras escarlatas:</p>
<ol>
<li><strong>Títulos de página que huelen a &#8220;Spam and  Keyword stuffing&#8221;</strong> es decir que no se &#8220;sientan&#8221; escritos por humanos. La idea es que se lean naturales y no solamente enfocados a empujar keywords.</li>
<li><strong>Links internos que manipulan y no tienen sentido</strong> como usar el mismo texto ancla en repetidas ocasiones dentro de la misma página para enlazar a su vez una misma página destino.</li>
<li><strong>Footers retacados de links</strong> inútiles.</li>
<li><strong>Bloques de texto sin sentido</strong> ni causa enfocados a máquinas de búsqueda.</li>
<li><strong>Backlinks de malas fuentes y/o producto de prácticas de dudosa reputación. </strong>Más claro ni el agua del grifo; si has comprado links en sitios que sólo se dedican a eso, hacer comment spam, comprado presencia directorios sin contenido real que piden intercambio de enlaces, sitios de &#8220;artículos&#8221; etcétera, en pocas palabras si has hecho <a title="SEO | White Hat Vs. Black Hat" href="http://vincoorbis.com/seo-white-hat-black-hat/" target="_blank">black hat</a> backlinking ,  posiblemente estarás en aprietos con papi Google. Esta bronca quizá es de las más complicadas de resolver, pero puedes comenzar con remover todos tus links a esos sitios horrendos e ir procurando la extinción de estos.</li>
<li><strong>Tener varias páginas con mismo contenido y keywords muy similares </strong>con la intención de atrapar más tráfico con distintas keywords. Fácil, y esto va &#8220;junto con pegado&#8221; al punto numero 1 de esta lista, el reto es aplicar un poco más de creatividad y trabajar menos como animales, aunque tome más tiempo pero se pueden crear títulos y contenidos que atacan hasta tres o cuatro distintas keywords siempre y cuando se tome uno el tiempo para hacer el &#8220;mix&#8221; correcto que no se lea escrito por un pollo.</li>
</ol>
<p>Estas son las principales recomendaciones o pronósticos SEO con relación a la actualización del algoritmo de Google que pretende penalizar sitios &#8220;pasados de listos en SEO&#8221;.</p>
<p>Probablemente el próximo post de mi parte trate este mismo asunto, efectos en los buscadores así como las primeras impresiones de algunos SEOs.</p>
<p>Espero les resulte interesante y mejor aún, útil.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/google-webspam-algorithm-update-y-algunas-precauciones-seo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aplicación Web profesional en minutos: Grails + Twitter Bootstrap + CloudFront + Jelastic.</title>
		<link>http://vincoorbis.com/aplicacion-web-profesional-en-minutos/</link>
		<comments>http://vincoorbis.com/aplicacion-web-profesional-en-minutos/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 02:41:14 +0000</pubDate>
		<dc:creator>jl</dc:creator>
				<category><![CDATA[Blogs y Micrositios]]></category>
		<category><![CDATA[Desarrollo en Grails]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[Cloudfront]]></category>
		<category><![CDATA[GoDaddy]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[Jelastic]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1427</guid>
		<description><![CDATA[<p>Después de muchos años de recibir solicitudes de cotizaciones, requerimientos y múltiples consultas de distintos clientes, ya no es extraño recibir solicitudes como esta:</p>
<p>Necesitamos una aplicación web de alta disponibilidad, con un bajo tiempo de carga, que tenga su dominio y otros dominios que apunten al principal,  que tenga un buen diseño, que se vea bien en todos los browsers y en dispositivos móviles, que pueda ser escalable y que esté alojada en servidores en Estados Unidos. Por cierto, por políticas de la empresa, debe ser programada en Java. La necesitamos para mañana y no contamos con mucho presupuesto.</p>
<p>Un verdadero poema a la carcajada, sin embargo, la solicitud es real, lo que nos hace pensar: <strong>¿Es realmente posible?</strong></p>
<p>¡Claro! En la actualidad existen innumerables frameworks que combinan toda clase de tecnologías que nos ayudan a crear aplicaciones web de todo tipo sin necesidad de ... <a href="http://vincoorbis.com/aplicacion-web-profesional-en-minutos/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Después de muchos años de recibir solicitudes de cotizaciones, requerimientos y múltiples consultas de distintos clientes, ya no es extraño recibir solicitudes como esta:</p>
<blockquote><p>Necesitamos una aplicación web de alta disponibilidad, con un bajo tiempo de carga, que tenga su dominio y otros dominios que apunten al principal,  que tenga un buen diseño, que se vea bien en todos los browsers y en dispositivos móviles, que pueda ser escalable y que esté alojada en servidores en Estados Unidos. Por cierto, por políticas de la empresa, debe ser programada en Java. La necesitamos para mañana y no contamos con mucho presupuesto.</p></blockquote>
<p>Un verdadero poema a la carcajada, sin embargo, la solicitud es real, lo que nos hace pensar: <strong>¿Es realmente posible?</strong></p>
<p>¡Claro! En la actualidad existen innumerables frameworks que combinan toda clase de tecnologías que nos ayudan a crear aplicaciones web de todo tipo sin necesidad de volver a inventar la rueda.</p>
<p>A continuación, describiré como crear una aplicación web utilizando <a title="Grails - The search is over." href="http://grails.org/" target="_blank">Grails </a>como framework de desarrollo, comprar un <a title=" 	Domain Names, Web Hosting and SSL Certificates - Go Daddy" href="http://www.godaddy.com/" target="_blank">dominio</a>, un repositorio de contenido en <a title="Amazon CloudFront" href="http://aws.amazon.com/es/cloudfront/" target="_blank">Amazon</a>, y una arquitectura completa con balanceador de carga, cluster y base de datos en <a title="Jelastic — Top Java Host, Rock-Solid Java in the Cloud, Java Server Hosting, Java Cloud Computing" href="http://jelastic.com/" target="_blank">Jelastic</a>. Utilizaremos <a title="Twitter Bootstrap" href="http://twitter.github.com/bootstrap/" target="_blank">twitter bootstrap</a> para el front-end y además podremos cambiarlo a nuestro <a title="Less · Twitter Bootstrap" href="http://twitter.github.com/bootstrap/less.html" target="_blank">antojo</a>. Todo esto, en no más de 120 minutos, lo que nos dará como resultado una aplicación robusta, de alta disponibilidad, con un diseño estándar y funcional. Además, para este ejemplo únicamente compraremos el dominio, utilizando las opciones y servicios gratuitos existentes para alojamiento y servidor de aplicaciones.</p>
<p><strong>No es la intención de este post ahondar en el dominio de cada una de las tecnologías</strong>, así que procuraré describir los pasos más comunes, si su intención es dominar Grails o aprender groovy, pueden comenzar por <a title="Grails - The search is over." href="http://grails.org/" target="_blank">acá</a>.</p>
<p>Las herramientas pre-instaladas que estaré utilizando son:</p>
<p><a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u25-download-346242.html">java </a>version &#8220;1.6.0_25&#8243;<br />
<a href="http://www.springsource.com/developer/sts"> SpringSource Tool Suite</a> Version: 2.9.1.RELEASE<br />
<a href="http://grails.org"> Grails</a>™ 2.0.3</p>
<p>Todo bajo un ambiente Windows 7  Home Premium con Service Pack 1</p>
<p><strong>CREAR LA APLICACIÓN:</strong></p>
<p>Utilizando STS creamos un proyecto nuevo Grails, para hacer esto podemos hacerlo desde el menú de la aplicación o directamente utilizando el atajo:</p>
<pre class="brush: bash; title: ; notranslate">Shift + Alt + N</pre>
<div id="attachment_1471" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/new-grails-project.png"><img class="size-full wp-image-1471" title="new-grails-project" src="http://vincoorbis.com/wp-content/uploads/2012/04/new-grails-project.png" alt="Nuevo Proyecto Grails" width="600" height="300" /></a><p class="wp-caption-text">Creamos un nuevo proyecto Grails</p></div>
<p>Seleccionamos <strong>Grails Project</strong></p>
<p>Elegimos un <strong>nombre</strong> para el proyecto</p>
<p>Elegimos utilizar usar especificaciones de proyecto y buscamos nuestra instalación de <strong>Grails 2.0.3</strong></p>
<div id="attachment_1472" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/grails-project-name.png"><img class="size-full wp-image-1472" title="grails-project-name" src="http://vincoorbis.com/wp-content/uploads/2012/04/grails-project-name.png" alt="Elegimos un nombre de proyecto" width="600" height="300" /></a><p class="wp-caption-text">Eleginos un nombre para el proyecto y una versión de instalación de Grails</p></div>
<p>Si no tenemos definida la instalación de Grails 2.03, seleccionamos &#8220;Configure Grails installations&#8221; y la agregamos a la lista de definiciones nuestra instalación previa de Grails.</p>
<div id="attachment_1476" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/grails-installations.png"><img class="size-full wp-image-1476" title="grails-installations" src="http://vincoorbis.com/wp-content/uploads/2012/04/grails-installations.png" alt="Instalación Específica de Grails" width="600" height="300" /></a><p class="wp-caption-text">Elegimos una instalación específica de Grails</p></div>
<p>Instalamos el plugin <a title="Plugin Twitter Bootstrap CSS framework resource files" href="http://grails.org/plugin/twitter-bootstrap">Twitter Bootstrap CSS framework resource files</a>. Este plugin nos permitirá utilizar el bootstrap de Twitter y nos incluirá en nuestra aplicación los archivos necesarios para poder utilizarlo.</p>
<p>Para hacerlo de forma más rápida utilizamos la consola de grails dentro del STS:</p>
<pre class="brush: bash; title: ; notranslate">Ctrl + Shift + Alt + g</pre>
<p>Instalamos el plugin:</p>
<pre class="brush: bash; title: ; notranslate">install-plugin twitter-bootstrap</pre>
<p>Nos aseguramos que estamos instalando el plugin en el proyecto que deseamos</p>
<div id="attachment_1478" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/install-plugin.png"><img class="size-full wp-image-1478" title="install-plugin" src="http://vincoorbis.com/wp-content/uploads/2012/04/install-plugin.png" alt="Instalar plugin twitter bootstrap" width="600" height="300" /></a><p class="wp-caption-text">Instalar plugin twitter bootstrap en nuestro proyecto</p></div>
<p style="text-align: left;">Instalamos el plugin <a href="http://grails.org/plugin/less-resources">LESS files resource mapper</a>. Este plugin nos permitirá customizar el bootstrap de twitter a nuestro antojo.</p>
<p style="text-align: left;">Para instalarlo utilizaremos otro método, aunque podemos instalarlo igual que el anterior. En este caso agregamos al archivo BuildConfig.groovy de nuestra aplicación (conf/BuildConfig.groovy):</p>
<pre class="brush: groovy; title: ; notranslate">compile &quot;:less-resources:1.3.0.2&quot;</pre>
<p>De forma que en el archivo el bloque nos quede de la siguiente manera:</p>
<pre class="brush: groovy; title: ; notranslate">
plugins {
 runtime &quot;:hibernate:$grailsVersion&quot;
 runtime &quot;:jquery:1.7.1&quot;
 runtime &quot;:resources:1.1.6&quot;
 compile &quot;:less-resources:1.3.0.2&quot;

// Uncomment these (or add new ones) to enable additional resources capabilities
 //runtime &quot;:zipped-resources:1.0&quot;
 //runtime &quot;:cached-resources:1.0&quot;
 //runtime &quot;:yui-minify-resources:0.1.4&quot;

build &quot;:tomcat:$grailsVersion&quot;
}
</pre>
<p><strong><a id="bug1" name="Bug1"></a>*Nota:</strong> Existe un pequeño bug en el plugin less, este se presenta cuando se ejecuta la aplicación y genera un error similar a este:</p>
<pre class="brush: bash; title: ; notranslate">Message: unterminated string literal (#17749)</pre>
<p>Para corregirlo, hay que agregar <a title="Fix for Plugin Less in Windows" href="https://github.com/longwa/less-grails-plugin/commit/1825a79426e47f6083cbe91f0a2fe590b466c0a8#diff-0" target="_blank">este fix</a> a su plugin:<br />
user/.grails/2.03./projects/nombredelproyecto/plugins/less-resources-1.3.0.2</p>
<p>Instalamos el plugin  <a title="Grails scaffolding with a Twitter Bootstrap look &amp; feel" href="http://grails-twitter-bootstrap.cloudfoundry.com/" target="_blank">twitter-bootstrap-scaffolding</a>. Este plugin utilizará twitter bootstrap en todas las vistas generadas automáticamente por grails, además suplantaremos algunos archivos para darle look &amp; feel desde que corramos por primera vez nuestra aplicación.</p>
<p>Para instalarlo, nuevamente agregamos una linea  a nuestro archivo BuildConfig.groovy</p>
<pre class="brush: groovy; title: ; notranslate">runtime ':fields:1.0.1'</pre>
<p>Nuestro bloque queda así:</p>
<pre class="brush: groovy; title: ; notranslate">
plugins {
 runtime &quot;:hibernate:$grailsVersion&quot;
 runtime &quot;:jquery:1.7.1&quot;
 runtime &quot;:resources:1.1.6&quot;
 runtime ':fields:1.0.1'
 compile &quot;:less-resources:1.3.0.2&quot;

// Uncomment these (or add new ones) to enable additional resources capabilities
 //runtime &quot;:zipped-resources:1.0&quot;
 //runtime &quot;:cached-resources:1.0&quot;
 //runtime &quot;:yui-minify-resources:0.1.4&quot;

build &quot;:tomcat:$grailsVersion&quot;
}
</pre>
<p><a title="twitter-bootstrap-scaffolding" href="https://github.com/robfletcher/twitter-bootstrap-scaffolding/zipball/master">Bajamos el proyecto</a> necesario para suplantar los archivos y copiamos los siguientes en nuestro proyecto:</p>
<pre class="brush: bash; title: ; notranslate">
 src/templates/scaffolding/*
 web-app/css/scaffolding.css
 grails-app/conf/ScaffoldingResources.groovy
 grails-app/taglib/**/*
 grails-app/views/index.gsp
 grails-app/views/layouts/bootstrap.gsp
 grails-app/views/_fields/default/_field.gsp
</pre>
<p>Ejecutamos por primera vez nuestra aplicación escribiendo lo siguiente en la linea de comandos Grails de STS:</p>
<pre class="brush: bash; title: ; notranslate">run-app</pre>
<div id="attachment_1485" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/run-app.png"><img class="size-full wp-image-1485" title="run-app" src="http://vincoorbis.com/wp-content/uploads/2012/04/run-app.png" alt="Ejecutar aplicación Grails" width="600" height="300" /></a><p class="wp-caption-text">Ejecutamos por primera vez nuestra aplicación</p></div>
<p>Si todo es correcto, grails buscará todas las dependencias necesarias, instalará los plugins y arrancará nuestra aplicación en un ambiente local:</p>
<p><a href="http://localhost:8080/votamesta">http://localhost:8080/votamesta</a></p>
<p>Si la consola muestra errores de compilación o de ejecución, no se asusten, que aún no terminamos. Verifiquen que uno de los errores no sea el <a href="#Bug1">bug anteriormente comentado</a> del plugin Less. Si muestra errores de compilación de otro tipo, basta con hacer un clean de la aplicación:</p>
<pre class="brush: bash; title: ; notranslate">clean</pre>
<p>No olviden parar antes la aplicación.</p>
<p>Ahora trabajaremos un poco para que el plugin less resources y twitter scaffolding puedan convivir. Antes de continuar, detenemos nuestra aplicación.</p>
<div id="attachment_1487" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/stop-app.png"><img class="size-full wp-image-1487" title="stop-app" src="http://vincoorbis.com/wp-content/uploads/2012/04/stop-app.png" alt="Parar aplicación" width="600" height="300" /></a><p class="wp-caption-text">Parar aplicación</p></div>
<p>Editamos el archivo conf/ScaffoldingResources.groovy de manera que queda de la siguiente forma:</p>
<pre class="brush: groovy; title: ; notranslate">
modules = {
scaffolding {
     resource url: [dir: 'less', file: 'custom-bootstrap.less'], attrs:[rel: &quot;stylesheet/less&quot;, type:'css']
     resource url:[plugin: 'twitter-bootstrap', dir: 'less', file: 'responsive.less'],attrs:[rel:   &quot;stylesheet/less&quot;, type:'css'], disposition: 'head'
     resource url: 'css/scaffolding.css'
 }
}
</pre>
<p>Añadimos una carpeta llamada less al directorio web-app<br />
En ella creamos un nuevo archivo llamado custom-bootstrap.less</p>
<div id="attachment_1488" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/crear-carpeta-less.png"><img class="size-full wp-image-1488" title="crear-carpeta-less" src="http://vincoorbis.com/wp-content/uploads/2012/04/crear-carpeta-less.png" alt="creamos carpeta less" width="600" height="300" /></a><p class="wp-caption-text">Creamos carpeta less y archivo custom</p></div>
<p>En el archivo custom-bootstrap.less agregamos la siguiente linea:</p>
<pre class="brush: css; title: ; notranslate">@import &quot;bootstrap.less&quot;;</pre>
<p>En la carpeta less también copiamos el archivo <strong><a href="https://github.com/groovydev/twitter-bootstrap-grails-plugin/blob/master/web-app/less/variables.less">variable.less</a></strong> de nuestro plugin twitter bootstrap, este nos permitirá configurar el boostrap a nuestro antojo sin mucha complicación.</p>
<p>A continuación ejecutamos nuevamenta nuestra aplicación</p>
<pre class="brush: bash; title: ; notranslate">run-app</pre>
<p>Y ya tenemos nuestra primer aplicación Grails funcionando en ambiente local, con look and feel de twitter bootstrap. Muy fácil, ¿no? &#8220;Pero lo que hemos hecho no tienen nada de aplicación, solo levantamos el entorno.&#8221; Cierto, es hora de crear un pequeño catálogo para darnos cuenta que es todavía más simple, la parte complicada ya la superamos.</p>
<p>Detenemos nuestra aplicación</p>
<p>Generamos nuestra primer clase de dominio, para ello utilizamos nuevamente la consola grails de STS:</p>
<pre class="brush: bash; title: ; notranslate">create-domain-class com.vincoorbis.votamesta.DiscoFavorito</pre>
<div id="attachment_1492" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/create-domain.png"><img class="size-full wp-image-1492" title="create-domain" src="http://vincoorbis.com/wp-content/uploads/2012/04/create-domain.png" alt="create domain class" width="600" height="300" /></a><p class="wp-caption-text">Creamos el dominio Disco Favorito</p></div>
<p>Ahora definimos las características principales de nuestro dominio DiscoFavorito.groovy (no olviden usar la <a href="http://grails.org/doc/latest/ref/Domain%20Classes/Usage.html">guía</a>):</p>
<pre class="brush: groovy; title: ; notranslate">
package com.vincoorbis.votamesta

class DiscoFavorito {

	String artista
	String disco
	String comentario
	String mail

    static constraints = {
		artista blank: false, nullable: false
		disco blank: false, nullable: false
		comentario blank: true, nullable: true, maxSize:1000
		mail email:true, nullable: true, blank: true
    }
}
</pre>
<p>Guardamos el archivo y ahora generamos nuestro controlador y vistas con un solo comando Grails:</p>
<pre class="brush: bash; title: ; notranslate">generate-all com.vincoorbis.votamesta.DiscoFavorito</pre>
<div id="attachment_1494" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/generate-all.png"><img class="size-full wp-image-1494" title="generate-all" src="http://vincoorbis.com/wp-content/uploads/2012/04/generate-all.png" alt="generate all" width="600" height="300" /></a><p class="wp-caption-text">Generamos controlador y vistas</p></div>
<p>Listo, Volvemos a ejecutar nuestra aplicación:</p>
<pre class="brush: bash; title: ; notranslate">run-app</pre>
<p>Ahora sí, ya tenemos una aplicación web creada con unas cuantas lineas:</p>
<div id="attachment_1496" class="wp-caption aligncenter" style="width: 1034px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/CrearDiscoFavorito.png"><img class="size-large wp-image-1496" title="CrearDiscoFavorito" src="http://vincoorbis.com/wp-content/uploads/2012/04/CrearDiscoFavorito-1024x482.png" alt="" width="1024" height="482" /></a><p class="wp-caption-text">Nuestra aplicación web</p></div>
<p>A partir del domino DiscoFavorito que definimos, se creo el controlador y las vistas necesarias para crea un nuevo Disco Favorito, editarlo, borrarlo y ver la lista de elementos creados, todo esto, con el look and feel del bootstrap de twitter.</p>
<p><strong>¡Fácil! ¿No?</strong></p>
<p>Ahora vamos a dejar un rato la aplicación para trabajar un poco con su publicación y arquitectura.</p>
<p><strong>JELASTIC:</strong></p>
<p><a title="Jelastic — Top Java Host, Rock-Solid Java in the Cloud, Java Server Hosting, Java Cloud Computing" href="http://jelastic.com/">Jelastic </a>es más que un hosting para aplicaciones java, si bien no está completamente maduro, nos proveé la capacidad de alojar aplicaciones y escalarlas, definir su arquitectura principal, añadir un balanceador de carga, un constructor de código y bases de datos con tan solo unos clicks, sin preocuparnos por la configuración y actualmente como siguen en base beta, ni siquiera nos preocupamos por su costo, porque sigue siendo gratis.</p>
<p>Para comprobar lo fácil que es usar jelastic, subiremos nuestra aplicación con unos cuantos clicks:</p>
<ol>
<li>Entremos a jelastic.com y creamos nuestro usuario, elegimos en donde queremos hospedar (Europa o USA)
<p><div id="attachment_1500" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/jelastic-sign-in.png"><img class="size-full wp-image-1500" title="jelastic-sign-in" src="http://vincoorbis.com/wp-content/uploads/2012/04/jelastic-sign-in.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Sign-in</p></div></li>
<li>Nos loggeamos a la aplicación de jelastic</li>
<li>Creamos un nuevo ambiente:
<p><div id="attachment_1501" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/enviroment.png"><img class="size-full wp-image-1501" title="enviroment" src="http://vincoorbis.com/wp-content/uploads/2012/04/enviroment.png" alt="" width="600" height="299" /></a><p class="wp-caption-text">Creamos un nuevo ambiente</p></div></li>
<li>En el diálogo Environment topology escogemos el nombre y la configuración que queramos para la arquitectura, en este caso, vamos a buscar configurar una muy robusta:<br />
*Nota: Recomiendo solo utilizar 2 instancias de tomcat, ya que si utilizamos más, el deploy se lleva mucho tiempo y en ocasiones falla.</p>
<p><div id="attachment_1502" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/topology.png"><img class="size-full wp-image-1502" title="topology" src="http://vincoorbis.com/wp-content/uploads/2012/04/topology.png" alt="" width="600" height="512" /></a><p class="wp-caption-text">Topología</p></div></li>
<li>Esperamos unos minutos a que los procesos de creación concluyan, Jelastic te enviará un correo de confirmación de creación del ambiente y un correo con los datos de acceso a tu base de datos.</li>
<li>Para poder subir la aplicación Grails que creamos, es necesario dar unos pasos extras en nuestro aplicación. Primero detenemos la aplicación si aún sigue activa.</li>
<li>Para poder aprovechar las ventajas del cluster, convertiremos nuestro dominio DiscoFavorito.groovy en una clase con implementación serializable:
<pre class="brush: groovy; title: ; notranslate">class DiscoFavorito implements Serializable {</pre>
</li>
<li>Descomentamos la línea 36 del archivo conf/BuildConfig.groovy, para que descargue el driver de mysql
<pre class="brush: groovy; title: ; notranslate">dependencies {
 // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

runtime 'mysql:mysql-connector-java:5.1.16'
 }</pre>
</li>
<li>Configuramos el archivo conf/DataSource.groovy con los datos que nos mandó Jelastic para el acceso a la Base de Datos:
<pre class="brush: groovy; title: ; notranslate">dataSource {
    pooled = true
    driverClassName = &quot;com.mysql.jdbc.Driver&quot;
    username = &quot;root&quot;
    password = &quot;*******&quot;
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = &quot;create-drop&quot; // one of 'create', 'create-drop', 'update', 'validate', ''
            url = &quot;jdbc:h2:mem:devDb;MVCC=TRUE&quot;
        }
    }
    test {
        dataSource {
            dbCreate = &quot;update&quot;
            url = &quot;jdbc:h2:mem:testDb;MVCC=TRUE&quot;
        }
    }
    production {
        dataSource {
            dbCreate = &quot;update&quot;
            //url = &quot;jdbc:h2:prodDb;MVCC=TRUE&quot;
			url = &quot;jdbc:mysql://mysql-votamesta.jelastic.servint.net/votamesta?autoReconnect=true&quot;
            pooled = true
            properties {
               maxActive = -1
               minEvictableIdleTimeMillis=1800000
               timeBetweenEvictionRunsMillis=1800000
               numTestsPerEvictionRun=3
               testOnBorrow=true
               testWhileIdle=true
               testOnReturn=true
               validationQuery=&quot;SELECT 1&quot;
            }
        }
    }
}</pre>
<p>*No olviden cambiar los valores por los que les fueron enviados en el correo del robot de Jelastic</li>
<li>Ahora generamos nuestro war desde la consola grails de STS:<br />
[batch]prod war[/batch]</p>
<p><div id="attachment_1504" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/war.png"><img class="size-full wp-image-1504" title="war" src="http://vincoorbis.com/wp-content/uploads/2012/04/war.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Generamos war</p></div></li>
<li>Nuestro war estará disponible en la carpeta /target de nuestro proyecto, es necesario que le cambiemos el nombre con el que se genero a ROOT.war, por ejemplo en este caso votamesta-0.1.war por ROOT.war</li>
<li>Subimos el archivo en la sección Deployment manager de nuestro panel de Jelastic:
<p><div id="attachment_1505" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/upload.png"><img class="size-full wp-image-1505" title="upload" src="http://vincoorbis.com/wp-content/uploads/2012/04/upload.png" alt="" width="600" height="281" /></a><p class="wp-caption-text">Subir war</p></div></li>
<li> Una vez que el archivo haya subido, lo &#8216;deployamos&#8217; a nuestro ambiento previamente creado.
<p><div id="attachment_1506" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/deploy.png"><img class="size-full wp-image-1506" title="deploy" src="http://vincoorbis.com/wp-content/uploads/2012/04/deploy.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Deplegar la aplicación en nuestro ambiente</p></div></li>
<li>Esperamos que el deploy sea existoso.</li>
</ol>
<p>Listo, ya tenemos nuestra <a href="http://votamesta.jelastic.servint.net/">aplicación </a>alojada en un servidor escalable y con carga balanceada. Fácil, ¿no?</p>
<p><strong>¿Y mi dominio?</strong></p>
<p>Nuestra aplicación ya tiene un dominio proporcionado por jelastic: <a href="http://votamesta.jelastic.servint.net/">http://votamesta.jelastic.servint.net/</a> Pero eso no significa que no podamos poner una nuestro propio dominio. Lo primero que debemos hacer es comprar uno, en este caso lo hice a través de <a href="http://www.godaddy.com/">GoDaddy</a>. Compré uno sencillo por $169.99 pesos por un año.</p>
<p>Una vez comprado, es muy sencillo utilizarlo para nuestra aplicación:</p>
<ol>
<li>Entramos a nuestro panel de dominios (<a href="https://dcc.godaddy.com/Default.aspx">https://dcc.godaddy.com/Default.aspx</a>).</li>
<li>Entramos a nuestro panel de DNS
<p><div id="attachment_1514" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/dns-godaddy.png"><img class="size-full wp-image-1514" title="dns-godaddy" src="http://vincoorbis.com/wp-content/uploads/2012/04/dns-godaddy.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Entrar al panel de DNS</p></div></li>
<li>Seleccionamos &#8220;editar zona&#8221; en el dominio que deseamos configurar.
<p><div id="attachment_1515" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/edit-zone.png"><img class="size-full wp-image-1515" title="edit-zone" src="http://vincoorbis.com/wp-content/uploads/2012/04/edit-zone.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Editar Zona</p></div></li>
<li>Modificamos el CNAME record www y lo apuntamos a nuestro dominio de jelastic
<div id="attachment_1516" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/CNAME.png"><img class="size-full wp-image-1516" title="CNAME" src="http://vincoorbis.com/wp-content/uploads/2012/04/CNAME.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Modificar CNAME Record</p></div>
<p>*Nota, al terminar de crear/editar el cname, no olviden dar click en &#8220;save zone file&#8221;, en la esquina superior derecha del panel, en botón negro.</li>
<li>En nuestro panel de jelastic entramos al panel de settings de nuestro ambiente
<p><div id="attachment_1517" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/settings.png"><img class="size-full wp-image-1517" title="settings" src="http://vincoorbis.com/wp-content/uploads/2012/04/settings.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Settings de ambiente</p></div></li>
<li>En el apartado de custom domain agregamos nuestro cname
<p><div id="attachment_1518" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/custom-domain.png"><img class="size-full wp-image-1518" title="custom-domain" src="http://vincoorbis.com/wp-content/uploads/2012/04/custom-domain.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Custom Domain</p></div></li>
<li>Esperamos que se propaguen los dns (a veces bastan 10 minutos)</li>
</ol>
<p>Listo, ahora ya  tenemos nuestra aplicación con su propio dominio.<br />
<a href="http://vincoorbis.com/wp-content/uploads/2012/04/votamesta.png"><img class="aligncenter size-full wp-image-1519" title="votamesta" src="http://vincoorbis.com/wp-content/uploads/2012/04/votamesta.png" alt="" width="1002" height="646" /></a><br />
<strong></strong></p>
<p><strong>Content Delivery Network</strong></p>
<p>Ya tenemos nuestra aplicación con su propio dominio, su balanceador de carga, lista para escalarse y con un diseño increíble y responsivo. ¿Qué más podemos hacer para que nuestra aplicación sea 100% profesional? Un CDN o Red de entrega de contenidos nos ayudará para disminuir el tiempo de carga de los recursos de nuestra página, reducir la carga de servidores, colocará nuestros recursos en una red de tráfico distribuida y aumentará el web caching.</p>
<p>Suena bastante complejo, pero no lo es, básicamente todos nuestros recursos estáticos (javascripts, css, imágenes) se subirán a esta red de entrega, mejorando la carga de nuestra página y reduciendo la carga de nuestra configuración en Jelastic.</p>
<p>¿Por qué CDN y no un simple server S3? Bien, las últimas versiones de grails implementan <a href="http://grails.org/plugin/resources">Resources plugin</a>, que entre otras cosas minimizan, comprimen y optimizan los recursos estáticos de nuestra aplicación, estos procesos se desencadenan cada que se reinicia la aplicación, generando distintos archivos cada vez, lo que hace algo complejo estar delegando la actualización de estos archivos al desarrollador. El CDN sin embargo, buscará los recursos en nuestra aplicación cada vez que estos cambien y los propagará en la red de entrega.</p>
<p>Para configurar una Instancia de Amazon CloudFront para nuestra aplicación haremos lo siguiente:</p>
<ol>
<ol>
<li>Instalamos el plugin <a title="Cdn-resources -- Content Delivery Network support for grails resources plugin" href="https://github.com/tomaslin/grails-cdn-resources" target="_blank">grails-cdn-resources</a> en nuestra aplicación:<br />
&lt;bash&gt;install-plugin cdn-resources&lt;/bash&gt;</li>
<li>Añadimos los siguientes parámetros al archivo config.groovy<br />
&lt;groovy&gt;<br />
grails.resources.cdn.enabled = true<br />
grails.resources.cdn.url = &#8220;http://static.votamesta.com/&#8221;&lt;/groovy&gt;</li>
<li>Creamos una cuenta en Amazon<br />
Antes de poder usar el plugin necesitaremos crear una cuenta en Amazon para poder crear un red de contenido. (Este proceso nos solicitará una tarjeta de crédito para registrarnos, solo se hará cargo si excedemos el limite de recursos gratuitos, no olviden leer lo que aceptan <img src='http://vincoorbis.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  )<br />
<a href="http://aws.amazon.com/cloudfront/">http://aws.amazon.com/cloudfront/</a></li>
<li>Entramos a la consola de AWS de Amazon<br />
<a href="https://console.aws.amazon.com/cloudfront/home">https://console.aws.amazon.com/cloudfront/home</a></p>
<p><div id="attachment_1524" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/cdn-console.png"><img class="size-full wp-image-1524" title="cdn-console" src="http://vincoorbis.com/wp-content/uploads/2012/04/cdn-console.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Consola Cloud Front</p></div></li>
<li>Creamos una Distribución
<p><div id="attachment_1525" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/create-dist.png"><img class="size-full wp-image-1525" title="create-dist" src="http://vincoorbis.com/wp-content/uploads/2012/04/create-dist.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Crear Distribución</p></div></li>
<li>Seleccionamos el Origen y establecemos la url de la aplicación
<p><div id="attachment_1526" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/seleccionamos-origen.png"><img class="size-full wp-image-1526" title="seleccionamos-origen" src="http://vincoorbis.com/wp-content/uploads/2012/04/seleccionamos-origen.png" alt="" width="600" height="481" /></a><p class="wp-caption-text">Seleccionamos Origen</p></div></li>
<li>Mapeamos la URL a un CNAME para que tengamos nuestra propia url para el cdn
<p><div id="attachment_1527" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/cname-cdn.png"><img class="size-full wp-image-1527" title="cname-cdn" src="http://vincoorbis.com/wp-content/uploads/2012/04/cname-cdn.png" alt="" width="600" height="492" /></a><p class="wp-caption-text">Mapeamos URL</p></div></li>
<li>Revisamos y creamos</li>
<li>Añadimos un record CDN en nuestra consola de GoDaddy, apuntamos a la url que nos generó CloudFront al crear la distribución.
<p><div id="attachment_1528" class="wp-caption aligncenter" style="width: 610px"><a href="http://vincoorbis.com/wp-content/uploads/2012/04/cname-map.png"><img class="size-full wp-image-1528" title="cname-map" src="http://vincoorbis.com/wp-content/uploads/2012/04/cname-map.png" alt="" width="600" height="300" /></a><p class="wp-caption-text">Añadimos Record</p></div></li>
<li>Descomentamos las siguientes lineas en BuildConfig.groovy</li>
</ol>
</ol>
<pre class="brush: groovy; title: ; notranslate">
        // Uncomment these (or add new ones) to enable additional resources capabilities
        runtime &quot;:zipped-resources:1.0&quot;
        //runtime &quot;:cached-resources:1.0&quot;
        runtime &quot;:yui-minify-resources:0.1.4&quot;
</pre>
<ol>
<li>Creamos war y volvemos a desplegar la aplicación en Jelastic</li>
</ol>
<p>Listo, ahora nuestra aplicación proveerá los recursos estáticos desde una red de datos distribuida.</p>
<p>En este momento ya tenemos una aplicación real en linea, con las mejores características de una aplicación profesional y pagando solo $169.99 pesos de un dominio y 1 peso en la validación de tarjeta de Amazon. ¿Puede mejorar? Por supuesto, aun nos faltan varios detalles, por ejemplo:</p>
<ol>
<li>Construir un war mucho más pequeño pre-cargando las librerías necesarias en la configuración de Jelastic.</li>
<li>Subir el código de la aplicación a un repositorio de código.</li>
<li>Desplegar la aplicación directamente del repositorio de código mediante una herramienta de construcción como Maven.</li>
<li>Configurar una aplicación segura (SSL)</li>
<li>Establecer una herramienta de medición de estadísticas (Google Analytics)</li>
<li>etc&#8230;</li>
</ol>
<p>Pero todos estos detalles los trabajaremos en otro Post. <img src='http://vincoorbis.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/aplicacion-web-profesional-en-minutos/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>¿Cuándo?</title>
		<link>http://vincoorbis.com/cuando/</link>
		<comments>http://vincoorbis.com/cuando/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 23:11:57 +0000</pubDate>
		<dc:creator>Eduardo García</dc:creator>
				<category><![CDATA[Administración de Proyectos]]></category>
		<category><![CDATA[manoderecha]]></category>
		<category><![CDATA[administración de proyectos]]></category>
		<category><![CDATA[calendario dinámico]]></category>
		<category><![CDATA[diagrama de gantt]]></category>
		<category><![CDATA[estimación de tiempos]]></category>
		<category><![CDATA[gantt chart]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1433</guid>
		<description><![CDATA[<p>La palabra preferida de los clientes es: <strong>¿Cuándo?</strong></p>
<p>El cálculo de fechas estimadas de entrega para las tareas de un proyecto es más complejo de lo que parece, sobre todo porque no se utilizan las herramientas adecuadas para ello. Un proyecto, idealmente, cuenta en su inicio con una fase de planeación, en la cuál se determinan las acciones que es necesario llevar a cabo para cumplir con el objetivo del mismo. Estas acciones, a su vez, deben ser descompuestas en tareas y asignadas a las personas que las llevarán a cabo. Este conjunto de tareas, las relaciones que existen entre ellas, y su duración estimada, forman un diagrama de Gantt, el cuál se actualiza periódicamente con la información generada en la fase de desarrollo para obtener una estimación más precisa de las fechas de terminación de las tareas, y por ende, ... <a href="http://vincoorbis.com/cuando/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>La palabra preferida de los clientes es: <strong>¿Cuándo?</strong></p>
<p>El cálculo de fechas estimadas de entrega para las tareas de un proyecto es más complejo de lo que parece, sobre todo porque no se utilizan las herramientas adecuadas para ello. Un proyecto, idealmente, cuenta en su inicio con una fase de planeación, en la cuál se determinan las acciones que es necesario llevar a cabo para cumplir con el objetivo del mismo. Estas acciones, a su vez, deben ser descompuestas en tareas y asignadas a las personas que las llevarán a cabo. Este conjunto de tareas, las relaciones que existen entre ellas, y su duración estimada, forman un diagrama de Gantt, el cuál se actualiza periódicamente con la información generada en la fase de desarrollo para obtener una estimación más precisa de las fechas de terminación de las tareas, y por ende, del proyecto.</p>
<p>Existen cuatro errores fundamentales en el proceso descrito anteriormente. Veámoslos a detalle:</p>
<p>I. Siempre existen tareas nuevas.</p>
<p>No importa que la fase de planeación sea detallada y minuciosa, o que trabajemos con un desarrollador de gran experiencia, siempre existirán nuevas tareas que agregar al proyecto. La función de la fase de planeación es minimizar el impacto que nuevos requerimientos o cambios a los establecidos tendrán en el proyecto, pero es prácticamente imposible eliminarlo. Por ende, las tareas que surjan sobre la marcha afectarán las fechas de entrega previamente acordadas. Más aún cuando surgen emergencias y es necesario suspender temporalmente el flujo natural del trabajo para atendarlas. Por ello, es necesario contar con reportes que nos permitan conocer las tareas atendidas en un periodo dado de tiempo, para poder justificar los movimientos en el calendario de entregas estimadas.</p>
<p>II. Sin embargo, se mueve.</p>
<p>Algo que es muy difícil de comunicar al cliente es el significado de estimado. Trabajamos con recursos limitados, especialmente hablando del número de horas hábiles de una persona. Siempre que queramos que alguien se dedique a hacer una cosa, tendrá que dejar de hacer lo que estaba haciendo. Es por ello que cualquier tarea nueva modifica las fechas de entrega de las demás en mayor o menor medida. Las fechas de entrega son aproximaciones, su propia naturaleza las hace estar sujetas a error, no pueden y no deben estar escritas en piedra o grabadas con sangre. Si lo estuvieran, tendríamos que rechazar cualquier nuevo requerimiento o cambio para garantizar su cumplimiento.</p>
<p>III. Siempre es hoy.</p>
<p>Hasta que no se invente la máquina del tiempo, las tareas pendientes de un proyecto siempre comienzan a atenderse hoy. Cualquier modelo que no contemple esto es inútil e irreal. Las tareas terminadas pertenecen a un histórico de referencia que no tiene relación con las tareas activas ni con el cálculo de la terminación de éstas.</p>
<p>IV. ¿Ya llegamos, papá?</p>
<p>Existen varias formas de mantener la información de un diagrama de Gantt actualizada. Una, comúnmente implementada y trágicamente fallida, es preguntarle al usuario periódicamente un porcentaje de avance. Si es difícil estimar la duración de una tarea, lo es más saber cuánto me falta para terminar. Además consume el tiempo de una persona dedicada exclusívamente a recorrer los cubículos levantando porcentajes.</p>
<p>Hay otra alternativa: al principio de la tarea, el usuario estima la duración de la tarea. Una vez al día, antes de salir, el usuario registra las horas que le dedicó a esta tarea, por lo que su duración estimada es el tiempo estimado menos el tiempo registrado. Si las horas registradas superan el estimado, es necesario reestimar. La información proviene directamente de la fuente, y nunca tiene más de 24 horas de antigüedad.</p>
<p>De esta forma, siempre que se genere un calendario tendremos una idea más precisa de lo que acontece en el proyecto.</p>
<p>La filosofía manoderecha intenta brindar una metodología, soportada por una herramienta de software, que redunde en un proceso de administración de proyectos más fácil, claro y apegado a la realidad. Dentro de ella, incluímos respuestas y soluciones a las problemáticas descritas anteriormente como resultado de la experiencia adquirida al administrar proyectos por años, y analizar y descomponer a detalle el proceso. No importa cuál sea tu actividad o la naturaleza de los proyectos que realizas, echa un vistazo a esta nueva forma de lidiar con ellos, te garantizamos que no te arrepentirás.</p>
<p><a title="Contacto" href="http://manoderecha.mx/contact/">Puedes solicitar un periodo de prueba gratuito aquí.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/cuando/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Desarrollo de aplicaciones móviles con PhoneGap</title>
		<link>http://vincoorbis.com/desarrollo-de-aplicaciones-moviles-con-phonegap/</link>
		<comments>http://vincoorbis.com/desarrollo-de-aplicaciones-moviles-con-phonegap/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 22:22:30 +0000</pubDate>
		<dc:creator>cc</dc:creator>
				<category><![CDATA[Desarrollo y Programación]]></category>
		<category><![CDATA[Diseño de sitios Web y Portales de Negocio]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[blackberry]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1431</guid>
		<description><![CDATA[<p>En mi búsqueda por nuevas tecnologías y opciones para el desarrollo de aplicaciones móviles me encontré con PhoneGap <a href="https://build.phonegap.com/">https://build.phonegap.com/</a>.
PhoneGap es un framework para desarrollar aplicaciones con HTML, CSS y Javascript para iPhone/iPad, Google Android, Palm, Symbian, BlackBerry y Windows Mobile.</p>
<p>Pero bueno si se utilizan herramientas para desarrollo WEB, pues ¿No sería lo mismo desarrollar aplicaciones WEB para móviles? Pues en realidad PhoneGap va más allá de esto ya que incluye un API (una interfaz para comunicar Javascript con el lenguaje nativo) el cual permite tener acceso al hardware del dispositivo como sería:</p>

Vibración
Sonido
Acelerómetro
Brújula
Geo localización

<p>Excelente opción para los desarrolladores Web que desean programar aplicaciones móviles lo más semejante a las aplicaciones nativas.</p>
<p>Una de las ventajas más grandes que se puede apreciar es la de poder programar aplicaciones y fácilmente portarla a los diferentes dispositivos,  sin tener que realizar migración de código.</p>
<p>La ... <a href="http://vincoorbis.com/desarrollo-de-aplicaciones-moviles-con-phonegap/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>En mi búsqueda por nuevas tecnologías y opciones para el desarrollo de aplicaciones móviles me encontré con PhoneGap <a href="https://build.phonegap.com/">https://build.phonegap.com/</a>.<br />
PhoneGap es un framework para desarrollar aplicaciones con HTML, CSS y Javascript para iPhone/iPad, Google Android, Palm, Symbian, BlackBerry y Windows Mobile.</p>
<p>Pero bueno si se utilizan herramientas para desarrollo WEB, pues ¿No sería lo mismo desarrollar aplicaciones WEB para móviles? Pues en realidad PhoneGap va más allá de esto ya que incluye un API (una interfaz para comunicar Javascript con el lenguaje nativo) el cual permite tener acceso al hardware del dispositivo como sería:</p>
<ul>
<li>Vibración</li>
<li>Sonido</li>
<li>Acelerómetro</li>
<li>Brújula</li>
<li>Geo localización</li>
</ul>
<p>Excelente opción para los desarrolladores Web que desean programar aplicaciones móviles lo más semejante a las aplicaciones nativas.</p>
<p>Una de las ventajas más grandes que se puede apreciar es la de poder programar aplicaciones y fácilmente portarla a los diferentes dispositivos,  sin tener que realizar migración de código.</p>
<p>La desventaja es que las aplicaciones serán más lentas que las aplicaciones nativas.</p>
<p>Otra desventaja es que para ciertas licencias se debe realizar un pago.<br />
Aún así, me parece una buena opción para el desarrollo de aplicaciones móviles.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/desarrollo-de-aplicaciones-moviles-con-phonegap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asíncronizando tu aplicación</title>
		<link>http://vincoorbis.com/asincronizando-tu-aplicacion/</link>
		<comments>http://vincoorbis.com/asincronizando-tu-aplicacion/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 00:09:19 +0000</pubDate>
		<dc:creator>Elden Barrera</dc:creator>
				<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Desarrollo y Programación]]></category>
		<category><![CDATA[Google Gears]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[Custom Events]]></category>
		<category><![CDATA[Gears]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[IndexedDB]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[on]]></category>
		<category><![CDATA[trigger]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1414</guid>
		<description><![CDATA[<p>Hace unos cuantos días me tocó entrar de emergencia a un proyecto uno de los principales retos que nos encontramos fue portar el proyecto de <strong>Gears</strong> (qepd) a <strong>HTML5</strong> usando <strong>IndexedDB</strong>.</p>
<p>Una de las principales características que tienen estas funciones de base de datos es que son <em>asíncronas</em>, esto quiere decir que se <strong>van</strong> a hacer algo y no sabemos a que hora regresan, bueno solo hasta que mandan llamar el <strong>callback</strong> correspondiente.
</p>
<p>Al estar haciendo varias de las pantallas nos encontramos con código muy parecido al siguiente:</p>


db = google.gears.factory.create('beta.database');
db.open('EjemploBDD');

var articulos = db.execute(&#34;SELECT nombre FROM articulos WHERE id = ? LIMIT 1;&#34;, [id]);

while(articulos.isValidRow()){
  $(&#34;#lista_articulos&#34;).append(&#34;&#60;li&#62;&#34;+articulos.fieldByName(&#34;nombre&#34;)+&#34;&#60;/li&#62;&#34;);
}

<p>Como vemos todo pasa de una manera muy lineal, si queremos aplicar lo mismo con la <strong>nueva</strong> forma tendríamos algo así:</p>


window.indexedDB = window.indexedDB &#124;&#124; window.mozIndexedDB &#124;&#124; window.webkitIndexedDB &#124;&#124; window.msIndexedDB;
var db = null; //base de datos

openRequest = window.indexedDB.open(&#34;EjemploBDD&#34;, 1);
openRequest.onsuccess ... <a href="http://vincoorbis.com/asincronizando-tu-aplicacion/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Hace unos cuantos días me tocó entrar de emergencia a un proyecto uno de los principales retos que nos encontramos fue portar el proyecto de <strong>Gears</strong> (qepd) a <strong>HTML5</strong> usando <strong>IndexedDB</strong>.</p>
<p>Una de las principales características que tienen estas funciones de base de datos es que son <em>asíncronas</em>, esto quiere decir que se <strong>van</strong> a hacer algo y no sabemos a que hora regresan, bueno solo hasta que mandan llamar el <strong>callback</strong> correspondiente.<br />
<span id="more-1414"></span></p>
<p>Al estar haciendo varias de las pantallas nos encontramos con código muy parecido al siguiente:</p>
<pre class="brush: jscript; title: ; notranslate">

db = google.gears.factory.create('beta.database');
db.open('EjemploBDD');

var articulos = db.execute(&quot;SELECT nombre FROM articulos WHERE id = ? LIMIT 1;&quot;, [id]);

while(articulos.isValidRow()){
  $(&quot;#lista_articulos&quot;).append(&quot;&lt;li&gt;&quot;+articulos.fieldByName(&quot;nombre&quot;)+&quot;&lt;/li&gt;&quot;);
}
</pre>
<p>Como vemos todo pasa de una manera muy lineal, si queremos aplicar lo mismo con la <strong>nueva</strong> forma tendríamos algo así:</p>
<pre class="brush: jscript; title: ; notranslate">

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var db = null; //base de datos

openRequest = window.indexedDB.open(&quot;EjemploBDD&quot;, 1);
openRequest.onsuccess = function(event){
  //hasta que abre la base de datos regresa a esta función
  db = openRequest.result;
  // verificación de la versión de la bdd
  // ....
};

openRequest.onerror = function(e){
  console.log(&quot;Error al abrir la bdd: &quot;, e);
};

var articulosCursor;
var articulos = [];

db.transaction([&quot;articulos&quot;]).objectStore(&quot;articulos&quot;).openCursor().onsuccess = function(event){
  articulosCursor = event.target.result;
	if(articulosCursor) {
   	articulos.push(articulosCursor.value);
   	articulosCursor.continue();
  }
};

for(articulo in articulos){
  $(&quot;#lista_articulos&quot;).append(&quot;&lt;li&gt;&quot;+articulos[articulo].nombre+&quot;&lt;/li&gt;&quot;);
}
</pre>
<p>Lo que obtenemos en este segundo código es que tenemos un error en <strong>db.transaction&#8230;</strong> ya que <strong>db está null</strong> por que no ha regresado del procedimiento de apertura, por lo tanto no se puede usar, entonces tendríamos que meter <em>TOOODOOOO</em> el código dentro del success del <strong>openRequest</strong> para asegurarnos de que haya sido abierta y una vez hecho esto insertar dentro del success de <strong>openCursor</strong> el código que agrega los artículos.</p>
<p>Entonces que pasaría si lo tenemos que hacer en 15-20 páginas diferentes tendríamos un código bastante repetido y difícil de leer ya que se convertiría en algo así</p>
<pre class="brush: jscript; title: ; notranslate">

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var db = null; //base de datos

openRequest = window.indexedDB.open(&quot;EjemploBDD&quot;, 1);
openRequest.onsuccess = function(event){
  //hasta que abre la base de datos regresa a esta función
  db = openRequest.result;
  // verificación de la versión de la bdd
  // ....
  var transaction = db.transaction([&quot;articulos&quot;]);
  var articulosCursor;
  var articulos = [];
  transaction.oncomplete = function(event) {
    //visualización
    for(articulo in articulos){
      $(&quot;#lista_articulos&quot;).append(&quot;&lt;li&gt;&quot;+articulos[articulo].nombre+&quot;&lt;/li&gt;&quot;);
    }
  };

  transaction.objectStore(&quot;articulos&quot;).openCursor().onsuccess = function() {
    //llenado del array
    articulosCursor = event.target.result;
  	if(articulosCursor) {
     	articulos.push(articulosCursor.value);
     	articulosCursor.continue();
    }
  }

};
</pre>
<p>No se ve tan feo en un principio pero solo es el <strong>llenado</strong> de un listado, si tenemos funcionalidad mas compleja se puede convertir en un <em>spaghetti</em> nada apetitoso.</p>
<p>Por lo que llega a nuestro rescate los <strong>custom events</strong> que en este caso los vamos a usar de <em>notificadores</em> de los diferentes eventos y así poder separar las diferentes partes de la aplicación sin morir en el intento.</p>
<p>init.js: vamos a hacer toda la inicialización que requiera la base de datos, actualizaciones etc.</p>
<p>init.js</p>
<pre class="brush: jscript; title: ; notranslate">

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
var db = null; //base de datos

//nos esperamos hasta que el documento esté cargado

$(document).ready(function(){
  openRequest = window.indexedDB.open(&quot;EjemploBDD&quot;, 1);
  openRequest.onsuccess = function(event){
    //hasta que abre la base de datos regresa a esta función
    db = openRequest.result;
    // verificación de la versión de la bdd
    // ....
    //una vez que se completaron todas las inicializaciones de la bdd lanzamos la notificación
    $(document).trigger(&quot;initDB&quot;);
    //si queremos pasar algún dato extra tenemos que hacer lo siguiente
    // $(document).trigger({type: &quot;initDB&quot;, param1: &quot;valor1&quot;})
  };
});
</pre>
<p>articulos.js: este javascript va a ser diferente para cada pantalla que tengamos.</p>
<pre class="brush: jscript; title: ; notranslate">

//queremos que &quot;escuche&quot; la notificación de que es seguro operar en la base de datos
$(document).on(&quot;initDB&quot;, function(evt){
  //para acceder a los parámetros extras
  //var param1 = evt.param1;
  var articulos = [];
  var articulosCursor;
  //ahora sabemos que la base de datos está disponible
  var transaction = db.transaction([&quot;articulos&quot;]);

  transaction.oncomplete = function(event) {
    //hasta que termina la transación en la base de datos mostramos los datos
    // para hacerlo mas interesante notificamos a nuestra función de llenado que ahora puede mostrar los resultados
    $(document).trigger({ type: &quot;llenarLista&quot;, articulos: articulos });
  };

  transaction.objectStore(&quot;articulos&quot;).openCursor().onsuccess = function() {
    //&quot;Select de la bdd&quot;
    articulosCursor = event.target.result;
  	if(articulosCursor) {
     	articulos.push(articulosCursor.value);
     	articulosCursor.continue();
    }
  }
});

$(document).on(&quot;llenarLista&quot;, function(evt){
  var articulos = evt.articulos;
  for(articulo in articulos){
     $(&quot;#lista_articulos&quot;).append(&quot;&lt;li&gt;&quot;+articulos[articulo].nombre+&quot;&lt;/li&gt;&quot;);
  }
});
</pre>
<p>Estos métodos también se pueden aplicar a peticiones <strong>AJAX</strong> y en general a cualquier evento <strong>callback</strong> que se tenga para no amontonar código en los success, aunque también hay que señalar que se puede volver un arma de doble filo si es usada en exceso por ejemplo si se ponen las llamadas en diferentes archivos haciendo difícil seguir la <em>trayectoria</em> del código</p>
<p>PD. .on está disponible desde la versión 1.7+ de jQuery si se tiene una versión mas antigüa&#8230;<strong>actualiza!!</strong>&#8230; o bien puedes usar la función .bind</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/asincronizando-tu-aplicacion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aprendiendo de los horrores ajenos</title>
		<link>http://vincoorbis.com/aprendiendo-de-los-horrores-ajenos/</link>
		<comments>http://vincoorbis.com/aprendiendo-de-los-horrores-ajenos/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 00:07:27 +0000</pubDate>
		<dc:creator>alice</dc:creator>
				<category><![CDATA[Consultoría]]></category>
		<category><![CDATA[Desarrollo y Programación]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1405</guid>
		<description><![CDATA[<p>Uno de nuestros objetivos en el desarrollo de sistemas es que sean <strong>un placer de usar.</strong></p>
<p>Para ello buscamos poner mucha atención a los pequeños detalles, que pueden ser casi imperceptible, pero que mejoran muchísimo la calidad de lo que entregamos. Para ilustrar esto se me ocurren los siguientes ejemplos:</p>
<p>1. Uso de botones correctamente etiquetados para la función que realizan.</p>
<p>2. Redacciones útiles de los mensajes de alerta (&#8220;Algo falló, error&#8221; vs. &#8220;Su sesión expiró y la acción no pudo ser completada&#8221;).</p>
<p>3. Un indicador visual de carga para mostrar al usuario que se está ejecutando una acción y que debe esperar.</p>
<p>Pero, nada nos invita más a cuidar los detalles en nuestros propios desarrollos que ser usuarios críticos de otros sitios web, y en este sentido lo que buscamos es identificar un error y poner mucha atención en no cometerlo nosotros. Somos una especie ... <a href="http://vincoorbis.com/aprendiendo-de-los-horrores-ajenos/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Uno de nuestros objetivos en el desarrollo de sistemas es que sean <strong>un placer de usar.</strong></p>
<p>Para ello buscamos poner mucha atención a los pequeños detalles, que pueden ser casi imperceptible, pero que mejoran muchísimo la calidad de lo que entregamos. Para ilustrar esto se me ocurren los siguientes ejemplos:</p>
<p>1. Uso de botones correctamente etiquetados para la función que realizan.</p>
<p>2. Redacciones útiles de los mensajes de alerta (&#8220;Algo falló, error&#8221; vs. &#8220;Su sesión expiró y la acción no pudo ser completada&#8221;).</p>
<p>3. Un indicador visual de carga para mostrar al usuario que se está ejecutando una acción y que debe esperar.</p>
<p>Pero, nada nos invita más a cuidar los detalles en nuestros propios desarrollos que ser usuarios críticos de otros sitios web, y en este sentido lo que buscamos es identificar un error y poner mucha atención en no cometerlo nosotros. Somos una especie de &#8220;coleccionistas de horrores&#8221;, como el que describiré a continuación:</p>
<p>Recientemente tuve que activar la Banca por Internet de una nueva cuenta que abrimos con Banorte. Este banco tiene unos procesos de seguridad que involucran varios pasos, una contraseña que establece el usuario que debe cumplir ciertas reglas  (número de caracteres, uso de números y mayúsculas, no usar símbolos) en combinación con ingresar un nombre de usuario proporcionado por el propio banco y una contraseña dinámica generada por un Token.</p>
<p>Cuando te registras por primera vez, además de cambiar la contraseña temporal que te proporcionaron hay que establecer una pregunta de seguridad, la cual no puedes escoger tú sino que debes de seleccionar de un grupo de preguntas predefinidas por ellos mismos.</p>
<p>Personalmente me parece un pésimo método de verificación de la identidad este esquema de preguntas, peor aún cuando son preguntas predefinidas, entonces aclaro que tengo un sesgo previo, pero lo que me encontré es que las opciones de preguntas eran:</p>
<p>Ciudad de nacimiento de tu madre,</p>
<p>Año de nacimiento de tu padre,</p>
<p>Año en el que te graduaste de la primaria,</p>
<p>Nombre de tu primer amor,</p>
<p>Apellido de tu profesor de matemáticas de la secundaria,</p>
<p>Nombre de tu primera mascota.</p>
<p>Todas ellas me parecen muy malas opciones de pregunta porque la capacidad de olvidar la respuesta, o bien, como la escribiste (digamos que tu mamá nació en Tuxtla Gutiérrez, pero por limitaciones de no usar acentos escribes Tuxtla, o Tuxtla Gtz o Tuxtla, Gtz.), la oportunidad de error es enorme y ahí se pierde casi por completo su valor como respuesta probatoria de que eres quien dices que eres.</p>
<p>La gota que provocó este post:</p>
<p>Después de mucho pensarlo elegí la pregunta &#8220;¿en qué año te graduaste de la primaria?&#8221; porque es un dato calculable, no requiero confiar en mi memoria. Al ingresar la respuesta y guardarla recibí el siguiente mensaje de error:</p>
<p><a href="http://vincoorbis.com/wp-content/uploads/2012/04/Screen-shot-2012-04-13-at-6.09.32-PM.png"><img class="alignnone size-full wp-image-1408" title="Error Banorte" src="http://vincoorbis.com/wp-content/uploads/2012/04/Screen-shot-2012-04-13-at-6.09.32-PM.png" alt="" width="846" height="341" /></a></p>
<p>El problema es el siguiente, las condiciones de seguridad de la respuesta requieren que sea de un mínimo de 6 y un máximo de 20 caracteres sin espacios. Díganme ustedes ¿qué año en su expresión numérica tiene al menos 6 caracteres? Y por cierto, el año en texto tiene 27 caracteres.</p>
<p>Les aseguro que me encargaré de que en ningún sistema nuestro haya una falta de congruencia como esta, especialmente en los procesos de seguridad que establezcamos.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/aprendiendo-de-los-horrores-ajenos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>¿Por qué los nombres tan raros de Ubuntu?</title>
		<link>http://vincoorbis.com/por-que-los-nombres-tan-raros-de-ubuntu/</link>
		<comments>http://vincoorbis.com/por-que-los-nombres-tan-raros-de-ubuntu/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 16:19:36 +0000</pubDate>
		<dc:creator>en</dc:creator>
				<category><![CDATA[Sistemas Open Source]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=1389</guid>
		<description><![CDATA[<p>A propósito del próximo lanzamiento de Ubuntu 12.04 quisiera comentar sobre sus nombres tan distintivos&#8230;</p>
<p>La gente que se ha acercado a Linux sabe que en cada nuevo lanzamiento de la distribución de Canonical, Ubuntu; viene con un nombre distintivo y un número.</p>
<p>Las versiones son cada seis meses, y cada cierto tiempo sale una version <strong>LTS</strong> (long term support) con soporte para 2 años o más, el número indica la fecha en que salió la versión, por lo regular salen en Abril y Octubre, la nueva versión saldrá en Abril (<strong>4</strong>) del 2012 (<strong>12</strong>)&#8230; por eso es la versión <strong>12.04</strong> el nombre debe tener las siguientes características:</p>
<p>1. Cualidad positiva en forma de adjetivo.
2. Algún animal.
3. Orden alfabético.
4. La fecha de salida.</p>
<p>Así tenemos la siguiente lista de lanzamientos:</p>
<p>4.10 &#8211; Warty Warthog
5.04 &#8211; Hoary Hedgehog
5.10 &#8211; Breezy Badger
6.06 &#8211; Dapper Drake
6.10 &#8211; Edgy ... <a href="http://vincoorbis.com/por-que-los-nombres-tan-raros-de-ubuntu/">Read More &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>A propósito del próximo lanzamiento de Ubuntu 12.04 quisiera comentar sobre sus nombres tan distintivos&#8230;</p>
<p>La gente que se ha acercado a Linux sabe que en cada nuevo lanzamiento de la distribución de Canonical, Ubuntu; viene con un nombre distintivo y un número.</p>
<p>Las versiones son cada seis meses, y cada cierto tiempo sale una version <strong>LTS</strong> (long term support) con soporte para 2 años o más, el número indica la fecha en que salió la versión, por lo regular salen en Abril y Octubre, la nueva versión saldrá en Abril (<strong>4</strong>) del 2012 (<strong>12</strong>)&#8230; por eso es la versión <strong>12.04</strong> el nombre debe tener las siguientes características:</p>
<p>1. Cualidad positiva en forma de adjetivo.<br />
2. Algún animal.<br />
3. Orden alfabético.<br />
4. La fecha de salida.</p>
<p>Así tenemos la siguiente lista de lanzamientos:</p>
<p>4.10 &#8211; Warty Warthog<br />
5.04 &#8211; Hoary Hedgehog<br />
5.10 &#8211; Breezy Badger<br />
6.06 &#8211; Dapper Drake<br />
6.10 &#8211; Edgy Eft<br />
7.04 &#8211; Feisty Fawn<br />
7.10 &#8211; Gusty Gibbon<br />
8.04 &#8211; Hardy Heron (LTS)<br />
8.10 &#8211; Intrepid Ibex<br />
9.04 &#8211; Jaunty Jackalope<br />
9.10 &#8211; Karmic Koala<br />
10.04 &#8211; Lucid Lynx (LTS)<br />
10.10 &#8211; Maverick Meerkat<br />
11.04 &#8211; Natty Narwhal<br />
11.10 &#8211; Oneiric Ocelot<br />
12.04 &#8211; Precise Pangolin (LTS)</p>
<p>También existe el caso de que el mismo nombre de Ubuntu cambia, esto es porque originalmente usa el entorno de escritorio <strong>GNOME </strong>pero también ha sido distribuido con los demás entornos y para distinguirlos agrega la primer letra del entorno, en el caso de <strong>KDE</strong>, el nombre es Kubuntu, en el caso de <strong>XFCE</strong> el nombre es Xubuntu.</p>
<p>Hay versiones especiales para el manejo de multimedia como el Ubuntu Studio, o para estudiantes como el Edubuntu.</p>
<p>Si quieres saber más sobre esta distro visita <a href="http://www.ubuntu.com" target="_blank">www.ubuntu.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/por-que-los-nombres-tan-raros-de-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

